mirror of
https://github.com/nextcloud/server.git
synced 2026-04-12 20:47:04 -04:00
Merge pull request #42366 from nextcloud/fix/dragdrop-join
This commit is contained in:
commit
aae99606e0
6 changed files with 107 additions and 18 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@ export default defineComponent({
|
|||
FileEntryGrid,
|
||||
headers: getFileListHeaders(),
|
||||
scrollToIndex: 0,
|
||||
dndNoticeHeight: 0,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -259,7 +258,10 @@ export default defineComponent({
|
|||
onDragOver(event: DragEvent) {
|
||||
// Detect if we're only dragging existing files or not
|
||||
const isForeignFile = event.dataTransfer?.types.includes('Files')
|
||||
|
||||
if (isForeignFile) {
|
||||
// Only handle uploading of existing Nextcloud files
|
||||
// See DragAndDropNotice for handling of foreign files
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,13 @@
|
|||
import type { Upload } from '@nextcloud/upload'
|
||||
import type { FileStat, ResponseDataDetailed } from 'webdav'
|
||||
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { davGetClient, davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { emit } from '@nextcloud/event-bus'
|
||||
import { getUploader } from '@nextcloud/upload'
|
||||
import { joinPaths } from '@nextcloud/paths'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
|
||||
import logger from '../logger.js'
|
||||
|
||||
export const handleDrop = async (data: DataTransfer) => {
|
||||
|
|
@ -85,10 +87,12 @@ const handleRecursiveUpload = async (entry: FileSystemEntry, path: string = ''):
|
|||
]
|
||||
} else {
|
||||
const directory = entry as FileSystemDirectoryEntry
|
||||
logger.debug('Handle directory recursivly', { name: directory.name })
|
||||
|
||||
// TODO: Implement this on `@nextcloud/upload`
|
||||
const absolutPath = `${davRootPath}${getUploader().destination.path}${path}${directory.name}`
|
||||
const absolutPath = joinPaths(davRootPath, getUploader().destination.path, path, directory.name)
|
||||
|
||||
logger.debug('Handle directory recursively', { name: directory.name, absolutPath })
|
||||
|
||||
const davClient = davGetClient()
|
||||
const dirExists = await davClient.exists(absolutPath)
|
||||
if (!dirExists) {
|
||||
|
|
|
|||
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
22
dist/files-main.js.LICENSE.txt
vendored
22
dist/files-main.js.LICENSE.txt
vendored
|
|
@ -168,6 +168,28 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
|
|
|
|||
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue