From 7dd5d14163509a8534688bd46810f1fed9b8debb Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 14 Sep 2021 11:32:09 -0700 Subject: [PATCH 1/7] add the basics --- .../contrib/files/browser/fileImportExport.ts | 2 +- .../files/browser/views/explorerViewer.ts | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index 23cd0bc126487..7710b6454e31f 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -418,7 +418,7 @@ export class NativeFileImport { private async doImport(target: ExplorerItem, source: DragEvent, token: CancellationToken): Promise { // Check for dropped external files to be folders - const files = coalesce(extractEditorsDropData(source, true).filter(editor => URI.isUri(editor.resource) && this.fileService.canHandleResource(editor.resource)).map(editor => editor.resource)); + const files = coalesce(extractEditorsDropData(source).filter(editor => URI.isUri(editor.resource) && this.fileService.canHandleResource(editor.resource)).map(editor => editor.resource)); const resolvedFiles = await this.fileService.resolveAll(files.map(file => ({ resource: file }))); if (token.isCancellationRequested) { diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index a0f7f9b42687f..dd30d74812f80 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -980,12 +980,21 @@ export class FileDragAndDrop implements ITreeDragAndDrop { try { - // Desktop DND (Import file) + // External File DND (Import file) if (data instanceof NativeDragAndDropData) { - if (isWeb) { - const browserUpload = this.instantiationService.createInstance(BrowserFileUpload); - await browserUpload.upload(target, originalEvent); - } else { + // Native DND from Desktop + if (originalEvent.dataTransfer?.types.indexOf('Files') !== -1) { + if (isWeb) { + const browserUpload = this.instantiationService.createInstance(BrowserFileUpload); + await browserUpload.upload(target, originalEvent); + } else { + const nativeImport = this.instantiationService.createInstance(NativeFileImport); + await nativeImport.import(resolvedTarget, originalEvent); + } + } + + // External FS-provided DND + else { const nativeImport = this.instantiationService.createInstance(NativeFileImport); await nativeImport.import(resolvedTarget, originalEvent); } From 52ef823bdd3779c69e7656ddc785548c2b2af5fd Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 16 Sep 2021 10:20:53 -0700 Subject: [PATCH 2/7] remove unused param --- src/vs/workbench/browser/dnd.ts | 45 +++++++++++++++------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index d71353750944a..1f9aae83c36fb 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -56,38 +56,33 @@ export interface IDraggedResourceEditorInput extends IBaseTextResourceEditorInpu isExternal?: boolean; } -export function extractEditorsDropData(e: DragEvent, externalOnly?: boolean): Array { +export function extractEditorsDropData(e: DragEvent): Array { const editors: IDraggedResourceEditorInput[] = []; if (e.dataTransfer && e.dataTransfer.types.length > 0) { - - // Check for window-to-window DND - if (!externalOnly) { - - // Data Transfer: Code Editors - const rawEditorsData = e.dataTransfer.getData(CodeDataTransfers.EDITORS); - if (rawEditorsData) { - try { - editors.push(...parse(rawEditorsData)); - } catch (error) { - // Invalid transfer - } + // Data Transfer: Code Editors + const rawEditorsData = e.dataTransfer.getData(CodeDataTransfers.EDITORS); + if (rawEditorsData) { + try { + editors.push(...parse(rawEditorsData)); + } catch (error) { + // Invalid transfer } + } - // Data Transfer: Resources - else { - try { - const rawResourcesData = e.dataTransfer.getData(DataTransfers.RESOURCES); - if (rawResourcesData) { - const resourcesRaw: string[] = JSON.parse(rawResourcesData); - for (const resourceRaw of resourcesRaw) { - if (resourceRaw.indexOf(':') > 0) { // mitigate https://github.com/microsoft/vscode/issues/124946 - editors.push({ resource: URI.parse(resourceRaw) }); - } + // Data Transfer: Resources + else { + try { + const rawResourcesData = e.dataTransfer.getData(DataTransfers.RESOURCES); + if (rawResourcesData) { + const resourcesRaw: string[] = JSON.parse(rawResourcesData); + for (const resourceRaw of resourcesRaw) { + if (resourceRaw.indexOf(':') > 0) { // mitigate https://github.com/microsoft/vscode/issues/124946 + editors.push({ resource: URI.parse(resourceRaw) }); } } - } catch (error) { - // Invalid transfer } + } catch (error) { + // Invalid transfer } } From b62e097aab5c461b852f9375aef0150aac7bc6b3 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 16 Sep 2021 10:28:19 -0700 Subject: [PATCH 3/7] increase clarity --- .../contrib/files/browser/fileImportExport.ts | 4 +-- .../files/browser/views/explorerViewer.ts | 27 ++++++++----------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index 7710b6454e31f..b02ee36fbd589 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -378,9 +378,9 @@ export class BrowserFileUpload { //#endregion -//#region Native File Import (drag and drop) +//#region External File Import (drag and drop) -export class NativeFileImport { +export class ExternalFileImport { constructor( @IFileService private readonly fileService: IFileService, diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index dd30d74812f80..531a0be470dca 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -54,7 +54,7 @@ import { IEditorInput } from 'vs/workbench/common/editor'; import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity'; import { ResourceFileEdit } from 'vs/editor/browser/services/bulkEditService'; import { IExplorerService } from 'vs/workbench/contrib/files/browser/files'; -import { BrowserFileUpload, NativeFileImport, getMultipleFilesOverwriteConfirm } from 'vs/workbench/contrib/files/browser/fileImportExport'; +import { BrowserFileUpload, ExternalFileImport, getMultipleFilesOverwriteConfirm } from 'vs/workbench/contrib/files/browser/fileImportExport'; import { toErrorMessage } from 'vs/base/common/errorMessage'; export class ExplorerDelegate implements IListVirtualDelegate { @@ -980,24 +980,19 @@ export class FileDragAndDrop implements ITreeDragAndDrop { try { - // External File DND (Import file) + // External file DND (Import/Upload file) if (data instanceof NativeDragAndDropData) { - // Native DND from Desktop - if (originalEvent.dataTransfer?.types.indexOf('Files') !== -1) { - if (isWeb) { - const browserUpload = this.instantiationService.createInstance(BrowserFileUpload); - await browserUpload.upload(target, originalEvent); - } else { - const nativeImport = this.instantiationService.createInstance(NativeFileImport); - await nativeImport.import(resolvedTarget, originalEvent); - } + // Native OS file DND into Web + if (originalEvent.dataTransfer?.types.indexOf('Files') !== -1 && isWeb) { + const browserUpload = this.instantiationService.createInstance(BrowserFileUpload); + await browserUpload.upload(target, originalEvent); } - // External FS-provided DND - else { - const nativeImport = this.instantiationService.createInstance(NativeFileImport); - await nativeImport.import(resolvedTarget, originalEvent); - } + // 2 Cases handled for import: + // FS-Provided file DND into Web/Desktop + // Native OS file DND into Desktop + const fileImport = this.instantiationService.createInstance(ExternalFileImport); + await fileImport.import(resolvedTarget, originalEvent); } // In-Explorer DND (Move/Copy file) From 03cd0530c51c0addf267783e4444f385ac261fc3 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 16 Sep 2021 15:07:53 -0700 Subject: [PATCH 4/7] activate provider --- src/vs/workbench/contrib/files/browser/fileImportExport.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index b02ee36fbd589..7443bd7d57241 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -418,7 +418,9 @@ export class ExternalFileImport { private async doImport(target: ExplorerItem, source: DragEvent, token: CancellationToken): Promise { // Check for dropped external files to be folders - const files = coalesce(extractEditorsDropData(source).filter(editor => URI.isUri(editor.resource) && this.fileService.canHandleResource(editor.resource)).map(editor => editor.resource)); + const candidateFiles = extractEditorsDropData(source).filter(editor => URI.isUri(editor.resource)); + await Promise.all(candidateFiles.map(editor => { return editor.resource ? this.fileService.activateProvider(editor.resource.scheme) : Promise.resolve(); })); + const files = coalesce(candidateFiles.filter(editor => URI.isUri(editor.resource) && this.fileService.canHandleResource(editor.resource)).map(editor => editor.resource)); const resolvedFiles = await this.fileService.resolveAll(files.map(file => ({ resource: file }))); if (token.isCancellationRequested) { From fe66c521b10bfc7c5fecd69bbf54f15b81688023 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 17 Sep 2021 08:09:09 +0200 Subject: [PATCH 5/7] :lipstick: `doImport` --- .../workbench/contrib/files/browser/fileImportExport.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileImportExport.ts b/src/vs/workbench/contrib/files/browser/fileImportExport.ts index 7443bd7d57241..31233d3f03da8 100644 --- a/src/vs/workbench/contrib/files/browser/fileImportExport.ts +++ b/src/vs/workbench/contrib/files/browser/fileImportExport.ts @@ -417,10 +417,12 @@ export class ExternalFileImport { private async doImport(target: ExplorerItem, source: DragEvent, token: CancellationToken): Promise { + // Activate all providers for the resources dropped + const candidateFiles = coalesce(extractEditorsDropData(source).map(editor => editor.resource)); + await Promise.all(candidateFiles.map(resource => this.fileService.activateProvider(resource.scheme))); + // Check for dropped external files to be folders - const candidateFiles = extractEditorsDropData(source).filter(editor => URI.isUri(editor.resource)); - await Promise.all(candidateFiles.map(editor => { return editor.resource ? this.fileService.activateProvider(editor.resource.scheme) : Promise.resolve(); })); - const files = coalesce(candidateFiles.filter(editor => URI.isUri(editor.resource) && this.fileService.canHandleResource(editor.resource)).map(editor => editor.resource)); + const files = coalesce(candidateFiles.filter(resource => this.fileService.canHandleResource(resource))); const resolvedFiles = await this.fileService.resolveAll(files.map(file => ({ resource: file }))); if (token.isCancellationRequested) { From 557ee10dd9b5539719b02815c79386f266868e83 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 17 Sep 2021 08:11:20 +0200 Subject: [PATCH 6/7] :lipstick: --- src/vs/workbench/browser/dnd.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 1f9aae83c36fb..c79e36d7a7166 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -59,6 +59,7 @@ export interface IDraggedResourceEditorInput extends IBaseTextResourceEditorInpu export function extractEditorsDropData(e: DragEvent): Array { const editors: IDraggedResourceEditorInput[] = []; if (e.dataTransfer && e.dataTransfer.types.length > 0) { + // Data Transfer: Code Editors const rawEditorsData = e.dataTransfer.getData(CodeDataTransfers.EDITORS); if (rawEditorsData) { From 790e4a277ce7a622ade36958441358fb90546b0f Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 21 Sep 2021 10:20:51 -0700 Subject: [PATCH 7/7] fix issues --- .../contrib/files/browser/views/explorerViewer.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 39e5078262ca7..9851fba30e9a1 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -839,7 +839,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { if (!containsDragType(originalEvent, DataTransfers.FILES, CodeDataTransfers.FILES, DataTransfers.RESOURCES)) { return false; } - if (isWeb && originalEvent.dataTransfer?.types.indexOf('Files') === -1) { + if (isWeb && !containsDragType(originalEvent, 'Files')) { // DnD from vscode to web is not supported #115535. Only if we are dragging from native finder / explorer then the "Files" data transfer will be set return false; } @@ -983,16 +983,17 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // External file DND (Import/Upload file) if (data instanceof NativeDragAndDropData) { // Native OS file DND into Web - if (originalEvent.dataTransfer?.types.indexOf('Files') !== -1 && isWeb) { + if (containsDragType(originalEvent, 'Files') && isWeb) { const browserUpload = this.instantiationService.createInstance(BrowserFileUpload); await browserUpload.upload(target, originalEvent); } - // 2 Cases handled for import: // FS-Provided file DND into Web/Desktop // Native OS file DND into Desktop - const fileImport = this.instantiationService.createInstance(ExternalFileImport); - await fileImport.import(resolvedTarget, originalEvent); + else { + const fileImport = this.instantiationService.createInstance(ExternalFileImport); + await fileImport.import(resolvedTarget, originalEvent); + } } // In-Explorer DND (Move/Copy file)