import React, { useEffect, useMemo, useRef, useState } from "react"; import { ArrowUp, ImagePlus, X } from "lucide-react"; import { cn } from "../lib/utils"; import { Textarea } from "./ui/textarea"; type MessageInputProps = { handleQueryChange: (event: React.ChangeEvent) => void; handleKeyDown: (event: React.ChangeEvent) => void; handleQuestionSubmit: () => void; setSimbaMode: (val: boolean) => void; query: string; isLoading: boolean; pendingImage: File | null; onImageSelect: (file: File) => void; onClearImage: () => void; }; export const MessageInput = React.memo(({ query, handleKeyDown, handleQueryChange, handleQuestionSubmit, setSimbaMode, isLoading, pendingImage, onImageSelect, onClearImage, }: MessageInputProps) => { const [simbaMode, setLocalSimbaMode] = useState(false); const fileInputRef = useRef(null); // Create blob URL once per file, revoke on cleanup const previewUrl = useMemo( () => (pendingImage ? URL.createObjectURL(pendingImage) : null), [pendingImage], ); useEffect(() => { return () => { if (previewUrl) URL.revokeObjectURL(previewUrl); }; }, [previewUrl]); const toggleSimbaMode = () => { const next = !simbaMode; setLocalSimbaMode(next); setSimbaMode(next); }; const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { onImageSelect(file); } // Reset so the same file can be re-selected e.target.value = ""; }; const canSend = !isLoading && (query.trim() || pendingImage); return (
{/* Image preview */} {pendingImage && (
Pending upload
)} {/* Textarea */}