import { Send, Paperclip, X, GripHorizontal } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { useState, useRef, useEffect } from "react"; import { useToast } from "@/hooks/use-toast"; import { chatService } from "@/services/chat"; interface ChatInputProps { onSendMessage: (message: string, files?: File[]) => void; } export const ChatInput = ({ onSendMessage }: ChatInputProps) => { const [message, setMessage] = useState(""); const [attachedFiles, setAttachedFiles] = useState([]); const [textareaHeight, setTextareaHeight] = useState(60); const [isDragging, setIsDragging] = useState(false); const fileInputRef = useRef(null); const textareaRef = useRef(null); const dragStartY = useRef(0); const dragStartHeight = useRef(0); const { toast } = useToast(); const handleMouseDown = (e: React.MouseEvent) => { setIsDragging(true); dragStartY.current = e.clientY; dragStartHeight.current = textareaHeight; e.preventDefault(); }; useEffect(() => { const handleMouseMove = (e: MouseEvent) => { if (!isDragging) return; const deltaY = dragStartY.current - e.clientY; // Inverted: moving up = positive const newHeight = Math.min(400, Math.max(60, dragStartHeight.current + deltaY)); setTextareaHeight(newHeight); }; const handleMouseUp = () => { setIsDragging(false); }; if (isDragging) { document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); } return () => { document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; }, [isDragging, textareaHeight]); const handleSend = () => { if (message.trim() || attachedFiles.length > 0) { onSendMessage(message, attachedFiles); setMessage(""); setAttachedFiles([]); } }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); handleSend(); } }; const handleFileSelect = (e: React.ChangeEvent) => { const files = Array.from(e.target.files || []); const newFiles = [...attachedFiles, ...files]; // Valida quantidade máxima de anexos (5) if (newFiles.length > chatService.getMaxAttachments()) { toast({ title: "Limite de anexos excedido", description: `Você pode anexar no máximo ${chatService.getMaxAttachments()} arquivos por mensagem.`, variant: "destructive", }); if (fileInputRef.current) { fileInputRef.current.value = ""; } return; } // Valida tipos de arquivo e tamanho const validFiles: File[] = []; for (const file of files) { // Valida tamanho (max 10MB por arquivo) if (file.size > 10 * 1024 * 1024) { toast({ title: "Arquivo muito grande", description: `${file.name} excede o limite de 10MB`, variant: "destructive", }); continue; } validFiles.push(file); } // Valida formatos permitidos const allFiles = [...attachedFiles, ...validFiles]; const validation = chatService.validateAttachments(allFiles); if (!validation.valid) { toast({ title: "Formato de arquivo não permitido", description: validation.error, variant: "destructive", }); if (fileInputRef.current) { fileInputRef.current.value = ""; } return; } setAttachedFiles(allFiles); if (fileInputRef.current) { fileInputRef.current.value = ""; } }; const removeFile = (index: number) => { setAttachedFiles(attachedFiles.filter((_, i) => i !== index)); }; return (
{/* Attached Files Preview */} {attachedFiles.length > 0 && (
{attachedFiles.map((file, index) => (
{file.name} ({(file.size / 1024).toFixed(1)} KB)
))}
)} {/* Message Input and Buttons */}
{/* Resize Handle - Hidden on mobile */}
{/* Textarea */}