From 3019fd0e1566d1dfa868f7b3cc2c74d8a14d67a1 Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Tue, 27 Jan 2026 08:12:47 -0500 Subject: [PATCH] Route all TTS through handleTTS for streaming support - speakChatText now uses handleTTS instead of speakTextDirect so embed modal TTS (intro, chat messages) respects streaming mode - Streaming result updates blobUrl on completion so existing download click handlers work without changes --- public/src/tts.js | 12 +++++++++++- public/src/uncloseai-embed-modal.js | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/public/src/tts.js b/public/src/tts.js index ab68d5a..2145e28 100644 --- a/public/src/tts.js +++ b/public/src/tts.js @@ -260,7 +260,17 @@ export async function speakTextStreaming(text, voice = "alloy", rate = 0.9, mode audio.play().catch(e => console.warn("Initial play blocked:", e.message)); // Return immediately with audio element - caller uses done promise to know when stream finishes - return { audio, blob: null, blobUrl: audioUrl, streamed: true, done }; + // The result object is mutable: blob/blobUrl get updated when done resolves, + // so click handlers that read result.blobUrl later will get the downloadable URL + const result = { audio, blob: null, blobUrl: audioUrl, streamed: true, done }; + + done.then(({ blob, blobUrl }) => { + result.blob = blob; + // Create a downloadable blob URL (MediaSource URL can't be downloaded) + result.blobUrl = URL.createObjectURL(blob); + }).catch(() => {}); + + return result; } // Process page content using Hermes (deprecated - use extractSpokenTokens instead) diff --git a/public/src/uncloseai-embed-modal.js b/public/src/uncloseai-embed-modal.js index c3a05f3..aef58f8 100644 --- a/public/src/uncloseai-embed-modal.js +++ b/public/src/uncloseai-embed-modal.js @@ -48,9 +48,9 @@ function parseVoiceSelection(selectedValue) { // Import required functions dynamically to avoid circular dependencies async function speakChatText(text, voiceSelection, speed) { - const { speakTextDirect } = await import("./tts.js"); + const { handleTTS } = await import("./tts.js"); const { model, voice } = parseVoiceSelection(voiceSelection); - return await speakTextDirect(text, voice, speed, model); + return await handleTTS(text, voice, speed, model); } async function* sendMessage(message) {