diff --git a/zebra-report/zebra-spaces.html b/zebra-report/zebra-spaces.html index 124eeba..6540a61 100644 --- a/zebra-report/zebra-spaces.html +++ b/zebra-report/zebra-spaces.html @@ -4013,17 +4013,27 @@ function renderRoom(){ /* per-speaker "stream" toggle: anyone can flip another speaker's * audio from WebRTC subscribe → HTTP Ogg/Opus tap. Higher latency, * cleaner playback under loss. Not a mod action — every listener - * gets to pick their own path per speaker. */ - if (canSpeak(m.role) && m.uuid !== myUUID && m.pubkey){ + * gets to pick their own path per speaker. Also rendered on your + * own row as a DJ self-monitor: confirms what listeners are hearing + * (~2s delayed). Safe with closed headphones; loud feedback with + * open speakers + music-mode mic — title attr warns. */ + if (canSpeak(m.role) && m.pubkey){ let mPubHex = ''; try { mPubHex = hex(unb64(m.pubkey)); } catch(_){} if (mPubHex){ + const isSelf = (m.uuid === myUUID); const sb = document.createElement('button'); sb.className = 'small'; const on = streamMode.has(mPubHex); sb.textContent = on ? '◉ stream' : '○ stream'; - sb.title = on - ? 'streaming — click to switch back to live (low-latency WebRTC)' - : 'switch to HTTP Ogg/Opus stream (~2s delay, glitch-free for DJ sets)'; + if (isSelf){ + sb.title = on + ? 'monitoring your own DJ stream — click to stop (feedback risk on open speakers!)' + : 'preview what listeners hear of YOUR mic (~2s delay) — headphones recommended'; + } else { + sb.title = on + ? 'streaming — click to switch back to live (low-latency WebRTC)' + : 'switch to HTTP Ogg/Opus stream (~2s delay, glitch-free for DJ sets)'; + } if (on) sb.classList.add('invert'); sb.onclick = () => toggleStreamFor(m.uuid, mPubHex); acts.appendChild(sb); @@ -4539,8 +4549,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');