feat(tts): add TTS buttons to PlanView and FilesView markdown preview with configurable input mode (#1443)
Add TTS controls to markdown preview surfaces so users can listen to plans and markdown files directly from the preview toolbar. Changes: - Add read-aloud / stop buttons to PlanView markdown preview. - Add read-aloud / stop buttons to FilesView markdown preview for markdown files. - Respect the existing showMessageTTSButtons preference in both preview views. - Add a persisted ttsInputMode setting with sanitized/raw modes. - Keep sanitized mode as the default for backward compatibility. - Allow raw markdown only for server TTS providers that can handle markdown. - Always use sanitized text for browser and macOS say fallback paths. - Add Voice Settings controls for TTS input mode. - Add i18n keys for the new preview buttons and setting labels. - Merge latest main and preserve newer FilesView toolbar/editor changes. Validation: - bun test packages/ui/src/stores/useConfigStore.test.ts packages/ui/src/components/chat/message/parts/ToolPart.test.ts packages/web/server/lib/tts/routes.test.js - bun run type-check - bun run lint - git diff --check --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Bohdan Triapitsyn
parent
a6bf73b245
commit
ba95e13b36
@@ -683,6 +683,7 @@ interface ConfigStore {
|
||||
sttSilenceHoldMs: number;
|
||||
sttTranscribeOnStop: boolean;
|
||||
showMessageTTSButtons: boolean;
|
||||
ttsInputMode: 'sanitized' | 'raw';
|
||||
voiceModeEnabled: boolean;
|
||||
// Summarization settings
|
||||
summarizeMessageTTS: boolean;
|
||||
@@ -710,6 +711,7 @@ interface ConfigStore {
|
||||
setSttSilenceHoldMs: (ms: number) => void;
|
||||
setSttTranscribeOnStop: (enabled: boolean) => void;
|
||||
setShowMessageTTSButtons: (show: boolean) => void;
|
||||
setTtsInputMode: (mode: 'sanitized' | 'raw') => void;
|
||||
setVoiceModeEnabled: (enabled: boolean) => void;
|
||||
setSummarizeMessageTTS: (enabled: boolean) => void;
|
||||
setSummarizeVoiceConversation: (enabled: boolean) => void;
|
||||
@@ -978,6 +980,13 @@ export const useConfigStore = create<ConfigStore>()(
|
||||
}
|
||||
return false;
|
||||
})(),
|
||||
ttsInputMode: (() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const saved = localStorage.getItem('ttsInputMode');
|
||||
if (saved === 'raw') return 'raw' as const;
|
||||
}
|
||||
return 'sanitized' as const;
|
||||
})(),
|
||||
// Voice mode enabled - load from localStorage or default to false
|
||||
voiceModeEnabled: (() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
@@ -2286,6 +2295,13 @@ export const useConfigStore = create<ConfigStore>()(
|
||||
}
|
||||
},
|
||||
|
||||
setTtsInputMode: (mode: 'sanitized' | 'raw') => {
|
||||
set({ ttsInputMode: mode });
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('ttsInputMode', mode);
|
||||
}
|
||||
},
|
||||
|
||||
setVoiceModeEnabled: (enabled: boolean) => {
|
||||
set({ voiceModeEnabled: enabled });
|
||||
if (typeof window !== 'undefined') {
|
||||
|
||||
Reference in New Issue
Block a user