Fix call-cluster bugs #11, #4a, #4b
#11: adding a 3rd person to a 1:1 call then having one participant close the app disconnected the call for everyone. leaveMeeting() ended a DM room for ALL peers on any leave; now it only tears down when <2 people remain, otherwise it falls through to the normal peer-left path (call continues). #4b: after someone left a call they never reappeared under "Add people". meeting-peer-left cleaned meetPeers/tiles but not meetPeerUids/meetNames, so the departed uid stayed in hereUids and was filtered out. Now deleted. #4a: a guest who enabled mic/cam on the pre-join screen had to re-tap after being admitted — the choices were applied on a blind 900ms timer that fired while still in the lobby. Now applied in the meeting-joined handler, after admission + media connect. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4469,6 +4469,7 @@ let meetReturn=null; // {kind:'dm'|'group', id} — chat to land on when
|
||||
const meetVU=new Map(); // peerId|'__local' -> {ctx,analyser,data,raf} active-speaker meters
|
||||
let MEET_ICE={ iceServers:[{ urls:'stun:stun.l.google.com:19302' }] };
|
||||
let meetMic=true, meetCam=true;
|
||||
let _pendingJoinMic=false, _pendingJoinCam=false; // #4a: pre-join (lobby) mic/cam choices, applied once actually admitted
|
||||
let meetIsHost=false, meetHostId=null; // host = the meeting creator (transferable by the host only)
|
||||
let meetScreen=false, meetScreenStream=null; // am I sharing my screen + the display stream
|
||||
const meetSharers=new Set(); // peerIds of OTHERS currently sharing their screen
|
||||
@@ -5541,6 +5542,10 @@ async function onMeetMsg(e){
|
||||
// for the UI only. Media is native; tell peers our mic is live.
|
||||
meetSend({type:'meeting-state', muted:!meetMic, camOff:!meetCam}); // tell existing peers my state
|
||||
if(meetIsHost) meetSend({type:'meeting-host', to:meetMyId}); // announce host so others know
|
||||
// #4a: now that we're actually in the call (post-admission, media connected), honor the mic/cam the
|
||||
// user turned on at the pre-join/lobby screen — so they don't have to re-tap after being admitted.
|
||||
if(_pendingJoinMic){ _pendingJoinMic=false; if(!meetMic){ try{ await toggleMic(); }catch(_){} } }
|
||||
if(_pendingJoinCam){ _pendingJoinCam=false; if(!meetCam){ try{ await toggleCam(); }catch(_){} } }
|
||||
refreshMeetPanel(); updateHostControls();
|
||||
return;
|
||||
}
|
||||
@@ -5570,7 +5575,7 @@ async function onMeetMsg(e){
|
||||
if(m.type==='meeting-peer-screen'){ if(m.on) meetSharers.add(m.from); else meetSharers.delete(m.from); setTileScreen(m.from, !!m.on); refreshMeetPanel(); return; }
|
||||
if(m.type==='meeting-sharemode'){ meetMultiShare=!!m.multi; refreshMeetPanel(); return; }
|
||||
if(m.type==='meeting-muteall'){ if(meetMic && meetLocalStream){ meetMic=false; meetLocalStream.getAudioTracks().forEach(t=>t.enabled=false); updateMicBtn(); setTileMute('__local', true); meetSend({type:'meeting-state', muted:true, camOff:!meetCam}); } toast('You were muted by the host'); return; }
|
||||
if(m.type==='meeting-peer-left'){ const p=meetPeers.get(m.peerId); if(p){ try{p.pc.close();}catch(_){} meetPeers.delete(m.peerId);} if(SFU.on) sfuDropPeer(m.peerId); meetSharers.delete(m.peerId); removeTile(m.peerId); refreshMeetPanel(); return; }
|
||||
if(m.type==='meeting-peer-left'){ const p=meetPeers.get(m.peerId); if(p){ try{p.pc.close();}catch(_){} meetPeers.delete(m.peerId);} if(SFU.on) sfuDropPeer(m.peerId); meetSharers.delete(m.peerId); meetPeerUids.delete(m.peerId); meetNames.delete(m.peerId); meetAvatars.delete(m.peerId); removeTile(m.peerId); refreshMeetPanel(); return; } // #4b: drop uid/name too, else they stay in hereUids and never reappear under "Add people"
|
||||
if(m.type==='meeting-signal'){
|
||||
const from=m.from, d=m.data||{};
|
||||
if(d.sdp){
|
||||
@@ -6071,9 +6076,10 @@ async function startGuestMeeting(code){
|
||||
ME={ id:'guest-'+Math.random().toString(36).slice(2,10), name:nm, email:'', guest:true, avatarUrl:null };
|
||||
_guestRoom=code; stopPrev(); ov.remove();
|
||||
try{ await sfuInit(); }catch(_){}
|
||||
// #4a: remember the pre-join choices; they're applied in the meeting-joined handler — i.e. AFTER the
|
||||
// host admits the guest and media is connected — not on a blind timer that fires while still in the lobby.
|
||||
_pendingJoinMic=joinMic; _pendingJoinCam=joinCam;
|
||||
switchTab('meeting'); await enterMeeting(code);
|
||||
// Apply their pre-join choices once the call is up.
|
||||
setTimeout(()=>{ try{ if(joinMic && !meetMic) toggleMic(); if(joinCam && !meetCam) toggleCam(); }catch(_){} }, 900);
|
||||
};
|
||||
go.onclick=join;
|
||||
inp.addEventListener('keydown',e=>{ if(e.key==='Enter'){ e.preventDefault(); join(); } });
|
||||
|
||||
Reference in New Issue
Block a user