import React, { useState, useRef, useEffect } from "react"; import { Send, Code, Lightbulb, Flame, ChevronDown, Cpu, Square, Bot, MessageCircle, ImagePlus, X, FolderOpen } from "lucide-react"; import { filesToAttachments, mergeAttachments, MAX_IMAGES } from "../lib/imageAttachments"; const MODES = [ { id: "tech", label: "Tech", Icon: Code }, { id: "creatif", label: "Créatif", Icon: Lightbulb }, { id: "brutal", label: "Brutal", Icon: Flame }, ]; export const ChatComposer = ({ mode, onChangeMode, modelPreference, onChangeModelPreference, availableModels, useAgentTools, onChangeUseAgentTools, agentProjectPath, onChangeAgentProjectPath, agentStatus, onSend, onCancel, disabled, streaming, }) => { const [value, setValue] = useState(""); const [attachments, setAttachments] = useState([]); const [openPicker, setOpenPicker] = useState(null); const [dragOver, setDragOver] = useState(false); const textareaRef = useRef(null); const pickerRef = useRef(null); const modelPickerRef = useRef(null); const fileInputRef = useRef(null); const models = availableModels?.length ? availableModels : [{ id: "auto", label: "Auto" }]; const sortedModels = [...models].sort((a, b) => { if (a.id === "auto") return -1; if (b.id === "auto") return 1; if (a.uncensored && !b.uncensored) return -1; if (!a.uncensored && b.uncensored) return 1; return 0; }); useEffect(() => { const el = textareaRef.current; if (!el) return; el.style.height = "auto"; el.style.height = Math.min(el.scrollHeight, 180) + "px"; }, [value]); useEffect(() => { if (!openPicker) return; const onClick = (e) => { const ref = openPicker === "mode" ? pickerRef : modelPickerRef; if (ref.current && !ref.current.contains(e.target)) setOpenPicker(null); }; document.addEventListener("mousedown", onClick); return () => document.removeEventListener("mousedown", onClick); }, [openPicker]); const togglePicker = (id) => setOpenPicker((prev) => (prev === id ? null : id)); const addFiles = async (files) => { const incoming = await filesToAttachments(files); if (!incoming.length) return; setAttachments((prev) => mergeAttachments(prev, incoming)); }; const submit = () => { const v = value.trim(); if ((!v && !attachments.length) || disabled) return; onSend(v, attachments.map((a) => a.base64), attachments.map((a) => a.mediaType)); setValue(""); setAttachments([]); }; const currentMode = MODES.find((m) => m.id === mode) || MODES[0]; const CurrentIcon = currentMode.Icon; const currentModel = models.find((m) => m.id === (modelPreference || "auto")) || models[0]; const modelShort = currentModel.id === "auto" ? "Auto" : (currentModel.label || currentModel.id).split("(")[0].trim().slice(0, 18); return (
{ e.preventDefault(); setDragOver(true); }} onDragLeave={() => setDragOver(false)} onDrop={(e) => { e.preventDefault(); setDragOver(false); addFiles(e.dataTransfer?.files); }} > {/* Top toolbar: mode + model + chat/agent toggle */}
{openPicker === "mode" && (
{MODES.map((m) => { const Icon = m.Icon; const active = m.id === mode; return ( ); })}
)}
{openPicker === "model" && (
{sortedModels.map((m) => { const active = m.id === (modelPreference || "auto"); return ( ); })}
)}
{useAgentTools && (
onChangeAgentProjectPath?.(e.target.value)} placeholder="Dossier projet agent (ex. C:\Users\admin\Desktop\JarvisProjects\mon_projet)" className="flex-1 min-w-0 bg-transparent border-b border-[var(--emo-border)] py-0.5 font-code text-[10px] outline-none focus:border-[var(--emo-accent)]" spellCheck={false} />
{agentStatus ? (

{agentStatus}

) : null}
)} {attachments.length > 0 && (
{attachments.map((a) => (
{a.name {a.name && ( {a.name} )}
))}
)} {/* Textarea */}