SarahXia0405 commited on
Commit
9ebc710
·
verified ·
1 Parent(s): 682a815

Update web/src/App.tsx

Browse files
Files changed (1) hide show
  1. web/src/App.tsx +31 -29
web/src/App.tsx CHANGED
@@ -890,34 +890,40 @@ function App() {
890
  // =========================
891
  // ✅ File Upload (FIXED)
892
  // =========================
893
- const handleFileUpload = (files: File[]) => {
 
 
 
 
894
  const newFiles: UploadedFile[] = files.map((file) => ({ file, type: "other" as FileType }));
895
  setUploadedFiles((prev) => [...prev, ...newFiles]);
896
  };
897
-
898
- // Robust remove: supports index OR File OR UploadedFile payload
899
- const handleRemoveFile = (arg: number | File | UploadedFile) => {
900
  setUploadedFiles((prev) => {
901
  if (!prev.length) return prev;
902
 
903
  let idx = -1;
904
 
905
- // Case 1: ChatArea passes index
906
  if (typeof arg === "number") {
907
  idx = arg;
908
  } else {
909
- // Case 2: ChatArea passes File or UploadedFile
910
  const file =
911
- (arg as UploadedFile)?.file instanceof File
912
  ? (arg as UploadedFile).file
913
- : (arg as File);
 
 
914
 
915
- idx = prev.findIndex(
916
- (x) =>
917
- x.file.name === file.name &&
918
- x.file.size === file.size &&
919
- x.file.lastModified === file.lastModified
920
- );
 
 
921
  }
922
 
923
  if (idx < 0 || idx >= prev.length) return prev;
@@ -925,7 +931,6 @@ function App() {
925
  const removed = prev[idx]?.file;
926
  const next = prev.filter((_, i) => i !== idx);
927
 
928
- // keep fingerprint set consistent
929
  if (removed) {
930
  const fp = `${removed.name}::${removed.size}::${removed.lastModified}`;
931
  uploadedFingerprintsRef.current.delete(fp);
@@ -934,25 +939,22 @@ function App() {
934
  return next;
935
  });
936
  };
937
-
938
- // FIX 2: NO await inside setState updater (prevents Vite/esbuild error)
939
  const handleFileTypeChange = async (index: number, type: FileType) => {
940
  if (!user) return;
941
-
942
  const target = uploadedFiles[index]?.file;
943
  if (!target) return;
944
-
945
- // update UI first (sync)
946
- setUploadedFiles((prev) => {
947
- if (index < 0 || index >= prev.length) return prev;
948
- return prev.map((f, i) => (i === index ? { ...f, type } : f));
949
- });
950
-
951
- // de-dupe upload per file fingerprint
952
  const fp = `${target.name}::${target.size}::${target.lastModified}`;
953
  if (uploadedFingerprintsRef.current.has(fp)) return;
954
  uploadedFingerprintsRef.current.add(fp);
955
-
956
  try {
957
  await apiUpload({
958
  user_id: user.email,
@@ -961,9 +963,9 @@ function App() {
961
  });
962
  toast.success("File uploaded to backend");
963
  } catch (e: any) {
964
- // allow retry
965
- uploadedFingerprintsRef.current.delete(fp);
966
  toast.error(e?.message || "Upload failed");
 
 
967
  }
968
  };
969
 
 
890
  // =========================
891
  // ✅ File Upload (FIXED)
892
  // =========================
893
+ // 1) Upload: accept File[] OR FileList OR null
894
+ const handleFileUpload = (input: File[] | FileList | null | undefined) => {
895
+ const files = Array.isArray(input) ? input : input ? Array.from(input) : [];
896
+ if (!files.length) return;
897
+
898
  const newFiles: UploadedFile[] = files.map((file) => ({ file, type: "other" as FileType }));
899
  setUploadedFiles((prev) => [...prev, ...newFiles]);
900
  };
901
+
902
+ // 2) Remove: accept index OR File OR UploadedFile (use any to avoid prop signature mismatch crash)
903
+ const handleRemoveFile = (arg: any) => {
904
  setUploadedFiles((prev) => {
905
  if (!prev.length) return prev;
906
 
907
  let idx = -1;
908
 
 
909
  if (typeof arg === "number") {
910
  idx = arg;
911
  } else {
 
912
  const file =
913
+ arg?.file instanceof File
914
  ? (arg as UploadedFile).file
915
+ : arg instanceof File
916
+ ? (arg as File)
917
+ : null;
918
 
919
+ if (file) {
920
+ idx = prev.findIndex(
921
+ (x) =>
922
+ x.file.name === file.name &&
923
+ x.file.size === file.size &&
924
+ x.file.lastModified === file.lastModified
925
+ );
926
+ }
927
  }
928
 
929
  if (idx < 0 || idx >= prev.length) return prev;
 
931
  const removed = prev[idx]?.file;
932
  const next = prev.filter((_, i) => i !== idx);
933
 
 
934
  if (removed) {
935
  const fp = `${removed.name}::${removed.size}::${removed.lastModified}`;
936
  uploadedFingerprintsRef.current.delete(fp);
 
939
  return next;
940
  });
941
  };
942
+
943
+ // 3) Type Change: must be async, and must NOT leave "await" outside
944
  const handleFileTypeChange = async (index: number, type: FileType) => {
945
  if (!user) return;
946
+
947
  const target = uploadedFiles[index]?.file;
948
  if (!target) return;
949
+
950
+ // update UI state immediately
951
+ setUploadedFiles((prev) => prev.map((f, i) => (i === index ? { ...f, type } : f)));
952
+
953
+ // dedupe upload per file fingerprint
 
 
 
954
  const fp = `${target.name}::${target.size}::${target.lastModified}`;
955
  if (uploadedFingerprintsRef.current.has(fp)) return;
956
  uploadedFingerprintsRef.current.add(fp);
957
+
958
  try {
959
  await apiUpload({
960
  user_id: user.email,
 
963
  });
964
  toast.success("File uploaded to backend");
965
  } catch (e: any) {
 
 
966
  toast.error(e?.message || "Upload failed");
967
+ // allow retry if failed
968
+ uploadedFingerprintsRef.current.delete(fp);
969
  }
970
  };
971