feat(tts): add TTSControls component with play/pause/stop and rate

This commit is contained in:
Gigi
2025-10-20 21:41:19 +02:00
parent a51fbd25d7
commit 34f44c59b5

View File

@@ -0,0 +1,77 @@
import React from 'react'
import { useTextToSpeech } from '../hooks/useTextToSpeech'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlay, faPause, faStop } from '@fortawesome/free-solid-svg-icons'
interface Props {
text: string
defaultLang?: string
className?: string
}
const TTSControls: React.FC<Props> = ({ text, defaultLang, className }) => {
const {
supported, speaking, paused,
speak, pause, resume, stop,
rate, setRate
} = useTextToSpeech({ defaultLang })
const canPlay = supported && text?.trim().length > 0
const handlePlayPause = () => {
if (!canPlay) return
if (!speaking) {
speak(text, defaultLang)
} else if (paused) {
resume()
} else {
pause()
}
}
const playLabel = !speaking ? 'Listen' : (paused ? 'Resume' : 'Pause')
if (!supported) return null
return (
<div className={className || 'tts-controls'} style={{ display: 'flex', gap: '0.5rem', alignItems: 'center', flexWrap: 'wrap' }}>
<button
type="button"
className="article-menu-btn"
onClick={handlePlayPause}
title={playLabel}
disabled={!canPlay}
>
<FontAwesomeIcon icon={!speaking ? faPlay : (paused ? faPlay : faPause)} />
<span style={{ marginLeft: 6 }}>{playLabel}</span>
</button>
<button
type="button"
className="article-menu-btn"
onClick={stop}
title="Stop"
disabled={!speaking && !paused}
>
<FontAwesomeIcon icon={faStop} />
<span style={{ marginLeft: 6 }}>Stop</span>
</button>
<label style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: '#aaa', fontSize: 12 }}>
Speed
<select
value={rate}
onChange={e => setRate(Number(e.target.value))}
style={{ background: 'transparent', color: 'inherit', border: '1px solid #444', borderRadius: 4, padding: '2px 6px' }}
>
<option value={0.8}>0.8x</option>
<option value={1}>1x</option>
<option value={1.2}>1.2x</option>
<option value={1.4}>1.4x</option>
<option value={1.6}>1.6x</option>
</select>
</label>
</div>
)
}
export default TTSControls