|
|
|
@ -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
|
|
|
|
|
}
|
|
|
|
|