Skip to content

Commit bec9dbf

Browse files
authored
feat(posts-list): show the metadata of post in tree view (#78)
* feat(posts-list): show the metadata of post * refactor: rename PostDataProviderItem to PostTreeViewItem * refactor: rename extensionViews.visiblePostList to visiblePostsList * fix: update metadata in posts list of the post when post updated * chore(eslint): disable no-dupe-class-members for typescript
1 parent 2a47537 commit bec9dbf

19 files changed

+372
-103
lines changed

.eslintrc.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,13 @@
1919
"no-undef": "off",
2020
"@typescript-eslint/no-floating-promises": "warn"
2121
},
22+
"overrides": [
23+
{
24+
"files": ["*.ts", "*.tsx"],
25+
"rules": {
26+
"no-dupe-class-members": "off"
27+
}
28+
}
29+
],
2230
"ignorePatterns": ["out", "dist", "src/test/**", "**/*.d.ts"]
2331
}

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
1212
"typescript.tsc.autoDetect": "off",
1313
"editor.formatOnSave": true,
14-
"cSpell.words": ["ASPNETCORE", "fluentui", "randomstring", "singleline", "tailwindcss"],
14+
"cSpell.words": ["ASPNETCORE", "fluentui", "iconfont", "randomstring", "singleline", "tailwindcss"],
1515
"json.format.enable": false,
1616
"eslint.alwaysShowStatus": true,
1717
"eslint.lintTask.enable": true,

download-iconfont.mjs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* eslint-disable no-console */
2+
import fetch from 'node-fetch';
3+
import fs from 'fs';
4+
import AdmZip from 'adm-zip';
5+
const url =
6+
'https://www.iconfont.cn/api/project/download.zip?spm=a313x.7781069.1998910419.d7543c303&pid=2996691&ctoken=ndNRCUzYy381Rxk59b1LjTrg';
7+
const cookie =
8+
'EGG_SESS_ICONFONT=X2bT0AZ-TAIilwY-GdJPZzopst30wSOteTYESbBaXxbdSzdNvsW9cIk8Rv2OFK9WB4P6YDevBbM0tOZXSeQ-PlBr9j4tU6xOUFjFBJ0DQn-bvfiHQ9VToJtqTPiCmSRpfaiJg2PNK_U65bOD27CiBF0XriLwpr2VwR2IdTxDcEjB_TASVO4TZeLD4yutVl7F-HAekMbP05tFgoqkHKErlg==; cna=G1LxGnOXCnwCAXPBn9cnCizc; hasViewVideo=true; ctoken=tpg9HdfcXbaBj1GRmc0B9X0-; u=5429096; u.sig=TNtkaPPSd2m-XekHonfzX8cnJ4FYtYu3NQ3Ic536XRI; locale=en-us; isg=BOPj3u3ohSIY2UmfHCh8ajjwciGN2HcatGxS7hVBlcK5VAB2nKxAa4fCTizadM8S';
9+
const filename = 'download.zip';
10+
11+
fetch(url, { headers: { cookie: cookie } }).then(f => {
12+
const dest = fs.createWriteStream('./download.zip');
13+
f.body?.pipe(dest);
14+
dest.on('finish', () => {
15+
try {
16+
const zip = AdmZip(filename, {});
17+
const outFileName = 'icons.woff2';
18+
zip.getEntries()
19+
.filter(e => !e.isDirectory && e.name.startsWith('iconfont.woff2'))
20+
.forEach(e => {
21+
zip.extractEntryTo(e, './dist/assets', false, true, undefined, outFileName);
22+
zip.extractEntryTo(e, 'src/assets', false, true, undefined, outFileName);
23+
});
24+
fs.unlink(filename, err => {
25+
if (err) {
26+
console.log(err);
27+
}
28+
console.log('iconfont assets downloaded');
29+
});
30+
} catch (ex) {
31+
console.warn('Failed to unzip iconfont assets! Some icons may not work correctly.', ex);
32+
}
33+
});
34+
}, undefined);

