import { useCallback, useEffect, useRef, useState } from "react"; import { useSTT } from "../../hooks/useSTT"; import * as commands from "../../lib/tauri-commands"; interface Props { sessionId: string; sendInput: (sessionId: string, data: string) => Promise; } export default function SttButton({ sessionId, sendInput }: Props) { const { state, error, toggle, cancelRecording } = useSTT(sessionId, sendInput); const [elapsed, setElapsed] = useState(0); const timerRef = useRef | null>(null); // Track recording duration useEffect(() => { if (state === "recording") { setElapsed(0); timerRef.current = setInterval(() => setElapsed((e) => e + 1), 1000); } else { if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; } } return () => { if (timerRef.current) clearInterval(timerRef.current); }; }, [state]); const handleClick = useCallback(async () => { // Auto-start STT container if not running if (state === "idle") { try { const status = await commands.getSttStatus(); if (!status.running) { await commands.startStt(); } } catch { // Container start failed, toggle will still attempt transcription } } await toggle(); }, [state, toggle]); const handleContextMenu = useCallback( (e: React.MouseEvent) => { e.preventDefault(); if (state === "recording") { cancelRecording(); } }, [state, cancelRecording], ); const formatTime = (seconds: number) => { const m = Math.floor(seconds / 60); const s = seconds % 60; return `${m}:${s.toString().padStart(2, "0")}`; }; return (
{state === "recording" && ( {formatTime(elapsed)} )} {state === "error" && error && ( {error} )}
); }