mirror of
https://github.com/dergigi/boris.git
synced 2026-01-29 19:54:39 +01:00
refactor: use TTSControls component in TTS settings for consistent UI
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user