"use client"; import { useId, useSyncExternalStore } from "react"; import { SpeakerIcon, StopIcon } from "@/components/icons"; import { useI18n, useLocale } from "@/lib/i18n"; import { isSpeaking, speak, speechAvailable, speechLocale, stopSpeaking, subscribeSpeech } from "@/lib/speech"; import { cn } from "@/lib/utils"; /** * Small round "read this aloud" control, placed next to the text a learner is * meant to read (a flashcard face, a question, a statement, an instruction). * It renders nothing where the browser has no speech synthesis, so no card * carries a dead button, and it flips to a stop control while it is the * utterance playing. */ export function SpeakButton({ text, language, className, }: { text: string; /** The deck's language, so the voice matches the text. */ language?: string; className?: string; }) { const { t } = useI18n(); const locale = useLocale(); const id = useId(); const speaking = useSyncExternalStore( subscribeSpeech, () => isSpeaking(id), () => false, ); if (!speechAvailable()) return null; return ( ); }