From ad721ea4259a2305f2287d82e792ae9331abc0dd Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 7 Mar 2023 17:21:30 +0800 Subject: [PATCH] fix: show files on symbol link folders (#2379) --- .../src/browser/file-tree.service.ts | 11 +++++++---- .../browser/services/file-tree-api.service.ts | 18 +++++++----------- .../browser/services/file-tree-dnd.service.ts | 17 ++++++++++------- .../services/file-tree-model.service.ts | 7 ++++++- packages/file-tree-next/src/common/index.ts | 8 +++++++- 5 files changed, 37 insertions(+), 24 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 5ea14b8830..601b69c674 100644 --- a/packages/file-tree-next/src/browser/file-tree.service.ts +++ b/packages/file-tree-next/src/browser/file-tree.service.ts @@ -306,17 +306,20 @@ export class FileTreeService extends Tree implements IFileTreeService { const parentURI = new URI(childrenParentStat.uri); const nearestParentDirectory = parent.parent as Directory; if (parent && nearestParentDirectory) { - let parentName; + let parentName: string | undefined = parent.name; if (parent.filestat.isSymbolicLink) { // 当软链目录本身发生折叠时 - parentName = new URI(parent.filestat.realUri).relative(parentURI)?.toString(); - parentName = [parent.uri.displayName].concat(parentName.split(Path.separator)).join(Path.separator); + const relativePath = new URI(parent.filestat.realUri).relative(parentURI)?.toString(); + if (relativePath) { + parentName = relativePath; + parentName = [parent.uri.displayName].concat(parentName.split(Path.separator)).join(Path.separator); + } } else if (nearestParentDirectory.filestat.isSymbolicLink) { parentName = new URI(nearestParentDirectory.filestat.realUri).relative(parentURI)?.toString(); } else { parentName = nearestParentDirectory.uri.relative(parentURI)?.toString(); } - if (parentName !== parent.name) { + if (parentName && parentName !== parent.name) { parent.updateMetaData({ name: parentName, uri: parentURI, diff --git a/packages/file-tree-next/src/browser/services/file-tree-api.service.ts b/packages/file-tree-next/src/browser/services/file-tree-api.service.ts index 731f6c3be7..6335fc9662 100644 --- a/packages/file-tree-next/src/browser/services/file-tree-api.service.ts +++ b/packages/file-tree-next/src/browser/services/file-tree-api.service.ts @@ -7,7 +7,7 @@ import { IFileServiceClient } from '@opensumi/ide-file-service/lib/common'; import { IDialogService } from '@opensumi/ide-overlay'; import { IWorkspaceEditService } from '@opensumi/ide-workspace-edit'; -import { IFileTreeAPI, IFileTreeService } from '../../common'; +import { IFileTreeAPI, IFileTreeService, IMoveFileMetadata } from '../../common'; import { Directory, File } from '../../common/file-tree-node.define'; @Injectable() @@ -98,9 +98,6 @@ export class FileTreeAPI implements IFileTreeAPI { // labelService可根据uri参数提供不同的展示效果 const name = presetName ? presetName : uri.displayName; let node: Directory | File; - if (!this.cacheFileStat.has(filestat.uri)) { - this.cacheFileStat.set(filestat.uri, filestat); - } if (filestat.isDirectory) { node = new Directory(tree as any, parent, uri, name, filestat, this.getReadableTooltip(uri)); } else { @@ -109,18 +106,18 @@ export class FileTreeAPI implements IFileTreeAPI { return node; } - async mvFiles(fromFiles: URI[], targetDir: URI) { + async mvFiles(fromFiles: IMoveFileMetadata[], targetDir: URI) { const error: string[] = []; for (const from of fromFiles) { - if (from.isEqualOrParent(targetDir)) { + if (from.url.isEqualOrParent(targetDir)) { return; } } // 合并具有包含关系的文件移动 const sortedFiles = fromFiles.sort((a, b) => a.toString().length - b.toString().length); - const mergeFiles: URI[] = []; + const mergeFiles: IMoveFileMetadata[] = []; for (const file of sortedFiles) { - if (mergeFiles.length > 0 && mergeFiles.find((exist) => exist.isEqualOrParent(file))) { + if (mergeFiles.length > 0 && mergeFiles.find((exist) => exist.url.isEqualOrParent(file.url))) { continue; } mergeFiles.push(file); @@ -131,7 +128,7 @@ export class FileTreeAPI implements IFileTreeAPI { const confirm = await this.dialogService.warning( formatLocalize( 'file.confirm.move', - `[ ${mergeFiles.map((uri) => uri.displayName).join(',')} ]`, + `[ ${mergeFiles.map((file) => file.url.displayName).join(',')} ]`, targetDir.displayName, ), [cancel, ok], @@ -141,8 +138,7 @@ export class FileTreeAPI implements IFileTreeAPI { } } for (const from of mergeFiles) { - const filestat = this.cacheFileStat.get(from.toString()); - const res = await this.mv(from, targetDir.resolve(from.displayName), filestat && filestat.isDirectory); + const res = await this.mv(from.url, targetDir.resolve(from.url.displayName), from.isDirectory); if (res) { error.push(res); } diff --git a/packages/file-tree-next/src/browser/services/file-tree-dnd.service.ts b/packages/file-tree-next/src/browser/services/file-tree-dnd.service.ts index 8235c65dae..00a5fa179e 100644 --- a/packages/file-tree-next/src/browser/services/file-tree-dnd.service.ts +++ b/packages/file-tree-next/src/browser/services/file-tree-dnd.service.ts @@ -307,7 +307,7 @@ export class DragAndDropService extends WithEventBus { } if (resources.length > 0) { const targetContainerUri = activeUri ? activeUri : (containing && containing.uri)!; - const resourcesCanBeMoved = resources.filter( + const resourcesCanBeMoved: (File | Directory)[] = resources.filter( (resource: File | Directory) => resource && resource.parent && @@ -316,7 +316,7 @@ export class DragAndDropService extends WithEventBus { if (resourcesCanBeMoved.length > 0) { // 最小化移动文件 const errors = await this.fileTreeAPI.mvFiles( - resourcesCanBeMoved.map((res) => res.uri), + resourcesCanBeMoved.map((res) => ({ url: res.uri, isDirectory: res.filestat.isDirectory })), targetContainerUri, ); if (errors && errors.length > 0) { @@ -347,12 +347,15 @@ export class DragAndDropService extends WithEventBus { ); // 由于节点移动时默认仅更新节点路径 // 我们需要自己更新额外的参数,如uri, filestat等 - target.updateURI(to); - target.updateFileStat({ - ...target.filestat, - uri: to.toString(), + target.updateMetaData({ + name: to.displayName, + fileStat: { + ...target.filestat, + uri: to.toString(), + }, + uri: to, + tooltip: this.fileTreeAPI.getReadableTooltip(to), }); - target.updateToolTip(this.fileTreeAPI.getReadableTooltip(to)); // 当重命名文件为文件夹时,刷新文件夹更新子文件路径 if (Directory.is(target)) { this.fileTreeService.refresh(target as Directory); 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 4fe0922ca0..431870721f 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 @@ -1604,7 +1604,12 @@ export class FileTreeModelService { } } const errors = await this.fileTreeAPI.mvFiles( - pasteStore.crossFiles ? pasteStore.crossFiles : pasteStore.files.map((file) => file.uri), + pasteStore.crossFiles + ? pasteStore.crossFiles.map((url) => ({ + url, + isDirectory: this.fileTreeService.getNodeByPathOrUri(url)?.filestat.isDirectory || false, + })) + : pasteStore.files.map((file) => ({ url: file.uri, isDirectory: file.filestat.isDirectory })), parent.uri, ); if (errors && errors.length > 0) { diff --git a/packages/file-tree-next/src/common/index.ts b/packages/file-tree-next/src/common/index.ts index 5b87731805..92a0b8e7d2 100644 --- a/packages/file-tree-next/src/common/index.ts +++ b/packages/file-tree-next/src/common/index.ts @@ -12,12 +12,18 @@ export const IFileTreeService = Symbol('IFileTreeService'); export interface IFileTreeService extends ITree { refresh(): Promise; } + +export interface IMoveFileMetadata { + url: URI; + isDirectory: boolean; +} + export interface IFileTreeAPI { copyFile(from: URI, to: URI): Promise; createFile(newUri: URI, content?: string): Promise; createDirectory(newUri: URI): Promise; delete(uri: URI): Promise; - mvFiles(oldUri: URI[], newUri: URI, isDirectory?: boolean): Promise; + mvFiles(oldUri: IMoveFileMetadata[], newUri: URI): Promise; mv(oldUri: URI, newUri: URI, isDirectory?: boolean): Promise; resolveChildren( tree: ITree,