const LIVEKIT_URL = "wss://voice.hobbs.farm"; let room = null; async function connect() { setStatus("connecting", "Connecting..."); try { // Request a token from the token service const response = await fetch("/api/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ identity: "jeremy-" + Date.now() }), }); if (!response.ok) throw new Error("Failed to get token"); const { token } = await response.json(); room = new LivekitClient.Room({ audioCaptureDefaults: { echoCancellation: true, noiseSuppression: true, autoGainControl: true, }, }); room.on(LivekitClient.RoomEvent.Connected, () => { setStatus("connected", "Connected"); document.getElementById("connectBtn").style.display = "none"; document.getElementById("disconnectBtn").style.display = "block"; }); room.on(LivekitClient.RoomEvent.Disconnected, () => { setStatus("disconnected", "Disconnected"); document.getElementById("connectBtn").style.display = "block"; document.getElementById("disconnectBtn").style.display = "none"; }); room.on(LivekitClient.RoomEvent.TrackSubscribed, (track) => { if (track.kind === LivekitClient.Track.Kind.Audio) { const element = track.attach(); document.body.appendChild(element); element.play(); } }); await room.connect(LIVEKIT_URL, token); await room.localParticipant.setMicrophoneEnabled(true); } catch (err) { setStatus("disconnected", "Error: " + err.message); console.error(err); } } async function disconnect() { if (room) { await room.disconnect(); room = null; } } function setMode(mode) { document.getElementById("modeDisplay").textContent = "Mode: " + mode; if (room && room.localParticipant) { const encoder = new TextEncoder(); room.localParticipant.publishData( encoder.encode(JSON.stringify({ type: "mode_change", mode })), { reliable: true } ); } } function setStatus(state, text) { const el = document.getElementById("status"); el.className = "status " + state; el.textContent = text; } document.getElementById("connectBtn").addEventListener("click", connect); document.getElementById("disconnectBtn").addEventListener("click", disconnect);