window.BackOneAddons = window.BackOneAddons || {}; window.BackOneAddons.voice = function voiceAddon() { let pc = null; let picker = null; let selectedPeer = null; let inCall = false; let localStream = null; let micEnabled = true; let root = null; function updateConnectionBar() { const bar = root?.querySelector('#voice-conn-bar'); if (!bar || !window.BackOneCommLayout) return; bar.innerHTML = BackOneCommLayout.connectionBarHtml( selectedPeer, BackOneNetworkSession.getActiveNetwork() ); } function updateHeadStatus() { const statusEl = root?.querySelector('#voice-head-status'); const breadcrumb = root?.querySelector('#voice-breadcrumb-peer'); if (!statusEl) return; if (inCall && selectedPeer) { statusEl.innerHTML = `Connected · ${selectedPeer.latency != null ? selectedPeer.latency + 'ms' : '—'}`; if (breadcrumb) breadcrumb.textContent = selectedPeer.peerId; } else if (selectedPeer) { statusEl.textContent = 'Ready'; if (breadcrumb) breadcrumb.textContent = selectedPeer.peerId; } else { statusEl.textContent = ''; if (breadcrumb) breadcrumb.textContent = '—'; } } function updateCallButtons() { const callBtn = root?.querySelector('#voice-call'); if (callBtn) callBtn.disabled = !selectedPeer || !BackOneNetworkSession.getNetworkId() || inCall; const selectedLabel = root?.querySelector('#voice-selected-label'); if (selectedLabel) { selectedLabel.innerHTML = selectedPeer ? `Selected: ${selectedPeer.peerId.slice(0, 10)}…` : 'Selected: —'; } updateHeadStatus(); updateConnectionBar(); } function hangUp() { if (pc) { pc.close(); pc = null; } if (localStream) { localStream.getTracks().forEach(t => t.stop()); localStream = null; } inCall = false; micEnabled = true; updateCallButtons(); window.BackOneRingingPopup?.dismiss(); } return { mount(container) { root = container; container.innerHTML = `