From c2e97aef1876672a17e62ab355ad9c953aec14cb Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 11 Oct 2024 11:11:26 +0800 Subject: [PATCH] fix: fix unexpected file operations on explorer (#4073) --- .../src/browser/file-tree.service.ts | 39 +++++++++++++++---- .../services/file-tree-model.service.ts | 24 +++++++----- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/packages/file-tree-next/src/browser/file-tree.service.ts b/packages/file-tree-next/src/browser/file-tree.service.ts index 09ef102959..fe5e7e98fe 100644 --- a/packages/file-tree-next/src/browser/file-tree.service.ts +++ b/packages/file-tree-next/src/browser/file-tree.service.ts @@ -634,7 +634,29 @@ export class FileTreeService extends Tree implements IFileTreeService { } } if (path) { - return this.root?.getTreeNodeByPath(path) as File | Directory; + const node = this.root?.getTreeNodeByPath(path) as File | Directory; + if (!node) { + // 尝试从再上层获取节点,可能为压缩节点 + let parentNode: Directory | undefined; + const paths = path.split(Path.separator); + while (paths.length >= 1) { + paths.pop(); + const parentPath = paths.join(Path.separator); + parentNode = this.root?.getTreeNodeByPath(parentPath) as Directory; + if (parentNode) { + break; + } + } + // 找到最相邻的父节点,从父节点的子节点中筛选出节点 + if (parentNode && Directory.is(parentNode)) { + for (const child of (parentNode as Directory).children || []) { + if (child.path.includes(path)) { + return child as Directory | File; + } + } + } + } + return node; } } @@ -713,13 +735,14 @@ export class FileTreeService extends Tree implements IFileTreeService { })) .filter((node) => node && !!node.node) as ISortNode[]; - nodes.sort((pathA, pathB) => { - // 直接获取节点深度比通过path取深度更可靠 - const pathADepth = pathA.node?.depth || 0; - const pathBDepth = pathB.node?.depth || 0; - return pathADepth - pathBDepth; - }); - + if (_paths.length > 1) { + nodes.sort((pathA, pathB) => { + // 直接获取节点深度比通过path取深度更可靠 + const pathADepth = pathA.node?.depth || 0; + const pathBDepth = pathB.node?.depth || 0; + return pathADepth - pathBDepth; + }); + } const roots = [] as ISortNode[]; for (let index = nodes.length - 1; index >= 0; index--) { // 从后往前遍历整个列表 diff --git a/packages/file-tree-next/src/browser/services/file-tree-model.service.ts b/packages/file-tree-next/src/browser/services/file-tree-model.service.ts index 78bf3e40cd..f29477bde1 100644 --- a/packages/file-tree-next/src/browser/services/file-tree-model.service.ts +++ b/packages/file-tree-next/src/browser/services/file-tree-model.service.ts @@ -1005,15 +1005,19 @@ export class FileTreeModelService { // 当存在选中的文件时,默认选中首个文件作为焦点 nextFocusedFile = this.selectedFiles[0]; } else { - const lastFile = roots[roots.length - 1].node; - const lastIndex = this.treeModel.root.getIndexAtTreeNode(lastFile); - let nextIndex = lastIndex + 1; - if (nextIndex >= this.treeModel.root.branchSize) { - const firstFile = roots[0].node; - const firstIndex = this.treeModel.root.getIndexAtTreeNode(firstFile); - nextIndex = firstIndex - 1; + const lastFile = roots[roots.length - 1]?.node; + if (!lastFile) { + nextFocusedFile = undefined; + } else { + const lastIndex = this.treeModel.root.getIndexAtTreeNode(lastFile); + let nextIndex = lastIndex + 1; + if (nextIndex >= this.treeModel.root.branchSize) { + const firstFile = roots[0].node; + const firstIndex = this.treeModel.root.getIndexAtTreeNode(firstFile); + nextIndex = firstIndex - 1; + } + nextFocusedFile = this.treeModel.root.getTreeNodeAtIndex(nextIndex); } - nextFocusedFile = this.treeModel.root.getTreeNodeAtIndex(nextIndex); } const toPromise = [] as Promise[]; @@ -1233,7 +1237,7 @@ export class FileTreeModelService { this.selectFileDecoration(node as File, false); } this.fileTreeService.updateRefreshable(true); - } else if (Directory.is(target)) { + } else if (Directory.is(target) && !Directory.isRoot(target)) { // 更新压缩目录展示名称 // 由于节点移动时默认仅更新节点路径 // 我们需要自己更新额外的参数,如uri, filestat等 @@ -1295,7 +1299,7 @@ export class FileTreeModelService { } if (this.fileTreeService.isCompactMode) { if (promptHandle.type === TreeNodeType.CompositeTreeNode) { - const isEmptyDirectory = !parent.children || parent.children.length === 0; + const isEmptyDirectory = (!parent.children || parent.children.length === 0) && !Directory.isRoot(parent); if (isEmptyDirectory) { const parentUri = parent.uri.resolve(newName); const newNodeName = [parent.name].concat(newName).join(Path.separator);