package-lock.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,50 @@
3333
],
3434
"main": "./dist/extension.js",
3535
"contributes": {
36+
"icons": {
37+
"vscode-cnb-date": {
38+
"description": "date",
39+
"default": {
40+
"fontPath": "dist/assets/icons.woff2",
41+
"fontCharacter": "\\e697"
42+
}
43+
},
44+
"vscode-cnb-image-upload": {
45+
"description": "image upload",
46+
"default": {
47+
"fontPath": "dist/assets/icons.woff2",
48+
"fontCharacter": "\\e80e"
49+
}
50+
},
51+
"vscode-cnb-cloud-upload": {
52+
"description": "cloud upload",
53+
"default": {
54+
"fontPath": "dist/assets/icons.woff2",
55+
"fontCharacter": "\\e7d9"
56+
}
57+
},
58+
"vscode-cnb-icon-seek": {
59+
"description": "icon seek",
60+
"default": {
61+
"fontPath": "dist/assets/icons.woff2",
62+
"fontCharacter": "\\e662"
63+
}
64+
},
65+
"vscode-cnb-folders": {
66+
"description": "folders",
67+
"default": {
68+
"fontPath": "dist/assets/icons.woff2",
69+
"fontCharacter": "\\e74a"
70+
}
71+
},
72+
"vscode-cnb-folder-close": {
73+
"description": "folder close",
74+
"default": {
75+
"fontPath": "dist/assets/icons.woff2",
76+
"fontCharacter": "\\e65b"
77+
}
78+
}
79+
},
3680
"commands": [
3781
{
3882
"title": "登录到博客园",
@@ -56,10 +100,7 @@
56100
{
57101
"command": "vscode-cnb.seek-posts-list",
58102
"title": "跳页",
59-
"icon": {
60-
"light": "dist/assets/icon-seek.svg",
61-
"dark": "dist/assets/icon-seek-dark.svg"
62-
},
103+
"icon": "$(vscode-cnb-icon-seek)",
63104
"enablement": "vscode-cnb.isAuthorized && !vscode-cnb.posts-list.refreshing && vscode-cnb.posts-list.pageCount > 0",
64105
"category": "Cnblogs Posts List"
65106
},
@@ -108,10 +149,7 @@
108149
"command": "vscode-cnb.upload-image",
109150
"title": "上传图片到博客园",
110151
"category": "Cnblogs",
111-
"icon": {
112-
"light": "dist/assets/icon-image-upload.svg",
113-
"dark": "dist/assets/icon-image-upload-dark.svg"
114-
},
152+
"icon": "$(vscode-cnb-image-upload)",
115153
"enablement": "vscode-cnb.isAuthorized"
116154
},
117155
{
@@ -134,10 +172,7 @@
134172
{
135173
"command": "vscode-cnb.save-post-file-to-cnblogs",
136174
"title": "保存到博客园",
137-
"icon": {
138-
"light": "dist/assets/icon-upload.svg",
139-
"dark": "dist/assets/icon-upload-dark.svg"
140-
},
175+
"icon": "$(vscode-cnb-cloud-upload)",
141176
"enablement": "vscode-cnb.isAuthorized",
142177
"category": "Cnblogs"
143178
},
@@ -721,7 +756,8 @@
721756
"lint": "eslint src --ext ts",
722757
"test": "node ./out/test/runTest.js",
723758
"format": "prettier --write .",
724-
"format-check": "prettier --check ."
759+
"format-check": "prettier --check .",
760+
"download-icons": "node ./download-iconfont.mjs"
725761
},
726762
"devDependencies": {
727763
"@types/express": "^4.17.1",
@@ -738,6 +774,7 @@
738774
"@typescript-eslint/eslint-plugin": "^5.1.0",
739775
"@typescript-eslint/parser": "^5.1.0",
740776
"@vscode/test-electron": "^1.6.2",
777+
"adm-zip": "^0.5.9",
741778
"autoprefixer": "^10.4.4",
742779
"babel-plugin-module-resolver": "^4.1.0",
743780
"clean-webpack-plugin": "^4.0.0",

src/assets/icon-seek-dark.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/assets/icon-seek.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/assets/icon-upload-dark.svg

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

src/assets/icon-upload.svg

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

src/assets/icons.woff2

2.23 KB
Binary file not shown.

src/commands/pdf/export-pdf.command.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ const inputTargetFolder = async (): Promise<Uri | undefined> => {
144144

145145
const handlePostInput = (post: Post): Promise<Post[]> => {
146146
const posts: Post[] = [post];
147-
extensionViews.visiblePostList()?.selection.map(item => {
147+
extensionViews.visiblePostsList()?.selection.map(item => {
148148
if (item instanceof Post && !posts.includes(item)) {
149149
posts.push(item);
150150
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const confirmDelete = async (
4040

4141
export const deleteSelectedPosts = async (post: Post) => {
4242
const selectedPosts: Post[] = post ? [post] : [];
43-
extensionViews.visiblePostList()?.selection.map(post => {
43+
extensionViews.visiblePostsList()?.selection.map(post => {
4444
if (post instanceof Post && !selectedPosts.includes(post)) {
4545
postsDataProvider.pagedPosts?.items.find(item => item === post);
4646
selectedPosts.push(post);

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import path from 'path';
99
import fs from 'fs';
1010
import { LocalDraft } from '../../services/local-draft.service';
1111
import { saveFilePendingChanges } from '../../utils/save-file-pending-changes';
12+
import { postsDataProvider } from '../../tree-view-providers/posts-data-provider';
1213

1314
export const modifyPostSettings = async (input: Post | Uri) => {
1415
let post: Post | undefined;
@@ -43,8 +44,9 @@ export const modifyPostSettings = async (input: Post | Uri) => {
4344
breadcrumbs: ['更新博文设置', editDto.post.title],
4445
post: postEditDto,
4546
localFileUri: localFilePath ? Uri.file(localFilePath) : undefined,
46-
successCallback: () => {
47+
successCallback: ({ id }) => {
4748
AlertService.info('博文已更新');
49+
postsDataProvider.fireTreeDataChangedEvent(id);
4850
},
4951
beforeUpdate: async post => {
5052
if (localFilePath && fs.existsSync(localFilePath)) {

src/models/post.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { parseISO } from 'date-fns';
2+
13
export class Post {
24
id: number = -1;
35
author: string = '';
@@ -8,7 +10,20 @@ export class Post {
810
categoryIds: number[] | null = [];
911
changeCreatedTime: boolean = false;
1012
changePostType: boolean = false;
11-
datePublished?: Date;
13+
private _datePublished?: Date | undefined;
14+
get datePublished(): Date | undefined {
15+
return this._datePublished;
16+
}
17+
set datePublished(value: Date | string | undefined) {
18+
this._datePublished = typeof value === 'string' ? parseISO(value) : value;
19+
}
20+
private _dateUpdated?: Date | undefined;
21+
get dateUpdated(): Date | undefined {
22+
return this._dateUpdated;
23+
}
24+
set dateUpdated(value: Date | string | undefined) {
25+
this._dateUpdated = typeof value === 'string' ? parseISO(value) : value;
26+
}
1227
description: string = '';
1328
featuredImage: string = '';
1429
displayOnHomePage: boolean = false;

src/services/post-category.service.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ export class PostCategoryService {
1717

1818
private constructor() {}
1919

20+
async findCategories(ids: number[], { useCache = true } = {}): Promise<PostCategories> {
21+
ids = ids.filter(x => x > 0);
22+
if (ids.length <= 0) {
23+
return [];
24+
}
25+
26+
const categories = await this.fetchCategories(!useCache);
27+
return categories.filter(({ categoryId }) => ids.includes(categoryId));
28+
}
29+
2030
async fetchCategories(forceRefresh = false): Promise<PostCategories> {
2131
if (this._cached && !forceRefresh) {
2232
return this._cached;

src/services/posts-list-view.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ export const revealPostsListItem = async (
99
return;
1010
}
1111

12-
const view = extensionViews.visiblePostList();
12+
const view = extensionViews.visiblePostsList();
1313
await view?.reveal(post, options);
1414
};

0 commit comments

Comments
 (0)