zebra-spaces: remove per-speaker stream toggle UI — adaptive worklet covers it

Fox 2026-06-05: "since we have this now there is no reason to have the
stream button anymore on the ux."

The ○/◉ button next to each row was the self-listener entry point
(speaker flips themselves onto the buffered HTTP Ogg/Opus path when
WebRTC was glitchy). With the adaptive worklet — predictive drain
detector, self-calibrating floor, ±6% time-stretching — the same
glitch-recovery happens automatically without user intervention.

Removed:
- 'strm' grid column from .member layout (back to 4 columns)
- .stream-toggle CSS rules (button styling, dark-mode variants)
- The button render block in renderRoom (per-uuid streamEl creation)
- row.appendChild(streamEl) and its preceding comment
- The unwired dead toggleStreamFor(uuid, pubHex) helper function

Kept (still useful):
- streamMode Set + startStream() + stopStream() — used by the global
  self-listener FSM
- selfListenerMode and its observer
- The HTTP /stream lip-sync override (httpLipSyncOverride)
- Double Dragon's manual-on/manual-off states + ddNoteManualToggle
  (no UI surface but the plumbing stays for future re-introduction
  if needed)

Layout is back to badge|handle/pub/acts|mic|meter — one fewer column,
slightly more breathing room per row.
This commit is contained in:
Russell Ballestrini 2026-06-05 09:38:32 -04:00
parent fa19f5df90
commit 54f69a3edb
No known key found for this signature in database

View file

