import { useCallback, useEffect, useRef } from 'react'; import { Mic, Loader2 } from 'lucide-react'; import { useAudioRecorder } from '@/lib/hooks/use-audio-recorder'; import { useI18n } from '@/lib/hooks/use-i18n'; import { cn } from '@/lib/utils'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; import { toast } from 'sonner'; interface SpeechButtonProps { onTranscription: (text: string) => void; className?: string; disabled?: boolean; size?: 'sm' | 'md'; } export function SpeechButton({ onTranscription, className, disabled, size = 'sm', }: SpeechButtonProps) { const { t } = useI18n(); // Ref to always call the latest onTranscription, avoiding stale closures const onTranscriptionRef = useRef(onTranscription); useEffect(() => { onTranscriptionRef.current = onTranscription; }, [onTranscription]); const stableOnTranscription = useCallback((text: string) => { onTranscriptionRef.current(text); }, []); const handleError = useCallback((error: string) => { toast.error(error); }, []); const { isRecording, isProcessing, startRecording, stopRecording } = useAudioRecorder({ onTranscription: stableOnTranscription, onError: handleError, }); const active = isRecording || isProcessing; const handleClick = () => { if (isRecording) { stopRecording(); } else if (!isProcessing) { startRecording(); } }; const isMd = size === 'md'; const sizeClasses = isMd ? 'h-8 w-8' : 'h-6 w-6'; const iconSize = isMd ? 'w-4 h-4' : 'w-3.5 h-3.5'; const barH = isMd ? 14 : 10; return ( {isProcessing ? t('roundtable.processing') : isRecording ? t('voice.stopListening') : t('voice.startListening')} ); }