fix(upload): fix multi-file drag-and-drop only uploading one file
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -214,22 +214,40 @@ async function traverseFileEntry(entry, files) {
|
|||||||
* Extract all File objects from a DataTransfer, recursively expanding any
|
* Extract all File objects from a DataTransfer, recursively expanding any
|
||||||
* dropped directories. Falls back gracefully to dataTransfer.files when the
|
* dropped directories. Falls back gracefully to dataTransfer.files when the
|
||||||
* FileSystem Entry API is unavailable (Safari < 11.1, some mobile browsers).
|
* FileSystem Entry API is unavailable (Safari < 11.1, some mobile browsers).
|
||||||
|
*
|
||||||
|
* IMPORTANT: DataTransferItemList is only accessible synchronously during the
|
||||||
|
* drop event handler. All entries and fallback File objects must be collected
|
||||||
|
* in a single synchronous pass before any `await`, otherwise the browser clears
|
||||||
|
* the list after the first yield — causing only the first file to be captured
|
||||||
|
* when multiple files are dropped.
|
||||||
|
*
|
||||||
* @param {DataTransfer} dataTransfer
|
* @param {DataTransfer} dataTransfer
|
||||||
* @returns {Promise<File[]>}
|
* @returns {Promise<File[]>}
|
||||||
*/
|
*/
|
||||||
async function getFilesFromDataTransfer(dataTransfer) {
|
async function getFilesFromDataTransfer(dataTransfer) {
|
||||||
if (dataTransfer.items && dataTransfer.items.length > 0) {
|
if (dataTransfer.items && dataTransfer.items.length > 0) {
|
||||||
const files = [];
|
// ── Synchronous pass ───────────────────────────────────────────────────
|
||||||
|
// Collect all FileSystemEntry objects and any plain File fallbacks NOW,
|
||||||
|
// before the first `await`, while the DataTransferItemList is still valid.
|
||||||
|
const entries = [];
|
||||||
|
const fallbackFiles = [];
|
||||||
for (let i = 0; i < dataTransfer.items.length; i++) {
|
for (let i = 0; i < dataTransfer.items.length; i++) {
|
||||||
const item = dataTransfer.items[i];
|
const item = dataTransfer.items[i];
|
||||||
const entry = item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
|
const entry = item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
|
||||||
if (entry) {
|
if (entry) {
|
||||||
await traverseFileEntry(entry, files);
|
entries.push(entry);
|
||||||
} else if (item.kind === 'file') {
|
} else if (item.kind === 'file') {
|
||||||
const file = item.getAsFile();
|
const file = item.getAsFile();
|
||||||
if (file) files.push(file);
|
if (file) fallbackFiles.push(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ── Asynchronous traversal ─────────────────────────────────────────────
|
||||||
|
// DataTransferItemList is no longer needed here; we work only with the
|
||||||
|
// already-captured FileSystemEntry objects and File objects.
|
||||||
|
const files = [...fallbackFiles];
|
||||||
|
for (const entry of entries) {
|
||||||
|
await traverseFileEntry(entry, files);
|
||||||
|
}
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
return Array.from(dataTransfer.files || []);
|
return Array.from(dataTransfer.files || []);
|
||||||
|
|||||||
Reference in New Issue
Block a user