81
common/resources/client/uploads/utils/get-dropped-files.ts
Executable file
81
common/resources/client/uploads/utils/get-dropped-files.ts
Executable file
@@ -0,0 +1,81 @@
|
||||
import {UploadedFile} from '../uploaded-file';
|
||||
|
||||
export async function getDroppedFiles(
|
||||
dataTransfer: DataTransfer
|
||||
): Promise<UploadedFile[]> {
|
||||
let files: UploadedFile[] = [];
|
||||
|
||||
if (dataTransfer.items?.[0] && 'webkitGetAsEntry' in dataTransfer.items[0]) {
|
||||
// need to make a copy if transfer items and get entry here, it
|
||||
// might not be available anymore in subsequent loop iterations
|
||||
const entries = [...dataTransfer.items].map(item => {
|
||||
return item.webkitGetAsEntry();
|
||||
});
|
||||
for (const entry of entries) {
|
||||
if (entry && !entry.isDirectory) {
|
||||
files.push(await filesystemEntryToFile(entry as FileSystemFileEntry));
|
||||
} else if (entry) {
|
||||
files = [
|
||||
...files,
|
||||
...(await readDirRecursive(entry as FileSystemDirectoryEntry)),
|
||||
];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
files = [...dataTransfer.files].map(f => new UploadedFile(f));
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
function filesystemEntryToFile(
|
||||
entry: FileSystemFileEntry
|
||||
): Promise<UploadedFile> {
|
||||
return new Promise(resolve => {
|
||||
entry.file(file => {
|
||||
resolve(new UploadedFile(file, entry.fullPath));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function readDirRecursive(
|
||||
entry: FileSystemDirectoryEntry,
|
||||
files: UploadedFile[] = []
|
||||
) {
|
||||
const entries = await readEntries(entry);
|
||||
|
||||
for (const childEntry of entries) {
|
||||
if (childEntry.isDirectory) {
|
||||
await readDirRecursive(childEntry as FileSystemDirectoryEntry, files);
|
||||
} else {
|
||||
files.push(
|
||||
await filesystemEntryToFile(childEntry as FileSystemFileEntry)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
function readEntries(
|
||||
dir: FileSystemDirectoryEntry
|
||||
): Promise<FileSystemEntry[]> {
|
||||
return new Promise(resolve => {
|
||||
drainDirReader(dir.createReader(), resolve);
|
||||
});
|
||||
}
|
||||
|
||||
function drainDirReader(
|
||||
reader: FileSystemDirectoryReader,
|
||||
resolve: (value: FileSystemEntry[]) => void,
|
||||
allEntries: FileSystemEntry[] = []
|
||||
) {
|
||||
// directory reader needs to be called repeatedly until it returns an empty array
|
||||
reader.readEntries(entries => {
|
||||
if (entries.length) {
|
||||
allEntries = [...allEntries, ...entries];
|
||||
drainDirReader(reader, resolve, allEntries);
|
||||
} else {
|
||||
resolve(allEntries);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user