import React, { useMemo } from 'react' import { useTextToSpeech } from '../hooks/useTextToSpeech' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faPlay, faPause, faGauge } from '@fortawesome/free-solid-svg-icons' import { UserSettings } from '../services/settingsService' import { detect } from 'tinyld' interface Props { text: string defaultLang?: string className?: string settings?: UserSettings } const SPEED_OPTIONS = [0.8, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.1, 2.4, 2.8, 3] const TTSControls: React.FC = ({ text, defaultLang, className, settings }) => { const { supported, speaking, paused, speak, pause, resume, rate, setRate } = useTextToSpeech({ defaultLang, defaultRate: settings?.ttsDefaultSpeed }) const canPlay = supported && text?.trim().length > 0 const resolvedSystemLang = useMemo(() => { const mode = settings?.ttsLanguageMode if ((mode ? mode === 'system' : settings?.ttsUseSystemLanguage) === true) { return navigator?.language?.split('-')[0] } return undefined }, [settings?.ttsLanguageMode, settings?.ttsUseSystemLanguage]) const detectContentLang = useMemo(() => { const mode = settings?.ttsLanguageMode if (mode) return mode === 'content' return settings?.ttsDetectContentLanguage !== false }, [settings?.ttsLanguageMode, settings?.ttsDetectContentLanguage]) const specificLang = useMemo(() => { const mode = settings?.ttsLanguageMode // If mode is not 'system' or 'content', it's a specific language code if (mode && mode !== 'system' && mode !== 'content') { return mode } return undefined }, [settings?.ttsLanguageMode]) const handlePlayPause = () => { if (!canPlay) return if (!speaking) { let langOverride: string | undefined // Priority: specific language > content detection > system language if (specificLang) { langOverride = specificLang } else if (detectContentLang && text) { try { const lang = detect(text) if (typeof lang === 'string' && lang.length >= 2) langOverride = lang.slice(0, 2) } catch (err) { console.debug('[tts][detect] failed', err) } } if (!langOverride && resolvedSystemLang) { langOverride = resolvedSystemLang } speak(text, langOverride) } else if (paused) { resume() } else { pause() } } const handleCycleSpeed = () => { const currentIndex = SPEED_OPTIONS.indexOf(rate) const nextIndex = (currentIndex + 1) % SPEED_OPTIONS.length const next = SPEED_OPTIONS[nextIndex] console.debug('[tts][ui] cycle speed', { from: rate, to: next, speaking, paused }) setRate(next) } const playLabel = !speaking ? 'Listen' : (paused ? 'Resume' : 'Pause') if (!supported) return null return (
) } export default TTSControls