upload multi files

This commit is contained in:
2026-03-17 16:56:34 +08:00
parent d01d7636c8
commit 9a6e6b8ecb
2 changed files with 57 additions and 52 deletions

View File

@@ -12,7 +12,7 @@ import { CloudUpload } from "lucide-react";
interface DropZoneProps { interface DropZoneProps {
fileType: "js" | "css"; fileType: "js" | "css";
isSaving: boolean; isSaving: boolean;
onFileSelected: (file: File) => Promise<void>; onFileSelected: (files: File[]) => Promise<void>;
} }
const useStyles = createStyles(({ token, css }) => ({ const useStyles = createStyles(({ token, css }) => ({
@@ -56,9 +56,9 @@ const DropZone: React.FC<DropZoneProps> = ({ fileType, isSaving, onFileSelected
const handleChange = useCallback( const handleChange = useCallback(
async (e: React.ChangeEvent<HTMLInputElement>) => { async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]; const files = Array.from(e.target.files || []);
if (file) { if (files.length > 0) {
await onFileSelected(file); await onFileSelected(files);
} }
e.target.value = ""; e.target.value = "";
}, },
@@ -84,6 +84,7 @@ const DropZone: React.FC<DropZoneProps> = ({ fileType, isSaving, onFileSelected
ref={inputRef} ref={inputRef}
type="file" type="file"
accept={`.${fileType}`} accept={`.${fileType}`}
multiple
style={{ display: "none" }} style={{ display: "none" }}
onChange={handleChange} onChange={handleChange}
/> />

View File

@@ -127,57 +127,61 @@ const FileSection: React.FC<FileSectionProps> = ({
// ── Shared save logic ───────────────────────────────────────────────────── // ── Shared save logic ─────────────────────────────────────────────────────
const saveFile = useCallback( const saveFile = useCallback(
async (file: File) => { async (fileOrFiles: File | File[]) => {
const ext = file.name.split(".").pop()?.toLowerCase(); const files = Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles];
if (ext !== fileType) {
message.error(t("fileTypeNotSupported", { expected: `.${fileType}` }));
return;
}
if (file.size > MAX_FILE_SIZE) {
message.error(t("fileSizeExceeded"));
return;
}
const sourcePath = for (const file of files) {
window.api.getPathForFile(file) || (file as File & { path?: string }).path; const ext = file.name.split(".").pop()?.toLowerCase();
if (!sourcePath) { if (ext !== fileType) {
message.error(t("fileAddFailed")); message.error(t("fileTypeNotSupported", { expected: `.${fileType}` }));
return; continue;
} }
if (file.size > MAX_FILE_SIZE) {
setIsSaving(true); message.error(t("fileSizeExceeded"));
try { continue;
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;
} }
const entry: FileEntry = { const sourcePath =
id: fileId, window.api.getPathForFile(file) || (file as File & { path?: string }).path;
fileName: result.data.fileName, if (!sourcePath) {
fileType, message.error(t("fileAddFailed"));
platform, continue;
status: "added", }
size: result.data.size,
storagePath: result.data.storagePath,
};
addFile(domainId, appId, entry); setIsSaving(true);
message.success(t("fileAdded", { name: result.data.fileName })); try {
} catch { const fileId = crypto.randomUUID();
message.error(t("fileAddFailed")); const result = await window.api.saveFile({
} finally { domainId,
setIsSaving(false); 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], [domainId, appId, platform, fileType, addFile, message, t],
@@ -248,7 +252,7 @@ const FileSection: React.FC<FileSectionProps> = ({
const droppedFiles = Array.from(e.dataTransfer.files); const droppedFiles = Array.from(e.dataTransfer.files);
if (droppedFiles.length === 0) return; if (droppedFiles.length === 0) return;
await saveFile(droppedFiles[0]); await saveFile(droppedFiles);
}, },
[saveFile], [saveFile],
); );