diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html index f057f04..7bf089e 100644 --- a/web/zebra-spaces.html +++ b/web/zebra-spaces.html @@ -5283,6 +5283,25 @@ $('btn-copy-share').addEventListener('click', async () => { return; } $('rdv-code').value = saved; + /* Auto-rejoin without a user gesture works on desktop (browsers + * grant audio engagement after first interaction with the origin) + * but breaks mobile listener audio: Firefox Android requires the + * silent-oscillator wake in primeAudioOnGesture to actually start + * the AudioContext render thread, and primeAudioOnGesture only + * runs inside the btn-enter click handler. Auto-rejoin that + * bypasses the click → audioCtx stays suspended → MediaStream- + * Source attaches silently → no audio. + * + * UA-gated: desktop preserves the zero-click rejoin convenience; + * mobile pre-fills the code + asks for one tap on enter so the + * gesture window opens and audio actually plays. Fox 2026-06-04 + * chose this trade after the AudioContext-suspended telemetry. */ + const isMobile = /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent); + if (isMobile){ + logLine('', 'last space: '+saved+' — click enter to resume (mobile needs gesture for audio)'); + setStatus('click enter to resume — '+saved, 'warn'); + return; + } logLine('', 'auto-rejoining last space …'); setTimeout(() => { joinSpace().catch(e => logLine('err', 'auto-rejoin failed: ' + e.message)); }, 100); })(); @@ -5356,8 +5375,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');