refactor: use TTSControls component in TTS settings for consistent UI

This commit is contained in:
Gigi
2025-10-20 23:09:36 +02:00
parent ea5c173745
commit d82e22ce1c

View File

@@ -1,9 +1,8 @@
import React, { useState } from 'react'
import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faGauge, faPlay, faPause } from '@fortawesome/free-solid-svg-icons'
import { faGauge } from '@fortawesome/free-solid-svg-icons'
import { UserSettings } from '../../services/settingsService'
import { useTextToSpeech } from '../../hooks/useTextToSpeech'
import { detect } from 'tinyld'
import TTSControls from '../TTSControls'
interface TTSSettingsProps {
settings: UserSettings
@@ -15,11 +14,6 @@ const EXAMPLE_TEXT = "Welcome to Boris. Text-to-speech brings your highlights an
const TTSSettings: React.FC<TTSSettingsProps> = ({ settings, onUpdate }) => {
const currentSpeed = settings.ttsDefaultSpeed || 2.1
const [isTestSpeaking, setIsTestSpeaking] = useState(false)
const { supported, speaking, paused, speak, pause, resume, stop } = useTextToSpeech({
defaultRate: currentSpeed
})
const handleCycleSpeed = () => {
const currentIndex = SPEED_OPTIONS.indexOf(currentSpeed)
@@ -27,46 +21,6 @@ const TTSSettings: React.FC<TTSSettingsProps> = ({ settings, onUpdate }) => {
onUpdate({ ttsDefaultSpeed: SPEED_OPTIONS[nextIndex] })
}
const handleTestPlayPause = () => {
if (!isTestSpeaking && !speaking) {
let langOverride: string | undefined
// Determine language based on settings
const mode = settings?.ttsLanguageMode
if (mode === 'system' || settings?.ttsUseSystemLanguage) {
langOverride = navigator?.language?.split('-')[0]
} else {
try {
const detected = detect(EXAMPLE_TEXT)
if (typeof detected === 'string' && detected.length >= 2) {
langOverride = detected.slice(0, 2)
}
} catch (err) {
console.debug('[tts][detect] failed', err)
}
}
setIsTestSpeaking(true)
speak(EXAMPLE_TEXT, langOverride)
} else if (paused) {
resume()
} else {
pause()
}
}
const handleStopTest = () => {
stop()
setIsTestSpeaking(false)
}
// Stop test speaking when settings change
React.useEffect(() => {
if (isTestSpeaking && !speaking) {
setIsTestSpeaking(false)
}
}, [speaking, isTestSpeaking])
return (
<div className="settings-section">
<h3 className="section-title">Text-to-Speech</h3>
@@ -100,36 +54,13 @@ const TTSSettings: React.FC<TTSSettingsProps> = ({ settings, onUpdate }) => {
</div>
</div>
{supported && (
<div className="setting-group">
<label>Test Example</label>
<div style={{ padding: '0.75rem', backgroundColor: 'var(--color-bg)', borderRadius: '4px', marginBottom: '0.75rem', fontSize: '0.95rem', lineHeight: '1.5' }}>
{EXAMPLE_TEXT}
</div>
<div className="setting-buttons">
<button
type="button"
className="article-menu-btn"
onClick={handleTestPlayPause}
title={isTestSpeaking ? (paused ? 'Resume' : 'Pause') : 'Play'}
>
<FontAwesomeIcon icon={isTestSpeaking && !paused ? faPause : faPlay} />
<span>{isTestSpeaking ? (paused ? 'Resume' : 'Pause') : 'Play'}</span>
</button>
{isTestSpeaking && (
<button
type="button"
className="article-menu-btn"
onClick={handleStopTest}
title="Stop"
style={{ color: 'var(--color-text)' }}
>
</button>
)}
</div>
<div className="setting-group">
<label>Test Example</label>
<div style={{ padding: '0.75rem', backgroundColor: 'var(--color-bg)', borderRadius: '4px', marginBottom: '0.75rem', fontSize: '0.95rem', lineHeight: '1.5' }}>
{EXAMPLE_TEXT}
</div>
)}
<TTSControls text={EXAMPLE_TEXT} settings={settings} />
</div>
</div>
)
}