fix: Voice-Stop greift hart durch + Schriftgroesse wirkt jetzt im Chat [appimage]
All checks were successful
Build AppImage / build (push) Successful in 7m11s

Voice-Stop:
- TTS-Audio jetzt vollstaendig zerstoert (pause + src='' + load) statt nur pause
- Wartende speakAndWait()-Promise wird beim Stop aufgeloest (vorher Hang)
- isActive()-Check direkt nach text_to_speech Result, kein Audio-Start mehr nach Stop

Schriftgroesse:
- .content hatte feste 13.5px → ueberschrieb --chat-font-size
- Headings (h1-h3) hatten feste px-Werte → jetzt em (relativ zu User-Schrift)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Eddy 2026-04-27 18:36:00 +02:00
parent f821e321aa
commit 75a93987fe
2 changed files with 36 additions and 11 deletions

View file

@ -294,8 +294,7 @@
} }
.content { .content {
font-size: 13.5px; /* Schrift wird von .msg geerbt (User-konfigurierbar) */
line-height: 1.55;
word-wrap: break-word; word-wrap: break-word;
} }
.content.faint { color: var(--vscode-descriptionForeground); } .content.faint { color: var(--vscode-descriptionForeground); }
@ -308,9 +307,9 @@
margin: 10px 0 4px 0; margin: 10px 0 4px 0;
font-weight: 600; font-weight: 600;
} }
.content :global(h1) { font-size: 16px; } .content :global(h1) { font-size: 1.25em; }
.content :global(h2) { font-size: 14.5px; } .content :global(h2) { font-size: 1.13em; }
.content :global(h3) { font-size: 13.5px; } .content :global(h3) { font-size: 1.05em; }
.content :global(.code-block-wrapper) { .content :global(.code-block-wrapper) {
background: var(--vscode-terminal-background); background: var(--vscode-terminal-background);
border: 1px solid var(--vscode-input-border); border: 1px solid var(--vscode-input-border);

View file

@ -43,6 +43,7 @@ let audioChunks: Blob[] = [];
let analyser: AnalyserNode | null = null; let analyser: AnalyserNode | null = null;
let animationFrame: number | null = null; let animationFrame: number | null = null;
let ttsAudio: HTMLAudioElement | null = null; let ttsAudio: HTMLAudioElement | null = null;
let ttsResolve: (() => void) | null = null;
// VAD // VAD
const SILENCE_THRESHOLD = 0.03; const SILENCE_THRESHOLD = 0.03;
@ -299,13 +300,28 @@ async function speakAndWait(text: string): Promise<void> {
try { try {
const voice = get(chatAppearance).ttsVoice || null; const voice = get(chatAppearance).ttsVoice || null;
const audioBase64: string = await invoke('text_to_speech', { text, voice }); const audioBase64: string = await invoke('text_to_speech', { text, voice });
// Falls in der Zwischenzeit gestoppt wurde — kein Audio mehr starten
if (!isActive()) return;
return new Promise((resolve) => { return new Promise((resolve) => {
let resolved = false;
const finish = () => {
if (resolved) return;
resolved = true;
if (ttsAudio) {
ttsAudio.pause();
ttsAudio.src = '';
try { ttsAudio.load(); } catch { /* ignore */ }
ttsAudio = null;
}
resolve();
};
ttsResolve = finish;
if (ttsAudio) { ttsAudio.pause(); ttsAudio = null; } if (ttsAudio) { ttsAudio.pause(); ttsAudio = null; }
ttsAudio = new Audio(`data:audio/wav;base64,${audioBase64}`); ttsAudio = new Audio(`data:audio/wav;base64,${audioBase64}`);
ttsAudio.onended = () => { ttsAudio = null; resolve(); }; ttsAudio.onended = finish;
ttsAudio.onerror = () => { ttsAudio = null; resolve(); }; ttsAudio.onerror = finish;
ttsAudio.play().catch(() => resolve()); ttsAudio.play().catch(finish);
monitorInterrupt(resolve); monitorInterrupt(finish);
}); });
} catch (err) { } catch (err) {
console.error('TTS fehlgeschlagen:', err); console.error('TTS fehlgeschlagen:', err);
@ -337,10 +353,20 @@ function monitorInterrupt(onInterrupt: () => void) {
function stopSpeaking() { function stopSpeaking() {
if (ttsAudio) { if (ttsAudio) {
try {
ttsAudio.pause(); ttsAudio.pause();
ttsAudio.currentTime = 0; ttsAudio.currentTime = 0;
ttsAudio.src = '';
ttsAudio.load();
} catch { /* ignore */ }
ttsAudio = null; ttsAudio = null;
} }
// Wartendes speakAndWait()-Promise sofort aufloesen
if (ttsResolve) {
const r = ttsResolve;
ttsResolve = null;
try { r(); } catch { /* ignore */ }
}
} }
// Helpers ------------------------------------------------------------------- // Helpers -------------------------------------------------------------------