From 7e0790d60f346d91831853af47c2afc5b72cf96c Mon Sep 17 00:00:00 2001 From: "dayuan.jiang" Date: Thu, 27 Mar 2025 08:02:03 +0000 Subject: [PATCH] refactor: update setFiles prop type to accept File[] and simplify file handling --- components/chat-example-panel.tsx | 9 +-- components/chat-input.tsx | 76 ++++++-------------- components/chat-message-display.tsx | 2 +- components/chat-panel.tsx | 17 +++-- components/file-preview-list.tsx | 57 +++++++++++++++ package-lock.json | 105 ++++++++++++++++++++++++++++ 6 files changed, 199 insertions(+), 67 deletions(-) create mode 100644 components/file-preview-list.tsx diff --git a/components/chat-example-panel.tsx b/components/chat-example-panel.tsx index 7bbf8f2..f0bc446 100644 --- a/components/chat-example-panel.tsx +++ b/components/chat-example-panel.tsx @@ -3,13 +3,8 @@ export default function ExamplePanel({ setFiles, }: { setInput: (input: string) => void; - setFiles: (files: FileList | undefined) => void; + setFiles: (files: File[]) => void; }) { - const createFileList = (file: File): FileList => { - const dt = new DataTransfer(); - dt.items.add(file); - return dt.files; - }; // New handler for the "Replicate this flowchart" button const handleReplicateFlowchart = async () => { setInput("Replicate this flowchart."); @@ -21,7 +16,7 @@ export default function ExamplePanel({ const file = new File([blob], "example.png", { type: "image/png" }); // Set the file to the files state - setFiles(createFileList(file)); + setFiles([file]); } catch (error) { console.error("Error loading example image:", error); } diff --git a/components/chat-input.tsx b/components/chat-input.tsx index ad775f4..0f51f59 100644 --- a/components/chat-input.tsx +++ b/components/chat-input.tsx @@ -13,8 +13,7 @@ import { History, } from "lucide-react"; import { ButtonWithTooltip } from "@/components/button-with-tooltip"; -import Image from "next/image"; - +import { FilePreviewList } from "./file-preview-list"; import { useDiagram } from "@/contexts/diagram-context"; import { HistoryDialog } from "@/components/history-dialog"; @@ -24,8 +23,8 @@ interface ChatInputProps { onSubmit: (e: React.FormEvent) => void; onChange: (e: React.ChangeEvent) => void; onClearChat: () => void; - files?: FileList; - onFileChange?: (files: FileList | undefined) => void; + files?: File[]; + onFileChange?: (files: File[]) => void; showHistory?: boolean; onToggleHistory?: (show: boolean) => void; } @@ -36,8 +35,8 @@ export function ChatInput({ onSubmit, onChange, onClearChat, - files, - onFileChange, + files = [], + onFileChange = () => {}, showHistory = false, onToggleHistory = () => {}, }: ChatInputProps) { @@ -73,19 +72,24 @@ export function ChatInput({ // Handle file changes const handleFileChange = (e: React.ChangeEvent) => { - if (onFileChange) { - onFileChange(e.target.files || undefined); + const newFiles = Array.from(e.target.files || []); + onFileChange([...files, ...newFiles]); + }; + + // Remove individual file + const handleRemoveFile = (fileToRemove: File) => { + onFileChange(files.filter((file) => file !== fileToRemove)); + if (fileInputRef.current) { + fileInputRef.current.value = ""; } }; - // Clear file selection + // Clear all files const clearFiles = () => { if (fileInputRef.current) { fileInputRef.current.value = ""; } - if (onFileChange) { - onFileChange(undefined); - } + onFileChange([]); }; // Trigger file input click @@ -116,17 +120,12 @@ export function ChatInput({ const droppedFiles = e.dataTransfer.files; // Only process image files - if (droppedFiles.length > 0) { - const imageFiles = Array.from(droppedFiles).filter((file) => - file.type.startsWith("image/") - ); + const imageFiles = Array.from(droppedFiles).filter((file) => + file.type.startsWith("image/") + ); - if (imageFiles.length > 0 && onFileChange) { - // Create a new FileList-like object with only image files - const dt = new DataTransfer(); - imageFiles.forEach((file) => dt.items.add(file)); - onFileChange(dt.files); - } + if (imageFiles.length > 0) { + onFileChange([...files, ...imageFiles]); } }; @@ -156,38 +155,7 @@ export function ChatInput({ onDragLeave={handleDragLeave} onDrop={handleDrop} > - {/* File preview area */} - {files && files.length > 0 && ( -
- {Array.from(files).map((file, index) => ( -
-
- {file.type.startsWith("image/") ? ( - {file.name} - ) : ( -
- {file.name} -
- )} -
- -
- ))} -
- )} +