mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
Support folder drops in Design Files (#1662)
Co-authored-by: mzl2233 <mzl2233@users.noreply.github.com>
This commit is contained in:
parent
db9752f5ae
commit
b311885bee
1 changed files with 57 additions and 2 deletions
|
|
@ -37,6 +37,18 @@ type DesignFilesGroupMode = 'kind' | 'modified';
|
||||||
type ModifiedSection = 'today' | 'yesterday' | 'previous7Days' | 'previous30Days' | 'older';
|
type ModifiedSection = 'today' | 'yesterday' | 'previous7Days' | 'previous30Days' | 'older';
|
||||||
type SortKey = 'name' | 'kind' | 'mtime';
|
type SortKey = 'name' | 'kind' | 'mtime';
|
||||||
type SortDir = 'asc' | 'desc';
|
type SortDir = 'asc' | 'desc';
|
||||||
|
type FileSystemEntryWithReader = FileSystemEntry & {
|
||||||
|
createReader?: () => FileSystemDirectoryReader;
|
||||||
|
};
|
||||||
|
type FileSystemFileEntryWithFile = FileSystemFileEntry & {
|
||||||
|
file: (
|
||||||
|
successCallback: (file: File) => void,
|
||||||
|
errorCallback?: (error: DOMException) => void,
|
||||||
|
) => void;
|
||||||
|
};
|
||||||
|
type DataTransferItemWithEntry = DataTransferItem & {
|
||||||
|
webkitGetAsEntry?: () => FileSystemEntry | null;
|
||||||
|
};
|
||||||
|
|
||||||
const MODIFIED_SECTION_ORDER: ModifiedSection[] = [
|
const MODIFIED_SECTION_ORDER: ModifiedSection[] = [
|
||||||
'today',
|
'today',
|
||||||
|
|
@ -671,11 +683,11 @@ export function DesignFilesPanel({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDrop(ev: React.DragEvent<HTMLDivElement>) {
|
async function handleDrop(ev: React.DragEvent<HTMLDivElement>) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
dragDepthRef.current = 0;
|
dragDepthRef.current = 0;
|
||||||
setDraggingFiles(false);
|
setDraggingFiles(false);
|
||||||
const dropped = Array.from(ev.dataTransfer.files ?? []);
|
const dropped = await filesFromDataTransfer(ev.dataTransfer);
|
||||||
if (dropped.length > 0) onUploadFiles(dropped);
|
if (dropped.length > 0) onUploadFiles(dropped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1394,6 +1406,49 @@ function dateDaysBefore(date: Date, days: number): Date {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function filesFromDataTransfer(dataTransfer: DataTransfer): Promise<File[]> {
|
||||||
|
const items = Array.from(dataTransfer.items ?? []);
|
||||||
|
if (items.length === 0) return Array.from(dataTransfer.files ?? []);
|
||||||
|
|
||||||
|
const files = await Promise.all(items.map(filesFromDataTransferItem));
|
||||||
|
const flattened = files.flat();
|
||||||
|
return flattened.length > 0 ? flattened : Array.from(dataTransfer.files ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function filesFromDataTransferItem(item: DataTransferItem): Promise<File[]> {
|
||||||
|
const entry = (item as DataTransferItemWithEntry).webkitGetAsEntry?.();
|
||||||
|
if (!entry) {
|
||||||
|
const file = item.kind === 'file' ? item.getAsFile() : null;
|
||||||
|
return file ? [file] : [];
|
||||||
|
}
|
||||||
|
return filesFromFileSystemEntry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function filesFromFileSystemEntry(entry: FileSystemEntry): Promise<File[]> {
|
||||||
|
if (entry.isFile) return [await fileFromEntry(entry as FileSystemFileEntryWithFile)];
|
||||||
|
if (!entry.isDirectory) return [];
|
||||||
|
|
||||||
|
const reader = (entry as FileSystemEntryWithReader).createReader?.();
|
||||||
|
if (!reader) return [];
|
||||||
|
|
||||||
|
const files: File[] = [];
|
||||||
|
for (;;) {
|
||||||
|
const entries = await readEntryBatch(reader);
|
||||||
|
if (entries.length === 0) break;
|
||||||
|
const nested = await Promise.all(entries.map(filesFromFileSystemEntry));
|
||||||
|
files.push(...nested.flat());
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileFromEntry(entry: FileSystemFileEntryWithFile): Promise<File> {
|
||||||
|
return new Promise((resolve, reject) => entry.file(resolve, reject));
|
||||||
|
}
|
||||||
|
|
||||||
|
function readEntryBatch(reader: FileSystemDirectoryReader): Promise<FileSystemEntry[]> {
|
||||||
|
return new Promise((resolve, reject) => reader.readEntries(resolve, reject));
|
||||||
|
}
|
||||||
|
|
||||||
function kindGlyph(kind: ProjectFileKind): string {
|
function kindGlyph(kind: ProjectFileKind): string {
|
||||||
if (kind === 'html') return '\u27E8\u27E9';
|
if (kind === 'html') return '\u27E8\u27E9';
|
||||||
if (kind === 'image') return '\u25A3';
|
if (kind === 'image') return '\u25A3';
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue