import { useState, useRef } from "react"; export default function InputBar({ onSubmit, disabled }) { const [image, setImage] = useState(null); const [audio, setAudio] = useState(null); const [text, setText] = useState(""); const [isRecording, setIsRecording] = useState(false); const mediaRecorderRef = useRef(null); const audioChunksRef = useRef([]); const fileInputRef = useRef(null); const recordingTimeoutRef = useRef(null); function handleImageSelect(e) { const file = e.target.files?.[0]; if (!file) return; setImage({ url: URL.createObjectURL(file), file }); } async function startRecording() { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const recorder = new MediaRecorder(stream); audioChunksRef.current = []; recorder.ondataavailable = (e) => { if (e.data.size > 0) audioChunksRef.current.push(e.data); }; recorder.onstop = () => { clearTimeout(recordingTimeoutRef.current); const blob = new Blob(audioChunksRef.current, { type: "audio/webm" }); setAudio({ url: URL.createObjectURL(blob), blob }); stream.getTracks().forEach((t) => t.stop()); }; recordingTimeoutRef.current = setTimeout(() => { if (recorder.state === "recording") recorder.stop(); }, 30_000); mediaRecorderRef.current = recorder; recorder.start(); setIsRecording(true); } catch (err) { console.error("Mic access denied:", err); } } function stopRecording() { mediaRecorderRef.current?.stop(); setIsRecording(false); } function handleSubmit() { if (!image && !audio && !text.trim()) return; onSubmit({ imageUrl: image?.url || null, audioUrl: audio?.url || null, text: text.trim() || null, }); setImage(null); setAudio(null); setText(""); } const hasInput = image || audio || text.trim(); return (
{/* Previews */} {(image || audio) && (
{image && (
Upload
)} {audio && (
)}
)} {/* Input row */}
setText(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter" && hasInput && !disabled) handleSubmit(); }} placeholder="Message Gemma 4..." disabled={disabled} className="flex-1 bg-[var(--color-surface)] border border-[var(--color-outline)] rounded-xl px-4 py-2.5 text-sm text-[var(--color-text)] placeholder:text-[var(--color-text-secondary)]/50 focus:border-[var(--color-blue)]/50 focus:outline-none disabled:opacity-50" />
); }