From 75a93987fecc8e9f22e1a9ce9da146d85f5bf320 Mon Sep 17 00:00:00 2001 From: Eddy Date: Mon, 27 Apr 2026 18:36:00 +0200 Subject: [PATCH] fix: Voice-Stop greift hart durch + Schriftgroesse wirkt jetzt im Chat [appimage] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/lib/components/Message.svelte | 9 +++---- src/lib/voice/conversationEngine.ts | 38 ++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/lib/components/Message.svelte b/src/lib/components/Message.svelte index 79cbcfc..26d5f35 100644 --- a/src/lib/components/Message.svelte +++ b/src/lib/components/Message.svelte @@ -294,8 +294,7 @@ } .content { - font-size: 13.5px; - line-height: 1.55; + /* Schrift wird von .msg geerbt (User-konfigurierbar) */ word-wrap: break-word; } .content.faint { color: var(--vscode-descriptionForeground); } @@ -308,9 +307,9 @@ margin: 10px 0 4px 0; font-weight: 600; } - .content :global(h1) { font-size: 16px; } - .content :global(h2) { font-size: 14.5px; } - .content :global(h3) { font-size: 13.5px; } + .content :global(h1) { font-size: 1.25em; } + .content :global(h2) { font-size: 1.13em; } + .content :global(h3) { font-size: 1.05em; } .content :global(.code-block-wrapper) { background: var(--vscode-terminal-background); border: 1px solid var(--vscode-input-border); diff --git a/src/lib/voice/conversationEngine.ts b/src/lib/voice/conversationEngine.ts index 12b88d3..93aec54 100644 --- a/src/lib/voice/conversationEngine.ts +++ b/src/lib/voice/conversationEngine.ts @@ -43,6 +43,7 @@ let audioChunks: Blob[] = []; let analyser: AnalyserNode | null = null; let animationFrame: number | null = null; let ttsAudio: HTMLAudioElement | null = null; +let ttsResolve: (() => void) | null = null; // VAD const SILENCE_THRESHOLD = 0.03; @@ -299,13 +300,28 @@ async function speakAndWait(text: string): Promise { try { const voice = get(chatAppearance).ttsVoice || null; 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) => { + 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; } ttsAudio = new Audio(`data:audio/wav;base64,${audioBase64}`); - ttsAudio.onended = () => { ttsAudio = null; resolve(); }; - ttsAudio.onerror = () => { ttsAudio = null; resolve(); }; - ttsAudio.play().catch(() => resolve()); - monitorInterrupt(resolve); + ttsAudio.onended = finish; + ttsAudio.onerror = finish; + ttsAudio.play().catch(finish); + monitorInterrupt(finish); }); } catch (err) { console.error('TTS fehlgeschlagen:', err); @@ -337,10 +353,20 @@ function monitorInterrupt(onInterrupt: () => void) { function stopSpeaking() { if (ttsAudio) { - ttsAudio.pause(); - ttsAudio.currentTime = 0; + try { + ttsAudio.pause(); + ttsAudio.currentTime = 0; + ttsAudio.src = ''; + ttsAudio.load(); + } catch { /* ignore */ } ttsAudio = null; } + // Wartendes speakAndWait()-Promise sofort aufloesen + if (ttsResolve) { + const r = ttsResolve; + ttsResolve = null; + try { r(); } catch { /* ignore */ } + } } // Helpers -------------------------------------------------------------------