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,22 +127,25 @@ 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 files = Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles];
for (const file of files) {
const ext = file.name.split(".").pop()?.toLowerCase(); const ext = file.name.split(".").pop()?.toLowerCase();
if (ext !== fileType) { if (ext !== fileType) {
message.error(t("fileTypeNotSupported", { expected: `.${fileType}` })); message.error(t("fileTypeNotSupported", { expected: `.${fileType}` }));
return; continue;
} }
if (file.size > MAX_FILE_SIZE) { if (file.size > MAX_FILE_SIZE) {
message.error(t("fileSizeExceeded")); message.error(t("fileSizeExceeded"));
return; continue;
} }
const sourcePath = const sourcePath =
window.api.getPathForFile(file) || (file as File & { path?: string }).path; window.api.getPathForFile(file) || (file as File & { path?: string }).path;
if (!sourcePath) { if (!sourcePath) {
message.error(t("fileAddFailed")); message.error(t("fileAddFailed"));
return; continue;
} }
setIsSaving(true); setIsSaving(true);
@@ -159,7 +162,7 @@ const FileSection: React.FC<FileSectionProps> = ({
if (!result.success) { if (!result.success) {
message.error(result.error || t("fileAddFailed")); message.error(result.error || t("fileAddFailed"));
return; continue;
} }
const entry: FileEntry = { const entry: FileEntry = {
@@ -179,6 +182,7 @@ const FileSection: React.FC<FileSectionProps> = ({
} finally { } finally {
setIsSaving(false); 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],
); );