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 {
fileType: "js" | "css";
isSaving: boolean;
onFileSelected: (file: File) => Promise<void>;
onFileSelected: (files: File[]) => Promise<void>;
}
const useStyles = createStyles(({ token, css }) => ({
@@ -56,9 +56,9 @@ const DropZone: React.FC<DropZoneProps> = ({ fileType, isSaving, onFileSelected
const handleChange = useCallback(
async (e: React.ChangeEvent<HTMLInputElement>) => {
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<DropZoneProps> = ({ fileType, isSaving, onFileSelected
ref={inputRef}
type="file"
accept={`.${fileType}`}
multiple
style={{ display: "none" }}
onChange={handleChange}
/>

View File

@@ -127,57 +127,61 @@ const FileSection: React.FC<FileSectionProps> = ({
// ── 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<FileSectionProps> = ({
const droppedFiles = Array.from(e.dataTransfer.files);
if (droppedFiles.length === 0) return;
await saveFile(droppedFiles[0]);
await saveFile(droppedFiles);
},
[saveFile],
);