feat: add drag-and-drop file upload to Cloud folders
Drag files over the native file browser area to see a drop zone overlay with dashed orange border. Dropping files triggers the existing upload handler. Uses debounced dragleave to prevent flicker between children. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
37105e6be6
commit
621d74bfb3
@@ -72,7 +72,23 @@
|
||||
</div>
|
||||
|
||||
<!-- Native File Browser (for FileBrowser-backed sections) -->
|
||||
<div v-else-if="useNativeUI" class="flex-1 min-h-0 flex flex-col">
|
||||
<div
|
||||
v-else-if="useNativeUI"
|
||||
class="flex-1 min-h-0 flex flex-col relative"
|
||||
@dragover.prevent="onDragOver"
|
||||
@dragleave="onDragLeave"
|
||||
@drop.prevent="onDrop"
|
||||
>
|
||||
<!-- Drag-and-drop overlay -->
|
||||
<div v-if="draggingOver" class="cloud-drop-overlay">
|
||||
<div class="cloud-drop-overlay-inner">
|
||||
<svg class="w-12 h-12 text-white/80 mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
||||
</svg>
|
||||
<p class="text-lg font-medium text-white/90">Drop files to upload</p>
|
||||
<p class="text-sm text-white/50">Files will be added to the current folder</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Upload progress -->
|
||||
<div v-if="uploading" class="glass-card p-3 mb-3 flex items-center gap-3">
|
||||
<div class="w-5 h-5 border-2 border-white/20 border-t-white/80 rounded-full animate-spin"></div>
|
||||
@@ -274,6 +290,27 @@ watch(useNativeUI, async (native) => {
|
||||
}, { immediate: true })
|
||||
|
||||
const uploadError = ref<string | null>(null)
|
||||
const draggingOver = ref(false)
|
||||
let dragLeaveTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
function onDragOver() {
|
||||
if (dragLeaveTimer) { clearTimeout(dragLeaveTimer); dragLeaveTimer = null }
|
||||
draggingOver.value = true
|
||||
}
|
||||
|
||||
function onDragLeave() {
|
||||
// Debounce to avoid flicker when dragging between child elements
|
||||
if (dragLeaveTimer) clearTimeout(dragLeaveTimer)
|
||||
dragLeaveTimer = setTimeout(() => { draggingOver.value = false }, 100)
|
||||
}
|
||||
|
||||
function onDrop(e: DragEvent) {
|
||||
draggingOver.value = false
|
||||
if (dragLeaveTimer) { clearTimeout(dragLeaveTimer); dragLeaveTimer = null }
|
||||
const dt = e.dataTransfer
|
||||
if (!dt?.files?.length) return
|
||||
handleUpload(Array.from(dt.files))
|
||||
}
|
||||
|
||||
async function handleUpload(files: File[]) {
|
||||
uploading.value = true
|
||||
|
||||
Reference in New Issue
Block a user