From 4fdef39d3ef40f51915fef66eb79669a59a0e202 Mon Sep 17 00:00:00 2001 From: mortalYoung Date: Mon, 29 Nov 2021 14:40:26 +0800 Subject: [PATCH 1/2] feat: support sort in folderTree --- .../__tests__/folderTreeService.test.ts | 117 +++++++++++++++++- .../workbench/explorer/folderTreeService.ts | 40 +++++- 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/src/services/workbench/__tests__/folderTreeService.test.ts b/src/services/workbench/__tests__/folderTreeService.test.ts index 7829e7e99..77a085d64 100644 --- a/src/services/workbench/__tests__/folderTreeService.test.ts +++ b/src/services/workbench/__tests__/folderTreeService.test.ts @@ -272,10 +272,125 @@ describe('Test StatusBarService', () => { const children = data[0].children!; expect(children).toHaveLength(2); expect(children[0]).toEqual({ - ...pendingNode, + ...fileNode, }); }); + test('Should in sort', () => { + const ignoreFolder = new TreeNodeModel({ + id: 'ignore-folder', + fileType: FileTypes.Folder, + name: '.git', + isLeaf: false, + children: [], + }); + const normalFolder = new TreeNodeModel({ + id: 'nomral-folder', + fileType: FileTypes.Folder, + name: 'folder', + isLeaf: false, + children: [], + }); + const normalFile = new TreeNodeModel({ + id: 'nomral-file', + fileType: FileTypes.File, + name: 'file', + isLeaf: true, + children: [], + }); + const ignoreFile = new TreeNodeModel({ + id: 'ignore-file', + fileType: FileTypes.File, + name: '.gitignore', + isLeaf: true, + children: [], + }); + const root = new TreeNodeModel({ + id: 'root', + fileType: FileTypes.RootFolder, + name: 'root-test', + isLeaf: false, + children: [ignoreFile, normalFile, normalFolder, ignoreFolder], + }); + folderTreeService.add(root); + + // let data = folderTreeService.getState().folderTree?.data || []; + let rootNode = folderTreeService.get('root')!; + expect(rootNode.children?.map((i) => i.name)).toEqual([ + '.git', + 'folder', + '.gitignore', + 'file', + ]); + + // add a file + folderTreeService.add( + new TreeNodeModel({ + id: 'another-ignore-file', + fileType: FileTypes.File, + name: '.prettierignore', + isLeaf: true, + children: [], + }), + 'root' + ); + + rootNode = folderTreeService.get('root')!; + expect(rootNode.children?.map((i) => i.name)).toEqual([ + '.git', + 'folder', + '.gitignore', + '.prettierignore', + 'file', + ]); + + // add a folder + folderTreeService.add( + new TreeNodeModel({ + id: 'another-normal-folder', + fileType: FileTypes.Folder, + name: 'another-folder', + isLeaf: false, + children: [], + }), + 'root' + ); + + rootNode = folderTreeService.get('root')!; + expect(rootNode.children?.map((i) => i.name)).toEqual([ + '.git', + 'another-folder', + 'folder', + '.gitignore', + '.prettierignore', + 'file', + ]); + + // add a input + folderTreeService.add( + new TreeNodeModel({ + id: 'create-folder', + fileType: FileTypes.Folder, + name: '', + isEditable: true, + isLeaf: false, + children: [], + }), + 'root' + ); + + rootNode = folderTreeService.get('root')!; + expect(rootNode.children?.map((i) => i.name)).toEqual([ + '', + '.git', + 'another-folder', + 'folder', + '.gitignore', + '.prettierignore', + 'file', + ]); + }); + test('Should support to set entry', () => { folderTreeService.setEntry(Button); expect(folderTreeService.getState().entry).toEqual(Button); diff --git a/src/services/workbench/explorer/folderTreeService.ts b/src/services/workbench/explorer/folderTreeService.ts index fc3d9107b..34b7ff8b3 100644 --- a/src/services/workbench/explorer/folderTreeService.ts +++ b/src/services/workbench/explorer/folderTreeService.ts @@ -157,6 +157,38 @@ export class FolderTreeService this.builtinService = container.resolve(BuiltinService); } + private sortTree(tree: IFolderTreeNodeProps[]) { + tree.sort((pre, cur) => { + // folder before file + if (pre.isLeaf !== cur.isLeaf) { + return pre.isLeaf! > cur.isLeaf! ? 1 : -1; + } + + // in general, both have name + if (pre.name && cur.name) { + const isHiddenFilePre = pre.name.startsWith('.') ? 1 : 0; + const isHiddenFileCur = cur.name.startsWith('.') ? 1 : 0; + // one is hidden file and another is not + if (isHiddenFilePre ^ isHiddenFileCur) { + return isHiddenFilePre ? -1 : 1; + } + // both are hidden files + if (isHiddenFilePre & isHiddenFilePre) { + // hidden file + return pre.name + .substring(1) + .localeCompare(cur.name.substring(1)); + } + return pre.name.localeCompare(cur.name!); + } + + // the node which is creating would without name + return pre.isEditable ? -1 : 1; + }); + + tree.forEach((treeNode) => this.sortTree(treeNode.children || [])); + } + public reset() { this.setState({ folderTree: { @@ -221,6 +253,8 @@ export class FolderTreeService // if root folder exists, then do nothing return; } + + this.sortTree(folder.children || []); this.setState({ folderTree: { ...folderTree, data: [folder] }, }); @@ -319,6 +353,7 @@ export class FolderTreeService } cloneData[index] = tree!.obj; + this.sortTree(cloneData[index].children || []); this.setState({ folderTree: { ...this.state.folderTree, @@ -363,7 +398,10 @@ export class FolderTreeService return; } tree.updateNode(id, restData); - if (index > -1) nextData[index] = tree.obj; + if (index > -1) { + nextData[index] = tree.obj; + this.sortTree(nextData[index].children || []); + } this.setState({ folderTree, }); From 51202b8e1d8540563e20d5c4f9e5f55054120ab0 Mon Sep 17 00:00:00 2001 From: mortalYoung Date: Tue, 30 Nov 2021 12:02:01 +0800 Subject: [PATCH 2/2] feat: improve check hidden files --- src/services/workbench/explorer/folderTreeService.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/services/workbench/explorer/folderTreeService.ts b/src/services/workbench/explorer/folderTreeService.ts index 34b7ff8b3..df9dedda8 100644 --- a/src/services/workbench/explorer/folderTreeService.ts +++ b/src/services/workbench/explorer/folderTreeService.ts @@ -157,6 +157,10 @@ export class FolderTreeService this.builtinService = container.resolve(BuiltinService); } + private isHiddenFile(file: IFolderTreeNodeProps) { + return !!file.name?.startsWith('.'); + } + private sortTree(tree: IFolderTreeNodeProps[]) { tree.sort((pre, cur) => { // folder before file @@ -166,8 +170,8 @@ export class FolderTreeService // in general, both have name if (pre.name && cur.name) { - const isHiddenFilePre = pre.name.startsWith('.') ? 1 : 0; - const isHiddenFileCur = cur.name.startsWith('.') ? 1 : 0; + const isHiddenFilePre = Number(this.isHiddenFile(pre)); + const isHiddenFileCur = Number(this.isHiddenFile(cur)); // one is hidden file and another is not if (isHiddenFilePre ^ isHiddenFileCur) { return isHiddenFilePre ? -1 : 1;