From 53b29a97e8d266944061380c3e8281ff5ad8adec Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Mon, 1 Jun 2026 21:59:56 -0400 Subject: [PATCH] =?UTF-8?q?zebra-report:=20hoist=20musicMode=20+=20device?= =?UTF-8?q?=20prefs=20to=20fix=20TDZ=20blocking=20init=20=E2=80=94=20mirro?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zebra-report/zebra-spaces.html | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/zebra-report/zebra-spaces.html b/zebra-report/zebra-spaces.html index 401c837..9e317ce 100644 --- a/zebra-report/zebra-spaces.html +++ b/zebra-report/zebra-spaces.html @@ -683,9 +683,10 @@ await loadOrCreateIdentity(); myHandle = localStorage.getItem(HANDLE_KEY) || ''; $('handle').value = myHandle; /* preferences that should outlive a reload — music-mode toggle and the - * last-picked mic + camera deviceIds. They're applied here before any - * device enumeration / mic acquisition so the very first getUserMedia - * call uses the right device + constraints. */ + * last-picked mic + camera deviceIds. Declared up here so the restore + * runs before their downstream `let` would put them in the temporal + * dead zone; downstream code now reads from these existing bindings. */ +let musicMode = false, micDeviceId = '', cameraDeviceId = ''; try { musicMode = localStorage.getItem(MUSIC_MODE_KEY) === '1'; } catch(_){} try { micDeviceId = localStorage.getItem(MIC_DEV_KEY) || ''; } catch(_){} try { cameraDeviceId = localStorage.getItem(CAM_DEV_KEY) || ''; } catch(_){} @@ -730,7 +731,9 @@ const SFU_BASE = (new URLSearchParams(location.search).get('sfu') let sfuPubPC = null, sfuPubPeerID = null; let sfuSubPC = null, sfuSubPeerID = null, sfuSubEvents = null; let sfuScreenPC = null, sfuScreenPeerID = null, sfuScreenStream = null; -let sfuCameraPC = null, sfuCameraPeerID = null, sfuCameraStream = null, cameraDeviceId = ''; +let sfuCameraPC = null, sfuCameraPeerID = null, sfuCameraStream = null; +/* cameraDeviceId is declared earlier so localStorage restore can write to it + * before the device-list refresh runs */ /* incoming screen/camera streams keyed by publisher pubkey hex (== streamID). * Cleared when the corresponding publisher leaves (peer-left or boot). */ const screenStreams = new Map(); // pubHex -> MediaStream @@ -1171,7 +1174,9 @@ async function refreshTurnCred(){ * zebra-audio carries over directly: re-acquire + replaceTrack on every * live sender (now multiple senders, one per peer). * ================================================================== */ -let micStream = null, audioCtx = null, musicMode = false, micDeviceId = ''; +let micStream = null, audioCtx = null; +/* musicMode + micDeviceId declared earlier so localStorage restore can + * populate them before getMic() reads micConstraints() */ function micConstraints(){ /* music mode = high-fidelity broadcast: stereo, raw, 48kHz so we can * push 256kbps Opus and let Opus's stereo modes carry music properly. @@ -2174,8 +2179,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');