Skip to content

Commit 0f47920

Browse files
authored
feat: reveal local draft in explorer after created (#75)
* feat: reveal local draft in explorer after created * refactor: remove redundant commands about local draft * refactor: rename LocalFileService to LocalDraft
1 parent 838779b commit 0f47920

File tree

11 files changed

+51
-153
lines changed

11 files changed

+51
-153
lines changed

package.json

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -91,25 +91,12 @@
9191
"category": "Cnblogs Posts List",
9292
"enablement": "vscode-cnb.isAuthorized"
9393
},
94-
{
95-
"command": "vscode-cnb.delete-local-draft",
96-
"title": "删除",
97-
"icon": "$(trash)",
98-
"category": "Cnblogs Local Draft"
99-
},
10094
{
10195
"command": "vscode-cnb.create-local-draft",
10296
"title": "新建本地草稿",
10397
"icon": "$(new-file)",
10498
"category": "Cnblogs Local Draft"
10599
},
106-
{
107-
"command": "vscode-cnb.save-local-draft-to-cnblogs",
108-
"title": "发布",
109-
"icon": "dist/assets/icon-upload.svg",
110-
"category": "Cnblogs Local Draft",
111-
"enablement": "vscode-cnb.isAuthorized"
112-
},
113100
{
114101
"command": "vscode-cnb.modify-post-settings",
115102
"title": "博文设置",
@@ -387,10 +374,6 @@
387374
"command": "vscode-cnb.modify-post-settings",
388375
"when": "false"
389376
},
390-
{
391-
"command": "vscode-cnb.save-local-draft-to-cnblogs",
392-
"when": "false"
393-
},
394377
{
395378
"command": "vscode-cnb.delete-post",
396379
"when": "false"
@@ -399,10 +382,6 @@
399382
"command": "vscode-cnb.save-post-file-to-cnblogs",
400383
"when": "true"
401384
},
402-
{
403-
"command": "vscode-cnb.delete-local-draft",
404-
"when": "false"
405-
},
406385
{
407386
"command": "vscode-cnb.logout",
408387
"when": "false"
@@ -481,24 +460,10 @@
481460
"group": "inline@4",
482461
"when": "viewItem =~ /^cnb-post/ && viewItem != cnb-post-category"
483462
},
484-
{
485-
"command": "vscode-cnb.save-local-draft-to-cnblogs",
486-
"when": "viewItem == cnb-local-draft-file",
487-
"group": "inline@1"
488-
},
489-
{
490-
"command": "vscode-cnb.delete-local-draft",
491-
"when": "viewItem == cnb-local-draft-file",
492-
"group": "inline@2"
493-
},
494463
{
495464
"command": "vscode-cnb.create-local-draft",
496465
"when": "viewItem == cnb-local-drafts-folder"
497466
},
498-
{
499-
"command": "vscode-cnb.delete-local-draft",
500-
"when": "viewItem == cnb-local-draft-file"
501-
},
502467
{
503468
"command": "vscode-cnb.rename-post",
504469
"when": "viewItem =~ /^cnb-post/ && viewItem != cnb-post-category",

src/commands/commands-registration.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,15 @@ import {
1111
refreshPostsList,
1212
seekPostsList,
1313
} from './posts-list/refresh-posts-list';
14-
import { saveLocalDraftToCnblogs, savePostFileToCnblogs, savePostToCnblogs } from './posts-list/save-post';
14+
import { savePostFileToCnblogs, savePostToCnblogs } from './posts-list/save-post';
1515
import { createLocalDraft } from './posts-list/create-local-draft';
16-
import { deleteLocalDraft } from './posts-list/delete-local-draft';
1716
import { deleteSelectedPosts } from './posts-list/delete-post';
1817
import { modifyPostSettings } from './posts-list/modify-post-settings';
1918
import { uploadImage } from './upload-image/upload-image';
2019
import { revealLocalPostFileInOs } from './reveal-local-post-file-in-os';
2120
import { showLocalFileToPostInfo } from './show-local-file-to-post-info';
2221
import { newPostCategory } from './post-category/new-post-category';
23-
import { deleteSelectedCategories } from './post-category/delete-selected-categoriess';
22+
import { deleteSelectedCategories } from './post-category/delete-selected-categories';
2423
import { refreshPostCategoriesList } from './post-category/refresh-post-categories-list';
2524
import { updatePostCategory } from './post-category/update-post-category';
2625
import { openPostInVscode } from './posts-list/open-post-in-vscode';
@@ -54,8 +53,6 @@ export const registerCommands = () => {
5453
commands.registerCommand(`${appName}.modify-post-settings`, modifyPostSettings),
5554
commands.registerCommand(`${appName}.delete-post`, deleteSelectedPosts),
5655
commands.registerCommand(`${appName}.create-local-draft`, createLocalDraft),
57-
commands.registerCommand(`${appName}.delete-local-draft`, deleteLocalDraft),
58-
commands.registerCommand(`${appName}.save-local-draft-to-cnblogs`, saveLocalDraftToCnblogs),
5956
commands.registerCommand(`${appName}.save-post-file-to-cnblogs`, savePostFileToCnblogs),
6057
commands.registerCommand(`${appName}.pull-post-remote-updates`, pullPostRemoteUpdates),
6158
commands.registerCommand(`${appName}.upload-clipboard-image`, () => uploadImage(true, 'clipboard')),
Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import { homedir } from 'os';
22
import path = require('path');
33
import { Uri, window, workspace } from 'vscode';
4-
import { LocalFileService } from '../../services/local-draft.service';
5-
import { AlertService } from '../../services/alert.service';
64
import { Settings } from '../../services/settings.service';
7-
import { localDraftsTreeItem, postsDataProvider } from '../../tree-view-providers/posts-data-provider';
8-
import { extensionViews } from '../../tree-view-providers/tree-view-registration';
5+
import { revealActiveFileInExplorer } from '../../utils/reveal-active-file';
96
import { openPostFile } from './open-post-file';
107

118
export const createLocalDraft = async () => {
@@ -26,22 +23,33 @@ export const createLocalDraft = async () => {
2623
const { fsPath: workspacePath } = Settings.workspaceUri;
2724
title = ['.md', '.html'].some(ext => title!.endsWith(ext)) ? title : `${title}${title.endsWith('.') ? '' : '.'}md`;
2825
const filePath = path.join(workspacePath, title);
26+
2927
try {
3028
await workspace.fs.stat(Uri.file(filePath));
31-
AlertService.error('已存在同名文件');
32-
return;
3329
} catch (e) {
34-
// ignore
30+
// 文件不存在
31+
await workspace.fs.writeFile(Uri.file(filePath), new TextEncoder().encode(''));
3532
}
3633

37-
await workspace.fs.writeFile(Uri.file(filePath), new TextEncoder().encode(''));
3834
await openPostFile(filePath);
39-
postsDataProvider.fireTreeDataChangedEvent(localDraftsTreeItem);
40-
const items = (await postsDataProvider.getChildren(localDraftsTreeItem)) as LocalFileService[] | undefined;
41-
if (items) {
42-
const item = items.find(x => x.filePath === filePath);
43-
if (item) {
44-
await extensionViews.postsList?.reveal(item);
45-
}
35+
await revealActiveFileInExplorer();
36+
// 设置中关闭了 `autoReveal` 的情况下, 需要两次调用 `workbench.files.action.showActiveFileInExplorer` 命令, 才能正确 `reveal`
37+
if (!workspace.getConfiguration('explorer').get<boolean>('autoReveal')) {
38+
await revealActiveFileInExplorer();
4639
}
40+
41+
const focusEditor = async () => {
42+
const { activeTextEditor } = window;
43+
if (activeTextEditor) {
44+
await window.showTextDocument(activeTextEditor.document, { preview: false, preserveFocus: false });
45+
}
46+
};
47+
await focusEditor();
48+
// 确保能 focus 到编辑器(不这么做, 有时会聚焦到 explorer 处)
49+
await new Promise<void>(resolve => {
50+
const innerTimeout = setTimeout(() => {
51+
clearTimeout(innerTimeout);
52+
focusEditor().finally(() => resolve());
53+
}, 50);
54+
});
4755
};

src/commands/posts-list/delete-local-draft.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/commands/posts-list/modify-post-settings.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { revealPostsListItem } from '../../services/posts-list-view';
77
import { postConfigurationPanel } from '../../services/post-configuration-panel.service';
88
import path from 'path';
99
import fs from 'fs';
10-
import { LocalFileService } from '../../services/local-draft.service';
10+
import { LocalDraft } from '../../services/local-draft.service';
1111
import { saveFilePendingChanges } from '../../utils/save-file-pending-changes';
1212

1313
export const modifyPostSettings = async (input: Post | Uri) => {
@@ -49,7 +49,7 @@ export const modifyPostSettings = async (input: Post | Uri) => {
4949
beforeUpdate: async post => {
5050
if (localFilePath && fs.existsSync(localFilePath)) {
5151
await saveFilePendingChanges(localFilePath);
52-
const content = await new LocalFileService(localFilePath).readAllText();
52+
const content = await new LocalDraft(localFilePath).readAllText();
5353
post.postBody = content;
5454
}
5555
return true;

src/commands/posts-list/open-post-file.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { commands, TextDocumentShowOptions, Uri } from 'vscode';
22
import { Post } from '../../models/post';
3-
import { LocalFileService } from '../../services/local-draft.service';
3+
import { LocalDraft } from '../../services/local-draft.service';
44
import { PostFileMapManager } from '../../services/post-file-map';
55

6-
export const openPostFile = async (post: LocalFileService | Post | string, options?: TextDocumentShowOptions) => {
6+
export const openPostFile = async (post: LocalDraft | Post | string, options?: TextDocumentShowOptions) => {
77
let filePath = '';
8-
if (post instanceof LocalFileService) {
8+
if (post instanceof LocalDraft) {
99
filePath = post.filePath;
1010
} else if (post instanceof Post) {
1111
filePath = PostFileMapManager.getFilePath(post.id) ?? '';

src/commands/posts-list/save-post.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Uri, workspace, window, ProgressLocation, MessageOptions } from 'vscode';
22
import { Post } from '../../models/post';
3-
import { LocalFileService } from '../../services/local-draft.service';
3+
import { LocalDraft } from '../../services/local-draft.service';
44
import { AlertService } from '../../services/alert.service';
55
import { postService } from '../../services/post.service';
66
import { PostFileMapManager } from '../../services/post-file-map';
@@ -77,13 +77,13 @@ export const savePostFileToCnblogs = async (fileUri: Uri | undefined) => {
7777
}
7878
break;
7979
case options[0]:
80-
await saveLocalDraftToCnblogs(new LocalFileService(filePath));
80+
await saveLocalDraftToCnblogs(new LocalDraft(filePath));
8181
break;
8282
}
8383
}
8484
};
8585

86-
export const saveLocalDraftToCnblogs = async (localDraft: LocalFileService) => {
86+
export const saveLocalDraftToCnblogs = async (localDraft: LocalDraft) => {
8787
if (!localDraft) {
8888
return;
8989
}

src/services/local-draft.service.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import path from 'path';
22
import fs from 'fs';
3-
import { TreeItem, Uri, workspace } from 'vscode';
3+
import { Uri, workspace } from 'vscode';
44
import { PostFileMapManager } from './post-file-map';
55
import { Settings } from './settings.service';
66

7-
export class LocalFileService {
7+
export class LocalDraft {
88
get fileName(): string {
99
return path.basename(this.filePath);
1010
}
@@ -28,22 +28,10 @@ export class LocalFileService {
2828
return new TextDecoder().decode(binary);
2929
}
3030

31-
toTreeItem(): TreeItem {
32-
return Object.assign(new TreeItem(this.fileName), {
33-
resourceUri: Uri.file(this.filePath),
34-
command: {
35-
command: `vscode.open`,
36-
arguments: [Uri.file(this.filePath), { preview: false }],
37-
title: '编辑博文',
38-
},
39-
contextValue: 'cnb-local-draft-file',
40-
} as TreeItem);
41-
}
42-
43-
static async readDrafts(): Promise<LocalFileService[]> {
31+
static async readDrafts(): Promise<LocalDraft[]> {
4432
const files = await workspace.fs.readDirectory(Settings.workspaceUri);
4533
return files
46-
.map(x => Object.assign(new LocalFileService(path.join(`${Settings.workspaceUri.fsPath}`, x[0]))))
34+
.map(x => Object.assign(new LocalDraft(path.join(`${Settings.workspaceUri.fsPath}`, x[0]))))
4735
.filter(
4836
x => !PostFileMapManager.getPostId(x.filePath) && ['.md', '.html'].some(ext => x.fileName.endsWith(ext))
4937
);

src/tree-view-providers/posts-data-provider.ts

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,15 @@
11
import { homedir } from 'os';
2-
import {
3-
Event,
4-
EventEmitter,
5-
MarkdownString,
6-
ProviderResult,
7-
ThemeIcon,
8-
TreeDataProvider,
9-
TreeItem,
10-
TreeItemCollapsibleState,
11-
Uri,
12-
} from 'vscode';
2+
import { Event, EventEmitter, MarkdownString, ProviderResult, TreeDataProvider, TreeItem, Uri } from 'vscode';
133
import { refreshPostsList } from '../commands/posts-list/refresh-posts-list';
144
import { Post } from '../models/post';
15-
import { LocalFileService } from '../services/local-draft.service';
165
import { PageModel } from '../models/page-model';
176
import { AlertService } from '../services/alert.service';
187
import { postService } from '../services/post.service';
198
import { globalState } from '../services/global-state';
209
import { PostFileMapManager } from '../services/post-file-map';
2110
import { Settings } from '../services/settings.service';
2211

23-
export const localDraftsTreeItem: TreeItem = Object.assign(new TreeItem('本地草稿'), {
24-
iconPath: new ThemeIcon('folder'),
25-
collapsibleState: TreeItemCollapsibleState.Collapsed,
26-
contextValue: 'cnb-local-drafts-folder',
27-
description: Settings.workspaceUri.fsPath.replace(homedir(), '~'),
28-
tooltip: '在本地创建的还未保存到博客园的文章',
29-
} as TreeItem);
30-
31-
export type PostDataProviderItem = Post | TreeItem | LocalFileService;
12+
export type PostDataProviderItem = Post | TreeItem;
3213

3314
export class PostsDataProvider implements TreeDataProvider<PostDataProviderItem> {
3415
private static _instance?: PostsDataProvider;
@@ -50,15 +31,9 @@ export class PostsDataProvider implements TreeDataProvider<PostDataProviderItem>
5031

5132
protected constructor() {}
5233

53-
getChildren(element?: PostDataProviderItem): ProviderResult<PostDataProviderItem[]> {
34+
getChildren(parent?: PostDataProviderItem): ProviderResult<PostDataProviderItem[]> {
5435
return new Promise<PostDataProviderItem[]>(resolve => {
55-
if (element === localDraftsTreeItem) {
56-
LocalFileService.readDrafts().then(
57-
v => resolve(v),
58-
() => void 0
59-
);
60-
return;
61-
} else if (!element) {
36+
if (!parent) {
6237
const pagedPosts = this._pagedPosts;
6338
if (!pagedPosts) {
6439
void refreshPostsList();
@@ -73,10 +48,7 @@ export class PostsDataProvider implements TreeDataProvider<PostDataProviderItem>
7348
}
7449

7550
getParent(el: PostDataProviderItem) {
76-
if (el instanceof LocalFileService) {
77-
return localDraftsTreeItem;
78-
}
79-
return undefined;
51+
return el instanceof Post ? undefined : undefined;
8052
}
8153

8254
readonly onDidChangeTreeData: Event<PostDataProviderItem | null | undefined> | undefined =
@@ -86,9 +58,7 @@ export class PostsDataProvider implements TreeDataProvider<PostDataProviderItem>
8658
if (item instanceof TreeItem) {
8759
return item;
8860
}
89-
if (item instanceof LocalFileService) {
90-
return item.toTreeItem();
91-
}
61+
9262
const descDatePublished = item.datePublished ? ` \n发布于: ${item.datePublished}` : '';
9363
const localPath = PostFileMapManager.getFilePath(item.id);
9464
const localPathForDesc = localPath?.replace(homedir(), '~') || '未关联本地文件';
@@ -118,11 +88,11 @@ export class PostsDataProvider implements TreeDataProvider<PostDataProviderItem>
11888
};
11989
this._pagedPosts = await postService.fetchPostsList({ pageIndex, pageSize });
12090
this.fireTreeDataChangedEvent(undefined);
121-
} catch (e) {
122-
if (e instanceof Error) {
123-
AlertService.error(e.message);
91+
} catch (ex) {
92+
if (ex instanceof Error) {
93+
AlertService.error(ex.message);
12494
} else {
125-
AlertService.error(`Failed to fetch posts list\n${JSON.stringify(e)}`);
95+
AlertService.error(`Failed to fetch posts list\n${JSON.stringify(ex)}`);
12696
}
12797
}
12898
}

src/utils/reveal-active-file.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { commands } from 'vscode';
2+
3+
export const revealActiveFileInExplorer = async (): Promise<void> =>
4+
await commands.executeCommand('workbench.files.action.showActiveFileInExplorer');

0 commit comments

Comments
 (0)