CR: check for supported image types, duplicate filenames

This commit is contained in:
starmorph
2025-05-19 16:11:38 -07:00
parent f3b616572b
commit 087587dad6

View File

@@ -215,29 +215,43 @@ export function Thread() {
setPdfUrlList([]); setPdfUrlList([]);
}; };
const SUPPORTED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
const SUPPORTED_FILE_TYPES = [...SUPPORTED_IMAGE_TYPES, "application/pdf"];
const isDuplicate = (file: File, images: Base64ContentBlock[], pdfs: Base64ContentBlock[]) => {
if (SUPPORTED_IMAGE_TYPES.includes(file.type)) {
return images.some(img => img.metadata?.name === file.name && img.mime_type === file.type);
}
if (file.type === "application/pdf") {
return pdfs.some(pdf => pdf.metadata?.filename === file.name);
}
return false;
};
const handleFileUpload = async (e: ChangeEvent<HTMLInputElement>) => { const handleFileUpload = async (e: ChangeEvent<HTMLInputElement>) => {
const files = e.target.files; const files = e.target.files;
if (!files) return; if (!files) return;
const fileArray = Array.from(files); const fileArray = Array.from(files);
const imageFiles = fileArray.filter((file) => const validFiles = fileArray.filter((file) => SUPPORTED_FILE_TYPES.includes(file.type));
file.type.startsWith("image"), const invalidFiles = fileArray.filter((file) => !SUPPORTED_FILE_TYPES.includes(file.type));
); const duplicateFiles = validFiles.filter((file) => isDuplicate(file, imageUrlList, pdfUrlList));
const pdfFiles = fileArray.filter( const uniqueFiles = validFiles.filter((file) => !isDuplicate(file, imageUrlList, pdfUrlList));
(file) => file.type === "application/pdf",
);
const invalidFiles = fileArray.filter(
(file) =>
!file.type.startsWith("image/") && file.type !== "application/pdf",
);
if (invalidFiles.length > 0) { if (invalidFiles.length > 0) {
toast.error( toast.error(
"You have uploaded invalid file type. Please upload an image or a PDF.", "You have uploaded invalid file type. Please upload a JPEG, PNG, GIF, WEBP image or a PDF.",
);
}
if (duplicateFiles.length > 0) {
toast.error(
`Duplicate file(s) detected: ${duplicateFiles.map(f => f.name).join(", ")}. Each file can only be uploaded once per message.`,
); );
} }
if (imageFiles.length) { const imageFiles = uniqueFiles.filter((file) => SUPPORTED_IMAGE_TYPES.includes(file.type));
const pdfFiles = uniqueFiles.filter((file) => file.type === "application/pdf");
if (imageFiles.length) {
const imageBlocks = await Promise.all(imageFiles.map(fileToImageBlock)); const imageBlocks = await Promise.all(imageFiles.map(fileToImageBlock));
setImageUrlList((prev) => [...prev, ...imageBlocks]); setImageUrlList((prev) => [...prev, ...imageBlocks]);
} }
@@ -281,18 +295,24 @@ export function Thread() {
if (!e.dataTransfer) return; if (!e.dataTransfer) return;
const files = Array.from(e.dataTransfer.files); const files = Array.from(e.dataTransfer.files);
const imageFiles = files.filter((file) => file.type.startsWith("image/")); const validFiles = files.filter((file) => SUPPORTED_FILE_TYPES.includes(file.type));
const pdfFiles = files.filter((file) => file.type === "application/pdf"); const invalidFiles = files.filter((file) => !SUPPORTED_FILE_TYPES.includes(file.type));
const invalidFiles = files.filter( const duplicateFiles = validFiles.filter((file) => isDuplicate(file, imageUrlList, pdfUrlList));
(file) => const uniqueFiles = validFiles.filter((file) => !isDuplicate(file, imageUrlList, pdfUrlList));
!file.type.startsWith("image/") && file.type !== "application/pdf",
);
if (invalidFiles.length > 0) { if (invalidFiles.length > 0) {
toast.error( toast.error(
"You have uploaded invalid file type. Please upload an image or a PDF.", "You have uploaded invalid file type. Please upload a JPEG, PNG, GIF, WEBP image or a PDF.",
); );
} }
if (duplicateFiles.length > 0) {
toast.error(
`Duplicate file(s) detected: ${duplicateFiles.map(f => f.name).join(", ")}. Each file can only be uploaded once per message.`,
);
}
const imageFiles = uniqueFiles.filter((file) => SUPPORTED_IMAGE_TYPES.includes(file.type));
const pdfFiles = uniqueFiles.filter((file) => file.type === "application/pdf");
if (imageFiles.length) { if (imageFiles.length) {
const imageBlocks: Base64ContentBlock[] = await Promise.all( const imageBlocks: Base64ContentBlock[] = await Promise.all(
@@ -586,7 +606,7 @@ export function Thread() {
type="file" type="file"
onChange={handleFileUpload} onChange={handleFileUpload}
multiple multiple
accept="image/*,application/pdf" accept="image/jpeg,image/png,image/gif,image/webp,application/pdf"
className="hidden" className="hidden"
/> />
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">