fix: Voice-Stop greift hart durch + Schriftgroesse wirkt jetzt im Chat [appimage]
All checks were successful
Build AppImage / build (push) Successful in 7m11s
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:
parent
f821e321aa
commit
75a93987fe
2 changed files with 36 additions and 11 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
ttsAudio.pause();
|
try {
|
||||||
ttsAudio.currentTime = 0;
|
ttsAudio.pause();
|
||||||
|
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 -------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue