diff --git a/web/app.js b/web/app.js index 80bfa2f..8c06794 100644 --- a/web/app.js +++ b/web/app.js @@ -39,6 +39,8 @@ let wakeLock = null; // ── DOM ───────────────────────────────────────────────────────────────────── const startBtn = document.getElementById("startBtn"); const stopBtn = document.getElementById("stopBtn"); +const muteBtn = document.getElementById("muteBtn"); +let micMuted = false; const statusEl = document.getElementById("status"); const messagesEl = document.getElementById("messages"); const orbEl = document.getElementById("orb"); @@ -600,6 +602,8 @@ startBtn.addEventListener("click", async () => { statusEl.textContent = "Connected — speak now"; startBtn.disabled = true; stopBtn.disabled = false; + muteBtn.disabled = false; + micMuted = false; setupMicAnalyser(); startVisualLoop(); @@ -627,8 +631,25 @@ stopBtn.addEventListener("click", () => { setState("idle"); startBtn.disabled = false; stopBtn.disabled = true; + muteBtn.disabled = true; + micMuted = false; + updateMuteIcon(); }); +// ── Mic mute toggle ───────────────────────────────────────────────────────── +muteBtn.addEventListener("click", async () => { + if (!room || !room.localParticipant) return; + micMuted = !micMuted; + await room.localParticipant.setMicrophoneEnabled(!micMuted); + updateMuteIcon(); +}); + +function updateMuteIcon() { + const muted = muteBtn.classList.toggle("muted", micMuted); + muteBtn.setAttribute("aria-label", muted ? "Unmute microphone" : "Mute microphone"); + muteBtn.title = muted ? "Unmute microphone" : "Mute microphone"; +} + // ── Helper: fetch a signed access token from the token endpoint ──────────── async function fetchToken(roomName) { const resp = await fetch("/token", { diff --git a/web/index.html b/web/index.html index c6cd350..3036dc9 100644 --- a/web/index.html +++ b/web/index.html @@ -31,6 +31,9 @@