diff options
author | John Molakvoæ <skjnldsv@protonmail.com> | 2023-12-20 09:25:04 +0100 |
---|---|---|
committer | John Molakvoæ <skjnldsv@protonmail.com> | 2023-12-20 10:51:03 +0100 |
commit | dbfd8f612bbf4b243fbce9d223746cc5355975eb (patch) | |
tree | 3b98f5f28362b4b380c259cf0b2a3cab96412b90 /apps/files/src/components/DragAndDropNotice.vue | |
parent | 820b67a5e258b3bd78bfe35c0e7530c537e46143 (diff) | |
download | nextcloud-server-dbfd8f612bbf4b243fbce9d223746cc5355975eb.tar.gz nextcloud-server-dbfd8f612bbf4b243fbce9d223746cc5355975eb.zip |
fix(files): drag and drop events chain and cancel
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/files/src/components/DragAndDropNotice.vue')
-rw-r--r-- | apps/files/src/components/DragAndDropNotice.vue | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/apps/files/src/components/DragAndDropNotice.vue b/apps/files/src/components/DragAndDropNotice.vue index 66cddcaff97..df03713601d 100644 --- a/apps/files/src/components/DragAndDropNotice.vue +++ b/apps/files/src/components/DragAndDropNotice.vue @@ -25,23 +25,33 @@ class="files-list__drag-drop-notice" @drop="onDrop"> <div class="files-list__drag-drop-notice-wrapper"> - <TrayArrowDownIcon :size="48" /> - <h3 class="files-list-drag-drop-notice__title"> - {{ t('files', 'Drag and drop files here to upload') }} - </h3> + <template v-if="canUpload && !isQuotaExceeded"> + <TrayArrowDownIcon :size="48" /> + <h3 class="files-list-drag-drop-notice__title"> + {{ t('files', 'Drag and drop files here to upload') }} + </h3> + </template> + + <!-- Not permitted to drop files here --> + <template v-else> + <h3 class="files-list-drag-drop-notice__title"> + {{ cantUploadLabel }} + </h3> + </template> </div> </div> </template> <script lang="ts"> -import { translate as t } from '@nextcloud/l10n' import { defineComponent } from 'vue' +import { Folder, Permission } from '@nextcloud/files' +import { showError, showSuccess } from '@nextcloud/dialogs' +import { translate as t } from '@nextcloud/l10n' import TrayArrowDownIcon from 'vue-material-design-icons/TrayArrowDown.vue' import logger from '../logger.js' import { handleDrop } from '../services/DropService' -import { showSuccess } from '@nextcloud/dialogs' export default defineComponent({ name: 'DragAndDropNotice', @@ -52,7 +62,7 @@ export default defineComponent({ props: { currentFolder: { - type: Object, + type: Folder, required: true, }, }, @@ -63,35 +73,86 @@ export default defineComponent({ } }, + computed: { + /** + * Check if the current folder has create permissions + */ + canUpload() { + return this.currentFolder && (this.currentFolder.permissions & Permission.CREATE) !== 0 + }, + isQuotaExceeded() { + return this.currentFolder?.attributes?.['quota-available-bytes'] === 0 + }, + + cantUploadLabel() { + if (this.isQuotaExceeded) { + return this.t('files', 'Your have used your space quota and cannot upload files anymore') + } else if (!this.canUpload) { + return this.t('files', 'You don’t have permission to upload or create files here') + } + return null + }, + }, + mounted() { // Add events on parent to cover both the table and DragAndDrop notice const mainContent = window.document.querySelector('main.app-content') as HTMLElement mainContent.addEventListener('dragover', this.onDragOver) mainContent.addEventListener('dragleave', this.onDragLeave) + mainContent.addEventListener('drop', this.onContentDrop) }, beforeDestroy() { const mainContent = window.document.querySelector('main.app-content') as HTMLElement mainContent.removeEventListener('dragover', this.onDragOver) mainContent.removeEventListener('dragleave', this.onDragLeave) + mainContent.removeEventListener('drop', this.onContentDrop) }, methods: { onDragOver(event: DragEvent) { + // Needed to keep the drag/drop events chain working + event.preventDefault() + const isForeignFile = event.dataTransfer?.types.includes('Files') + + logger.debug('Drag over DragAndDropNotice', { isForeignFile, event }) if (isForeignFile) { - // Only handle uploading + // Only handle uploading of outside files (not Nextcloud files) this.dragover = true } }, - onDragLeave(/* event: DragEvent */) { + onDragLeave(event: DragEvent) { + // Counter bubbling, make sure we're ending the drag + // only when we're leaving the current element + // Avoid flickering + const currentTarget = event.currentTarget as HTMLElement + if (currentTarget?.contains(event.relatedTarget as HTMLElement)) { + return + } + + if (this.dragover) { + this.dragover = false + } + }, + + onContentDrop(event: DragEvent) { + logger.debug('Drag and drop cancelled, dropped on empty space', { event }) + event.preventDefault() if (this.dragover) { this.dragover = false } }, onDrop(event: DragEvent) { + logger.debug('Dropped on DragAndDropNotice', { event, error: this.cantUploadLabel }) + + if (!this.canUpload || this.isQuotaExceeded) { + showError(this.cantUploadLabel) + return + } + if (this.$el.querySelector('tbody')?.contains(event.target as Node)) { return } |