diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2025-01-15 18:03:40 +0100 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2025-01-15 18:03:40 +0100 |
commit | b3eb664b58770c8374c52d837ff2efe3fc2bbd61 (patch) | |
tree | 7bbcb062c22c0c85176caa322d797129291cfd82 | |
parent | 6beaed95a8c9e162ba0cf91bd3a45b6a34b95536 (diff) | |
download | nextcloud-server-fix/better-drag-n-drop.tar.gz nextcloud-server-fix/better-drag-n-drop.zip |
-rw-r--r-- | apps/files/src/components/BreadCrumbs.vue | 6 | ||||
-rw-r--r-- | apps/files/src/components/DragAndDropNotice.vue | 5 | ||||
-rw-r--r-- | apps/files/src/components/FileEntry.vue | 3 | ||||
-rw-r--r-- | apps/files/src/components/FileEntryMixin.ts | 9 | ||||
-rw-r--r-- | apps/files/src/directives/vFilesDrop.ts | 11 |
5 files changed, 25 insertions, 9 deletions
diff --git a/apps/files/src/components/BreadCrumbs.vue b/apps/files/src/components/BreadCrumbs.vue index e75c4cb7fe0..c9718ae92ed 100644 --- a/apps/files/src/components/BreadCrumbs.vue +++ b/apps/files/src/components/BreadCrumbs.vue @@ -116,7 +116,7 @@ export default defineComponent({ dir, to: this.getTo(dir), name: basename(dir), - onDrop: () => this.onDrop(dir) + onDrop: () => this.onDrop(dir), })) }, @@ -158,13 +158,13 @@ export default defineComponent({ if (folder === undefined) { const result = await this.currentView!.getContents(dir) folder = result.folder + // Cache folder and children (potentially also part of the breadcrumbs) emit('files:node:created', folder) result.contents.forEach((node) => { - if (node.type === FileType.Folder) { + if (node.type === FileType.Folder && this.getNodeFromSource(node.source) === undefined) { emit('files:node:created', node) } }) - folder = result.folder } this.folders[dir] = folder as Folder diff --git a/apps/files/src/components/DragAndDropNotice.vue b/apps/files/src/components/DragAndDropNotice.vue index aebbe38bb02..2e0b94233eb 100644 --- a/apps/files/src/components/DragAndDropNotice.vue +++ b/apps/files/src/components/DragAndDropNotice.vue @@ -192,8 +192,9 @@ export default defineComponent({ root: this.currentFolder.root!, id: Number.parseInt(upload.response?.headers?.['oc-fileid']), permissions: this.currentFolder.permissions, - crtime: new Date(), - mtime: new Date(), + crtime: new Date(upload.file.lastModified || Date.now()), + mtime: new Date(upload.file.lastModified || Date.now()), + mime: upload.response?.request?.headers?.['Content-Type'] ?? upload.file.type, })) } diff --git a/apps/files/src/components/FileEntry.vue b/apps/files/src/components/FileEntry.vue index 7d80a3aba59..9c4bab7736a 100644 --- a/apps/files/src/components/FileEntry.vue +++ b/apps/files/src/components/FileEntry.vue @@ -15,8 +15,9 @@ :draggable="canDrag" class="files-list__row" v-files-drop="{ - enabled: isFolder, + disabled: !isFolder, targetFolder: source, + callback: onDrop, }" v-on="rowListeners"> <!-- Failed indicator --> diff --git a/apps/files/src/components/FileEntryMixin.ts b/apps/files/src/components/FileEntryMixin.ts index 9798a312935..1f6c7035f85 100644 --- a/apps/files/src/components/FileEntryMixin.ts +++ b/apps/files/src/components/FileEntryMixin.ts @@ -11,6 +11,7 @@ import { generateUrl } from '@nextcloud/router' import { isPublicShare } from '@nextcloud/sharing/public' import { t } from '@nextcloud/l10n' import { vOnClickOutside } from '@vueuse/components' +import { extname } from 'path' import Vue, { computed, defineComponent } from 'vue' import { action as sidebarAction } from '../actions/sidebarAction.ts' @@ -374,6 +375,14 @@ export default defineComponent({ this.dragover = false }, + /** + * Callback when the drop listener is done. + * We reset the dragover state. + */ + onDrop() { + this.dragover = false + }, + async onDragStart(event: DragEvent) { event.stopPropagation() if (!this.canDrag || !this.fileid) { diff --git a/apps/files/src/directives/vFilesDrop.ts b/apps/files/src/directives/vFilesDrop.ts index c54169df6d1..dd4eb1198c9 100644 --- a/apps/files/src/directives/vFilesDrop.ts +++ b/apps/files/src/directives/vFilesDrop.ts @@ -36,6 +36,7 @@ const onFileDrop: DirectiveHook<HTMLElement, VNode | null, OnFileDropProperties // We need to use `ondrop` instead of addEventListener as we have no reference to previous // event listener to remove it from the component el.ondrop = async (event: DragEvent) => { + const dataTransfer = event.dataTransfer const options = typeof value === 'function' ? await value() : value logger.debug('Start handling drop', { options }) @@ -56,13 +57,14 @@ const onFileDrop: DirectiveHook<HTMLElement, VNode | null, OnFileDropProperties } // Skip handling if event was aborted by the user (clicking somewhere) if (event.button > 0) { + logger.debug('Drop aborted by user') return options.callback?.([]) } let result: INode[]|Upload[] = [] const draggingStore = useDragAndDropStore() if (draggingStore.isDragging) { - // Internal files are being dragged + logger.debug('Internal files are being dragged') const filesStore = useFilesStore() const nodes = filesStore.getNodes(draggingStore.dragging) await onDropInternalFiles( @@ -71,12 +73,15 @@ const onFileDrop: DirectiveHook<HTMLElement, VNode | null, OnFileDropProperties event.ctrlKey, ) result = nodes - } else if (event.dataTransfer) { + } else if (dataTransfer) { + logger.debug('Dropped external files') const uploads = await onDropExternalFiles( - event.dataTransfer, + dataTransfer, options.targetFolder, ) result = uploads + } else { + logger.debug('Drag and drop: Neither internal files are being dropped nor a datatransfer is available', { event }) } return options.callback?.(result) |