fix: recover voice UI after text tasks
Rebuild & Deploy / rebuild (push) Successful in 47s

This commit is contained in:
snowspeeder committed 2026-08-29 08:03:59 -04:00
1 parent b1643b635d
commit 1fffed8ab3
1 file changed
+36 -12
+36 -12
View File
@@ -162,6 +162,9 @@ function updateModeUI() {
if (isText) {
setState(room ? "listening" : "idle");
window.setTimeout(() => chatInput.focus(), 0);
} else {
// Refresh mode-specific copy even when the underlying state is unchanged.
setState(uiState);
}
}
@@ -188,19 +191,28 @@ async function setConversationMode(mode) {
stopVisualLoop();
statusEl.textContent = "Secure room · Text mode";
} else {
await room.startAudio();
await room.localParticipant.setMicrophoneEnabled(true);
micMuted = false;
muteBtn.disabled = false;
updateMuteIcon();
setupMicAnalyser();
startVisualLoop();
statusEl.textContent = "Secure room · Microphone on";
try {
await room.startAudio();
await room.localParticipant.setMicrophoneEnabled(true);
setupMicAnalyser();
statusEl.textContent = "Secure room · Microphone on";
} catch (err) {
// Keep the conversation usable even if this browser denies or does
// not implement microphone capture. The mute control can retry.
console.warn("Microphone could not be enabled:", err);
micMuted = true;
updateMuteIcon();
statusEl.textContent = "Voice mode · Microphone unavailable";
}
}
}
voiceModeBtn.addEventListener("click", () => setConversationMode("voice"));
textModeBtn.addEventListener("click", () => setConversationMode("text"));
voiceModeBtn.addEventListener("click", () => setConversationMode("voice").catch(console.error));
textModeBtn.addEventListener("click", () => setConversationMode("text").catch(console.error));
// ── Audio analysers (mic + remote agent audio) ─────────────────────────────
let micCtx = null;
@@ -523,9 +535,15 @@ function handleDataPacket(payload, participant, topic) {
agentReady = true;
} else if (msg.type === "transcript") {
addMessage(msg.role || "agent", msg.text);
if (conversationMode === "text" && (msg.role || "agent") === "agent") {
setState("listening");
chatInput.focus();
if ((msg.role || "agent") === "agent") {
if (conversationMode === "text") {
setState("listening");
chatInput.focus();
} else if (uiState === "thinking") {
// Text arrives even when headless playback or an analyser is
// unavailable; use it to release the thinking state.
setState("speaking");
}
}
} else if (msg.type === "task_event") {
handleTaskEvent(msg);
@@ -913,9 +931,15 @@ stopBtn.addEventListener("click", () => {
// ── Mic mute toggle ─────────────────────────────────────────────────────────
muteBtn.addEventListener("click", async () => {
if (!room || !room.localParticipant) return;
micMuted = !micMuted;
await room.localParticipant.setMicrophoneEnabled(!micMuted);
updateMuteIcon();
const nextMuted = !micMuted;
try {
await room.localParticipant.setMicrophoneEnabled(!nextMuted);
micMuted = nextMuted;
updateMuteIcon();
} catch (err) {
console.warn("Microphone toggle failed:", err);
statusEl.textContent = "Microphone unavailable in this browser";
}
});
function updateMuteIcon() {