diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html index 88fc1f1..3f21c53 100644 --- a/web/zebra-spaces.html +++ b/web/zebra-spaces.html @@ -3813,7 +3813,16 @@ $('btn-leave').addEventListener('click', async () => { try { sessionStorage.removeItem(ACTIVE_CAM_KEY); } catch(_){} if (sigReconnect){ clearTimeout(sigReconnect); sigReconnect = null; } for (const u of [...peers.keys()]) tearPeer(u); - if (ws){ try { ws.close(); } catch(_){} ws = null; } + /* send 'bye' BEFORE closing the WS — server distinguishes a strong + * leave (user clicked leave / closed tab) from a hiccup disconnect + * (refresh, network blip). On bye, the server broadcasts peer-left + * immediately; without it, the server defers the broadcast behind an + * 8s grace so a refresh can rejoin invisibly. */ + if (ws){ + try { ws.send(JSON.stringify({ type: 'bye' })); } catch(_){} + try { ws.close(); } catch(_){} + ws = null; + } await sfuUnpublish(); await sfuUnpublishScreen(); await sfuUnpublishCamera(); await sfuUnsubscribe(); dropMic(); members.clear(); handraise.clear(); myUUID=''; myRole=''; hostUUID=''; outstandingInvite=null; @@ -3845,8 +3854,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');