import { useState, useRef, useEffect } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Send, Mic, MicOff, Paperclip, Sparkles } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { ProviderBadge } from "@/components/ProviderBadge"; import { AIProvider } from "@/types/chat"; import { cn } from "@/lib/utils"; interface ChatInputProps { onSendMessage: (message: string) => void; onFileUpload?: (file: File) => void; isLoading: boolean; isListening: boolean; transcript: string; provider: AIProvider; onStartListening: () => void; onStopListening: () => void; } export function ChatInput({ onSendMessage, onFileUpload, isLoading, isListening, transcript, provider, onStartListening, onStopListening, }: ChatInputProps) { const [input, setInput] = useState(""); const textareaRef = useRef(null); const fileInputRef = useRef(null); // Update input with voice transcript useEffect(() => { if (transcript && !isListening) { setInput(transcript); } }, [transcript, isListening]); const handleSubmit = () => { if (input.trim() && !isLoading) { onSendMessage(input.trim()); setInput(""); if (textareaRef.current) { textareaRef.current.style.height = "auto"; } } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleSubmit(); } }; const handleTextareaChange = (e: React.ChangeEvent) => { setInput(e.target.value); const textarea = e.target; textarea.style.height = "auto"; textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`; }; const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file && onFileUpload) { onFileUpload(file); } if (fileInputRef.current) { fileInputRef.current.value = ""; } }; return (
{/* Voice transcript indicator */} {isListening && (
{[...Array(3)].map((_, i) => (
))}
{transcript || "Listening..."}
)} {/* Input Container */}
{/* File Upload */} {/* Textarea */}