Spaces:
Sleeping
Sleeping
File size: 2,823 Bytes
05c5ed5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | "use client";
import { useCallback } from "react";
import { appStore, UploadedFile } from "@/app/store";
import { useFileUpload } from "@/hooks/use-presigned-upload";
import { generateUUID } from "@/lib/utils";
import { toast } from "sonner";
export function useThreadFileUploader(threadId?: string) {
const appStoreMutate = appStore((s) => s.mutate);
const { upload } = useFileUpload();
const uploadFiles = useCallback(
async (files: File[]) => {
if (!threadId || files.length === 0) return;
const MAX_SIZE_BYTES = 50 * 1024 * 1024; // 50MB per file
for (const file of files) {
if (file.size > MAX_SIZE_BYTES) {
toast.error(`${file.name}: file too large (>50MB)`);
continue;
}
const previewUrl = file.type?.startsWith("image/")
? URL.createObjectURL(file)
: undefined;
const fileId = generateUUID();
const abortController = new AbortController();
const uploadingFile: UploadedFile = {
id: fileId,
url: "",
name: file.name,
mimeType: file.type || "application/octet-stream",
size: file.size,
isUploading: true,
progress: 0,
previewUrl,
abortController,
};
appStoreMutate((prev) => ({
threadFiles: {
...prev.threadFiles,
[threadId]: [...(prev.threadFiles[threadId] ?? []), uploadingFile],
},
}));
try {
const uploaded = await upload(file);
if (uploaded) {
appStoreMutate((prev) => ({
threadFiles: {
...prev.threadFiles,
[threadId]: (prev.threadFiles[threadId] ?? []).map((f) =>
f.id === fileId
? {
...f,
url: uploaded.url,
isUploading: false,
progress: 100,
}
: f,
),
},
}));
} else {
appStoreMutate((prev) => ({
threadFiles: {
...prev.threadFiles,
[threadId]: (prev.threadFiles[threadId] ?? []).filter(
(f) => f.id !== fileId,
),
},
}));
}
} catch (_err) {
appStoreMutate((prev) => ({
threadFiles: {
...prev.threadFiles,
[threadId]: (prev.threadFiles[threadId] ?? []).filter(
(f) => f.id !== fileId,
),
},
}));
} finally {
if (previewUrl) URL.revokeObjectURL(previewUrl);
}
}
},
[threadId, appStoreMutate, upload],
);
return { uploadFiles };
}
|