fix(tts): pause button actually pauses queued audio

The onplay handler set the button text to 'Pause' mid-playback but the
button's onclick was still wired to speakText. Clicking Pause re-ran
speakText, which created a fresh Audio from the cached blob — the queued
audio paused while a new one started from the beginning, sounding like a
double-play.

Rebind the click handler to direct audio.pause()/play() while the queued
audio owns playback, restore the original (cache-replay) handler on end
or error.
This commit is contained in:
russell@unturf.com 2026-06-03 15:12:49 -04:00
parent 211dfa0eba
commit 264f0e7269
No known key found for this signature in database

View file

@ -1254,12 +1254,23 @@ async function speakTextQueued(text, playButton, messageId) {
function bindLifecycle(audio) {
currentQueuedAudio = audio;
// Save the message-level click handler so we can restore it
// once this queued audio ends — it's how replay-from-cache works.
const originalClick = playButton.onclick;
const toggleThisAudio = () => {
if (audio.paused) audio.play();
else audio.pause();
};
audio.onplay = () => {
playButton.classList.remove("tts-queued", "tts-loading");
playButton.disabled = false;
playButton.textContent = "Pause";
currentAudio = audio;
currentAudio.playButton = playButton;
// Click should pause/resume THIS audio while it owns playback.
// Without this, the original onclick re-runs speakText and
// restarts from the cached blob — sounds like a double-play.
playButton.onclick = toggleThisAudio;
};
audio.onpause = () => {
if (!audio.ended) playButton.textContent = "Play";
@ -1269,6 +1280,7 @@ async function speakTextQueued(text, playButton, messageId) {
playButton.classList.remove("tts-queued", "tts-loading");
playButton.disabled = false;
playButton.textContent = "Play";
playButton.onclick = originalClick;
currentQueuedAudio = null;
resolve();
};
@ -1277,6 +1289,7 @@ async function speakTextQueued(text, playButton, messageId) {
playButton.classList.remove("tts-queued", "tts-loading");
playButton.disabled = false;
playButton.textContent = "Play";
playButton.onclick = originalClick;
currentQueuedAudio = null;
reject(new Error("Audio playback failed"));
};