diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html index 83bd378..4da0f36 100644 --- a/web/zebra-spaces.html +++ b/web/zebra-spaces.html @@ -3191,6 +3191,21 @@ async function handleSignal(raw){ if (canSpeak(myRole) && canSpeak(m.role) && !peers.has(m.uuid)){ connectToPeer(m.uuid, myUUID < m.uuid); } + /* If the role transition stripped them of the ability to + * publish (anything -> listener), their camera/screen/game + * tiles can't get fresh RTP anymore. The demoted page calls + * sfuUnpublish* on its own side which should propagate via + * SFU 'ended', but that path is unreliable (Pion may not + * fire OnConnectionStateChange immediately and SSE renego + * can race). Authoritative removal: drop tiles by pubkey + * here, the moment the role change broadcast lands. */ + if (canSpeak(prev) && !canSpeak(m.role) && subjPub){ + try { + removeScreenTile(subjPub); + removeCameraTile(subjPub); + removeVideoTile('gameshare', subjPub); + } catch(_){} + } } renderRoom(); reorderTiles(); @@ -3974,8 +3989,8 @@ logLine('', 'ready โ€” pick a handle, type a rendezvous code, enter the space');