From 9a6e6b8ecb088486017537c0e0fcd5d0367cd017 Mon Sep 17 00:00:00 2001 From: xue jiahao Date: Tue, 17 Mar 2026 16:56:34 +0800 Subject: [PATCH] upload multi files --- .../src/components/AppDetail/DropZone.tsx | 9 +- .../src/components/AppDetail/FileSection.tsx | 100 +++++++++--------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/renderer/src/components/AppDetail/DropZone.tsx b/src/renderer/src/components/AppDetail/DropZone.tsx index ab8039e..5a0e7a8 100644 --- a/src/renderer/src/components/AppDetail/DropZone.tsx +++ b/src/renderer/src/components/AppDetail/DropZone.tsx @@ -12,7 +12,7 @@ import { CloudUpload } from "lucide-react"; interface DropZoneProps { fileType: "js" | "css"; isSaving: boolean; - onFileSelected: (file: File) => Promise; + onFileSelected: (files: File[]) => Promise; } const useStyles = createStyles(({ token, css }) => ({ @@ -56,9 +56,9 @@ const DropZone: React.FC = ({ fileType, isSaving, onFileSelected const handleChange = useCallback( async (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (file) { - await onFileSelected(file); + const files = Array.from(e.target.files || []); + if (files.length > 0) { + await onFileSelected(files); } e.target.value = ""; }, @@ -84,6 +84,7 @@ const DropZone: React.FC = ({ fileType, isSaving, onFileSelected ref={inputRef} type="file" accept={`.${fileType}`} + multiple style={{ display: "none" }} onChange={handleChange} /> diff --git a/src/renderer/src/components/AppDetail/FileSection.tsx b/src/renderer/src/components/AppDetail/FileSection.tsx index b59c94d..3e9e5fd 100644 --- a/src/renderer/src/components/AppDetail/FileSection.tsx +++ b/src/renderer/src/components/AppDetail/FileSection.tsx @@ -127,57 +127,61 @@ const FileSection: React.FC = ({ // ── Shared save logic ───────────────────────────────────────────────────── const saveFile = useCallback( - async (file: File) => { - const ext = file.name.split(".").pop()?.toLowerCase(); - if (ext !== fileType) { - message.error(t("fileTypeNotSupported", { expected: `.${fileType}` })); - return; - } - if (file.size > MAX_FILE_SIZE) { - message.error(t("fileSizeExceeded")); - return; - } + async (fileOrFiles: File | File[]) => { + const files = Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles]; - const sourcePath = - window.api.getPathForFile(file) || (file as File & { path?: string }).path; - if (!sourcePath) { - message.error(t("fileAddFailed")); - return; - } - - setIsSaving(true); - try { - const fileId = crypto.randomUUID(); - const result = await window.api.saveFile({ - domainId, - appId, - platform, - fileType, - fileId, - sourcePath, - }); - - if (!result.success) { - message.error(result.error || t("fileAddFailed")); - return; + for (const file of files) { + const ext = file.name.split(".").pop()?.toLowerCase(); + if (ext !== fileType) { + message.error(t("fileTypeNotSupported", { expected: `.${fileType}` })); + continue; + } + if (file.size > MAX_FILE_SIZE) { + message.error(t("fileSizeExceeded")); + continue; } - const entry: FileEntry = { - id: fileId, - fileName: result.data.fileName, - fileType, - platform, - status: "added", - size: result.data.size, - storagePath: result.data.storagePath, - }; + const sourcePath = + window.api.getPathForFile(file) || (file as File & { path?: string }).path; + if (!sourcePath) { + message.error(t("fileAddFailed")); + continue; + } - addFile(domainId, appId, entry); - message.success(t("fileAdded", { name: result.data.fileName })); - } catch { - message.error(t("fileAddFailed")); - } finally { - setIsSaving(false); + setIsSaving(true); + try { + const fileId = crypto.randomUUID(); + const result = await window.api.saveFile({ + domainId, + appId, + platform, + fileType, + fileId, + sourcePath, + }); + + if (!result.success) { + message.error(result.error || t("fileAddFailed")); + continue; + } + + const entry: FileEntry = { + id: fileId, + fileName: result.data.fileName, + fileType, + platform, + status: "added", + size: result.data.size, + storagePath: result.data.storagePath, + }; + + addFile(domainId, appId, entry); + message.success(t("fileAdded", { name: result.data.fileName })); + } catch { + message.error(t("fileAddFailed")); + } finally { + setIsSaving(false); + } } }, [domainId, appId, platform, fileType, addFile, message, t], @@ -248,7 +252,7 @@ const FileSection: React.FC = ({ const droppedFiles = Array.from(e.dataTransfer.files); if (droppedFiles.length === 0) return; - await saveFile(droppedFiles[0]); + await saveFile(droppedFiles); }, [saveFile], );