@ -484,15 +484,15 @@
* the pubkey, never wrap a handle mid-word. */ * the pubkey, never wrap a handle mid-word. */
.member { .member {
display: grid; display: grid;
/* extra 1.4rem column for the per-speaker stream toggle — lives on the /* 4 columns: badge, handle/pub/acts, mic, meter. The per-speaker
* top row next to the mic icon so it never wraps + never adds row * stream toggle column ('strm') was removed 2026-06-05 — the
* height (the original 3-row layout is preserved). Single-char button * adaptive worklet handles wiggle absorption automatically, no
* (○ / ◉) keeps the column tight. */ * manual buffered-HTTP fallback button needed. */
grid-template-columns: 5.5rem minmax(0, 1fr) 1.4rem 1.4rem 5rem; grid-template-columns: 5.5rem minmax(0, 1fr) 1.4rem 5rem;
grid-template-areas: grid-template-areas:
"badge handle mic strm meter" "badge handle mic meter"
"badge pub pub pub pub" "badge pub pub pub"
"badge acts acts acts acts"; "badge acts acts acts";
align-items: center; gap: 0.35rem 0.55rem; padding: 0.35rem 0; align-items: center; gap: 0.35rem 0.55rem; padding: 0.35rem 0;
border-bottom: 1px dotted #ccc; font-size: 0.85rem; border-bottom: 1px dotted #ccc; font-size: 0.85rem;
} }
@ -500,19 +500,8 @@
.member > .handle { grid-area: handle; } .member > .handle { grid-area: handle; }
.member > .pub-short { grid-area: pub; } .member > .pub-short { grid-area: pub; }
.member > .mic { grid-area: mic; } .member > .mic { grid-area: mic; }
.member > .stream-toggle { grid-area: strm; justify-self: center; }
.member > .meter { grid-area: meter; } .member > .meter { grid-area: meter; }
.member > .mod-actions { grid-area: acts; } .member > .mod-actions { grid-area: acts; }
/* single-char stream toggle: ○ when off, ◉ when on. Keep the button
* compact so it fits the 1.4rem column without forcing the row taller. */
.stream-toggle {
font-size: 0.95rem; line-height: 1; padding: 0.1rem 0.3rem;
background: transparent; border: 1px solid #888; cursor: pointer;
color: inherit;
}
.stream-toggle.on { background: #000; color: #fff; border-color: #000; }
html.theme-dark .stream-toggle { border-color: #aaa; }
html.theme-dark .stream-toggle.on { background: #fff; color: #000; border-color: #fff; }
.member:last-child { border-bottom: none; } .member:last-child { border-bottom: none; }
.badge { .badge {
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
@ -5950,18 +5939,6 @@ function stopStream(uuid){
} }
} catch(_){} } catch(_){}
} }
function toggleStreamFor(uuid, pubHex){
if (streamMode.has(pubHex)){
streamMode.delete(pubHex);
stopStream(uuid);
ddNoteManualToggle(pubHex, false);
} else {
streamMode.add(pubHex);
startStream(uuid, pubHex);
ddNoteManualToggle(pubHex, true);
}
renderRoom();
}
/* selfListenerMode — a speaker/cohost/host who wants to consume the /* selfListenerMode — a speaker/cohost/host who wants to consume the
* room via the buffered HTTP Ogg/Opus path instead of the live WebRTC * room via the buffered HTTP Ogg/Opus path instead of the live WebRTC
@ -6147,22 +6124,11 @@ function renderRoom(){
* every speaker row grow a third sub-row of mod-actions even for * every speaker row grow a third sub-row of mod-actions even for
* non-mods (just-self-monitor self-rows), which fox flagged as * non-mods (just-self-monitor self-rows), which fox flagged as
* causing vertical scroll. Single-char glyph keeps the column 1.4rem. */ * causing vertical scroll. Single-char glyph keeps the column 1.4rem. */
let streamEl = null; /* The per-row stream toggle (○/◉ for self-listener mode) was
/* Per-row stream toggle. The ONLY row that gets one is SELF — and * removed 2026-06-05. The adaptive worklet with predictive
* only when we can speak (host/cohost/speaker). The button flips * grow + self-calibrating floor now absorbs wiggles
* THIS viewer's whole audio path from the live WebRTC mesh to the * automatically; there's no scenario where a user needs to
* buffered HTTP Ogg/Opus broadcast tap (the listener-quality * manually flip onto the buffered HTTP path. */
* stream). selfListenerMode is global, so the ◉/○ glyph reflects
* that flag rather than streamMode of any single pubHex. */
if (canSpeak(m.role) && m.uuid === myUUID && canSpeak(myRole)){
streamEl = document.createElement('button');
streamEl.className = 'stream-toggle' + (selfListenerMode ? ' on' : '');
streamEl.textContent = selfListenerMode ? '◉' : '○';
streamEl.title = selfListenerMode
? 'listening on the buffered HTTP stream — click to rejoin the live WebRTC mesh (also unmutes is via the mic button)'
: 'switch yourself to the listener stream (buffered, ~2s behind) — auto-mutes your mic';
streamEl.onclick = () => roomMachines.selfListener.send('TOGGLE');
}
if (isMod(myRole) && m.uuid !== myUUID){ if (isMod(myRole) && m.uuid !== myUUID){
if (m.role === 'listener'){ if (m.role === 'listener'){
const b = document.createElement('button'); b.className='small invert'; const b = document.createElement('button'); b.className='small invert';
@ -6215,11 +6181,6 @@ function renderRoom(){
acts.appendChild(actsRemoval); acts.appendChild(actsRemoval);
row.appendChild(badge); row.appendChild(handle); row.appendChild(pub); row.appendChild(badge); row.appendChild(handle); row.appendChild(pub);
row.appendChild(micEl); row.appendChild(micEl);
/* stream toggle (when rendered) goes between mic and meter so it
* lands in the `strm` grid column on the top row. If absent the
* column collapses to its 1.4rem track width (small whitespace
* gap, no row-height change). */
if (streamEl) row.appendChild(streamEl);
row.appendChild(meter); row.appendChild(acts); row.appendChild(meter); row.appendChild(acts);
wrap.appendChild(row); wrap.appendChild(row);
} }
@ -6887,8 +6848,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace"> <footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-05</span><br> <span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> &nbsp;·&nbsp; built <span class="stamp-date">2026-06-05</span><br>
md5 <span class="stamp-md5">dda84f98199acdcd1bb7102cd2878ec9</span><br> md5 <span class="stamp-md5">9728607e6d8187fed0bfa947f93cccaa</span><br>
sha256 <span class="stamp-sha">6a59cafee418659fbaeb94c6e0af9014a7359841a09c880a245901bb4657ac3c</span><br> sha256 <span class="stamp-sha">26680e413131920d5c0dc981b20460b1c087d08193f1f5d89925d22e3013ec11</span><br>
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br> <span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span> <span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
</footer> </footer>