diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-10-29 21:58:20 +0100 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-10-29 22:58:39 +0100 |
commit | 23553ff0f27c11446de8944a3d8bfd9135613a16 (patch) | |
tree | 9f05deff573db5ef851c1db0603b9f2097dfe443 /apps/files/src/components | |
parent | 2d5060d1e3161aadfafb11d3690bc337b9092d31 (diff) | |
download | nextcloud-server-refactor/drop-to-uploader.tar.gz nextcloud-server-refactor/drop-to-uploader.zip |
refactor(files): Use `@nextcloud/upload` for file drop handlingrefactor/drop-to-uploader
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'apps/files/src/components')
-rw-r--r-- | apps/files/src/components/BreadCrumbs.vue | 36 | ||||
-rw-r--r-- | apps/files/src/components/DragAndDropNotice.vue | 26 | ||||
-rw-r--r-- | apps/files/src/components/FileEntryMixin.ts | 47 |
3 files changed, 45 insertions, 64 deletions
diff --git a/apps/files/src/components/BreadCrumbs.vue b/apps/files/src/components/BreadCrumbs.vue index c423b698d40..c35d4fc34b3 100644 --- a/apps/files/src/components/BreadCrumbs.vue +++ b/apps/files/src/components/BreadCrumbs.vue @@ -47,7 +47,7 @@ import NcBreadcrumbs from '@nextcloud/vue/dist/Components/NcBreadcrumbs.js' import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js' import { useNavigation } from '../composables/useNavigation' -import { onDropInternalFiles, dataTransferToFileTree, onDropExternalFiles } from '../services/DropService' +import { onDropInternalFiles, onDropExternalFiles } from '../services/DropService' import { showError } from '@nextcloud/dialogs' import { useDragAndDropStore } from '../store/dragging.ts' import { useFilesStore } from '../store/files.ts' @@ -222,14 +222,23 @@ export default defineComponent({ // dragover state on the DragAndDropNotice component. event.preventDefault() + // If another button is pressed, cancel it. This + // allows cancelling the drag with the right click. + if (event.button !== 0) { + return + } + // Caching the selection const selection = this.draggingFiles const items = [...event.dataTransfer?.items || []] as DataTransferItem[] - // We need to process the dataTransfer ASAP before the - // browser clears it. This is why we cache the items too. - const fileTree = await dataTransferToFileTree(items) + // Check if we are uploading files + if (items.find((item) => item.kind === 'file') !== undefined) { + await onDropExternalFiles(items) + return + } + // Else we're moving/copying files // We might not have the target directory fetched yet const contents = await this.currentView?.getContents(path) const folder = contents?.folder @@ -238,24 +247,13 @@ export default defineComponent({ return } - const canDrop = (folder.permissions & Permission.CREATE) !== 0 - const isCopy = event.ctrlKey - - // If another button is pressed, cancel it. This - // allows cancelling the drag with the right click. - if (!canDrop || event.button !== 0) { - return - } - - logger.debug('Dropped', { event, folder, selection, fileTree }) - - // Check whether we're uploading files - if (fileTree.contents.length > 0) { - await onDropExternalFiles(fileTree, folder, contents.contents) + const canDrop = Boolean(folder.permissions & Permission.CREATE) + if (!canDrop) { return } - // Else we're moving/copying files + logger.debug('Dropped', { event, folder, selection }) + const isCopy = event.ctrlKey const nodes = selection.map(source => this.filesStore.getNode(source)) as Node[] await onDropInternalFiles(nodes, folder, contents.contents, isCopy) diff --git a/apps/files/src/components/DragAndDropNotice.vue b/apps/files/src/components/DragAndDropNotice.vue index 23ebf7cd296..19fe8b6923d 100644 --- a/apps/files/src/components/DragAndDropNotice.vue +++ b/apps/files/src/components/DragAndDropNotice.vue @@ -38,7 +38,7 @@ import debounce from 'debounce' import TrayArrowDownIcon from 'vue-material-design-icons/TrayArrowDown.vue' import { useNavigation } from '../composables/useNavigation' -import { dataTransferToFileTree, onDropExternalFiles } from '../services/DropService' +import { onDropExternalFiles } from '../services/DropService' import logger from '../logger.ts' import type { RawLocation } from 'vue-router' @@ -168,38 +168,24 @@ export default defineComponent({ event.preventDefault() event.stopPropagation() - // Caching the selection - const items: DataTransferItem[] = [...event.dataTransfer?.items || []] - - // We need to process the dataTransfer ASAP before the - // browser clears it. This is why we cache the items too. - const fileTree = await dataTransferToFileTree(items) - - // We might not have the target directory fetched yet - const contents = await this.currentView?.getContents(this.currentFolder.path) - const folder = contents?.folder - if (!folder) { - showError(this.t('files', 'Target folder does not exist any more')) - return - } - // If another button is pressed, cancel it. This // allows cancelling the drag with the right click. if (event.button) { return } - logger.debug('Dropped', { event, folder, fileTree }) + logger.debug('Dropped', { event }) - // Check whether we're uploading files - const uploads = await onDropExternalFiles(fileTree, folder, contents.contents) + // Caching the selection + const items: DataTransferItem[] = [...event.dataTransfer?.items || []] + const uploads = await onDropExternalFiles(items) // Scroll to last successful upload in current directory if terminated const lastUpload = uploads.findLast((upload) => upload.status !== UploadStatus.FAILED && !upload.file.webkitRelativePath.includes('/') && upload.response?.headers?.['oc-fileid'] // Only use the last ID if it's in the current folder - && upload.source.replace(folder.source, '').split('/').length === 2) + && upload.source.replace(this.currentFolder.source, '').split('/').length === 2) if (lastUpload !== undefined) { logger.debug('Scrolling to last upload in current folder', { lastUpload }) diff --git a/apps/files/src/components/FileEntryMixin.ts b/apps/files/src/components/FileEntryMixin.ts index e5d6a27e96c..7ad5229c933 100644 --- a/apps/files/src/components/FileEntryMixin.ts +++ b/apps/files/src/components/FileEntryMixin.ts @@ -18,9 +18,10 @@ import Vue, { defineComponent } from 'vue' import { action as sidebarAction } from '../actions/sidebarAction.ts' import { getDragAndDropPreview } from '../utils/dragUtils.ts' import { hashCode } from '../utils/hashUtils.ts' -import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts' +import { onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts' import logger from '../logger.ts' import { isDownloadable } from '../utils/permissions.ts' +import { useLink } from 'vue-router/composables' Vue.directive('onClickOutside', vOnClickOutside) @@ -337,15 +338,15 @@ export default defineComponent({ onDragOver(event: DragEvent) { this.dragover = this.canDrop - if (!this.canDrop) { + if (!this.canDrop && event.dataTransfer) { event.dataTransfer.dropEffect = 'none' return } // Handle copy/move drag and drop - if (event.ctrlKey) { + if (event.ctrlKey && event.dataTransfer) { event.dataTransfer.dropEffect = 'copy' - } else { + } else if (event.dataTransfer) { event.dataTransfer.dropEffect = 'move' } }, @@ -405,40 +406,36 @@ export default defineComponent({ event.preventDefault() event.stopPropagation() + // If another button is pressed, cancel it. This + // allows cancelling the drag with the right click. + if (!this.canDrop || event.button) { + return + } + // Caching the selection const selection = this.draggingFiles const items = [...event.dataTransfer?.items || []] as DataTransferItem[] - // We need to process the dataTransfer ASAP before the - // browser clears it. This is why we cache the items too. - const fileTree = await dataTransferToFileTree(items) - - // We might not have the target directory fetched yet - const contents = await this.currentView?.getContents(this.source.path) - const folder = contents?.folder - if (!folder) { - showError(this.t('files', 'Target folder does not exist any more')) - return - } + logger.debug('Dropped', { event, selection }) - // If another button is pressed, cancel it. This - // allows cancelling the drag with the right click. - if (!this.canDrop || event.button) { + // Check whether we're uploading files + if (items.find((item) => item.kind === 'file') !== undefined) { + await onDropExternalFiles(items) + this.dragover = false return } - const isCopy = event.ctrlKey + // Else we are copying / moving files this.dragover = false - logger.debug('Dropped', { event, folder, selection, fileTree }) - - // Check whether we're uploading files - if (fileTree.contents.length > 0) { - await onDropExternalFiles(fileTree, folder, contents.contents) + const contents = await this.currentView?.getContents(this.source.path) + const folder = contents?.folder + if (!folder) { + showError(this.t('files', 'Target folder does not exist any more')) return } - // Else we're moving/copying files + const isCopy = event.ctrlKey const nodes = selection.map(source => this.filesStore.getNode(source)) as Node[] await onDropInternalFiles(nodes, folder, contents.contents, isCopy) |