From 82c6c9ce0e1467b1e65098c61567e9e64e6c8671 Mon Sep 17 00:00:00 2001 From: sravan Date: Thu, 30 Jul 2026 17:51:46 +0530 Subject: [PATCH] fix(calls): no duplicate native tile; drop Ringing placeholder; name+DP from roster MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caller saw the native callee TWICE — the outgoing 'Ringing…' placeholder (never cleared, since a native callee doesn't send the mesh 'answered') plus a separate id-labelled tile. Now when a native LiveKit participant joins: remove the __waiting placeholder, stop ringback, and label the tile from CONTACTS (name + DP) instead of the raw user id. Also (plugin, needs build): connectRoom disconnects any previous LiveKit connection before joining, so repeated calls never leave duplicate/stale participants in the room. WebView fix deploys now (no rebuild); the connectRoom fix rides the next build. Co-Authored-By: Claude Opus 4.8 --- .../Sources/NativeCallPlugin/NativeCallPlugin.swift | 2 ++ server/public/home.html | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift b/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift index f0e9687..18b4933 100644 --- a/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift +++ b/mobile/plugins/native-call/ios/Sources/NativeCallPlugin/NativeCallPlugin.swift @@ -59,9 +59,11 @@ public class NativeCallPlugin: CAPPlugin, CAPBridgedPlugin, PKPushRegistryDelega private func connectRoom(url: String, token: String) { guard !url.isEmpty, !token.isEmpty else { return } + let old = room let r = Room() room = r Task { [weak self] in + await old?.disconnect() // drop any previous/stale connection so we never leave DUPLICATE participants do { try await r.connect(url: url, token: token) try await r.localParticipant.setMicrophone(enabled: true) diff --git a/server/public/home.html b/server/public/home.html index 03fa9fb..aab4f8c 100644 --- a/server/public/home.html +++ b/server/public/home.html @@ -4411,10 +4411,16 @@ function sfuAttach(pub, track, participant, _try){ 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. + // no mesh peer id. Key its tile + audio by the LiveKit identity so it still shows and is heard. The + // outgoing "Ringing…" placeholder is cleared here (its mesh 'answered' signal never fires for native), + // and we label the tile from the contact roster so it shows a NAME + DP, not a raw user id. pid='lk:'+participant.identity; - if(!meetNames.get(pid)) meetNames.set(pid, participant.name||'Caller'); - stopRingback(); + removeWaitingTile(); stopRingback(); + if(!meetNames.get(pid)){ + const c=(typeof CONTACTS!=='undefined'?CONTACTS:[]).find(x=>x&&x.id===participant.identity); + meetNames.set(pid, (c&&c.name) || (_dmCallWaiting&&_dmCallWaiting.name) || participant.name || 'Caller'); + if(c&&c.avatar) meetAvatars.set(pid, c.avatar); + } } const p=SFU.peers.get(pid)||{}; SFU.peers.set(pid,p); const mt=track.mediaStreamTrack; if(track.kind==='audio') p.audio=mt;