From f30482808bc52c1f851fe6f01eef3f6b6dcea417 Mon Sep 17 00:00:00 2001 From: Johannes Zellner Date: Wed, 11 Mar 2026 15:11:16 +0100 Subject: [PATCH] Workaround chrome quirks on file drop handling --- dashboard/src/components/FolderView.vue | 53 +++++++++++++++++++------ 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/dashboard/src/components/FolderView.vue b/dashboard/src/components/FolderView.vue index 25251e012..bff35be4b 100644 --- a/dashboard/src/components/FolderView.vue +++ b/dashboard/src/components/FolderView.vue @@ -175,37 +175,66 @@ async function onDrop(targetFolder, dataTransfer, files) { }); } - async function readEntries(dirReader) { - return new Promise((resolve, reject) => { - dirReader.readEntries(resolve, reject); - }); + function setRelativePath(file, entry) { + const relativePath = (entry.fullPath || entry.name || '').replace(/^\//, ''); + if (relativePath) { + // trying with defineProperty() to better mimic native behavior adding a non-enumeratible property + try { + Object.defineProperty(file, 'webkitRelativePath', { value: relativePath }); + } catch { + file.webkitRelativePath = relativePath; + } + } + } + + + // wrapper as chrome only returns files in batches of 100 entries + async function readAllEntries(dirReader) { + const all = []; + let batch; + do { + batch = await new Promise((resolve, reject) => { + dirReader.readEntries(resolve, reject); + }); + all.push(...batch); + } while (batch.length > 0); + return all; } const fileList = []; async function traverseFileTree(item) { if (item.isFile) { - fileList.push(await getFile(item)); + const file = await getFile(item); + setRelativePath(file, item); + fileList.push(file); } else if (item.isDirectory) { - // Get folder contents const dirReader = item.createReader(); - const entries = await readEntries(dirReader); + const entries = await readAllEntries(dirReader); for (const i in entries) { - await traverseFileTree(entries[i], item.name); + await traverseFileTree(entries[i]); } } else { - console.log('Skipping uknown file type', item); + console.log('Skipping unknown file type', item); } } // collect all files to upload for (const item of dataTransfer.items) { - const entry = item.webkitGetAsEntry(); + const entry = item.webkitGetAsEntry ? item.webkitGetAsEntry() : null; + + if (!entry) { + const file = item.getAsFile ? item.getAsFile() : null; + if (file) fileList.push(file); + continue; + } if (entry.isFile) { - fileList.push(await getFile(entry)); + const file = await getFile(entry); + setRelativePath(file, entry); + fileList.push(file); } else if (entry.isDirectory) { - await traverseFileTree(entry, sanitize(`${cwd.value}/${targetFolder}`)); + await traverseFileTree(entry); } }