diff --git a/server/public/home.html b/server/public/home.html index 7bbfe93..03fa9fb 100644 --- a/server/public/home.html +++ b/server/public/home.html @@ -4407,10 +4407,14 @@ function sfuRebuild(pid){ addTile(pid, st, meetNames.get(pid)||'Guest', false); setTileScreen(pid, !!p.screen); meetWatchStream(pid, st); } function sfuAttach(pub, track, participant, _try){ - const pid=peerIdForUid(participant.identity); - if(!pid){ // #9: uid→peerId map (from the mesh join) may lag the LiveKit track — retry a few times - if((_try||0)<10){ setTimeout(()=>sfuAttach(pub,track,participant,(_try||0)+1), 400); } - return; + let pid=peerIdForUid(participant.identity); + if(!pid){ // uid→peerId map (from the mesh join) may lag the LiveKit track — retry a few times… + if((_try||0)<6){ setTimeout(()=>sfuAttach(pub,track,participant,(_try||0)+1), 400); return; } + // …then fall back: a NATIVE (CallKit + LiveKit) participant joins LiveKit but NOT our WS mesh, so it has + // no mesh peer id. Key its tile + audio by the LiveKit identity so it still shows and is heard. + pid='lk:'+participant.identity; + if(!meetNames.get(pid)) meetNames.set(pid, participant.name||'Caller'); + stopRingback(); } const p=SFU.peers.get(pid)||{}; SFU.peers.set(pid,p); const mt=track.mediaStreamTrack; if(track.kind==='audio') p.audio=mt; @@ -4419,7 +4423,7 @@ function sfuAttach(pub, track, participant, _try){ sfuRebuild(pid); updateShareMode(); } function sfuDetach(pub, track, participant){ - const pid=peerIdForUid(participant.identity); if(!pid) return; const p=SFU.peers.get(pid); if(!p) return; const mt=track.mediaStreamTrack; + let pid=peerIdForUid(participant.identity); if(!pid) pid='lk:'+participant.identity; const p=SFU.peers.get(pid); if(!p) return; const mt=track.mediaStreamTrack; if(p.audio===mt) p.audio=null; else if(p.screen===mt){ p.screen=null; meetSharers.delete(pid); setTileScreen(pid,false); } else if(p.cam===mt) p.cam=null; sfuRebuild(pid); updateShareMode(); }