Native video: render others' screen-share on native calls

Last native-video gap: on a native (iOS) call the WebView has no LiveKit
connection, so a screen shared by a web/desktop participant never rendered.
The mesh already flips the sharer's tile into the big "stage" (meeting-
peer-screen -> meetSharers -> sharing-mode), so extend the tile sync: each
tile now carries a `screen` flag (meetSharers.has(id)). The plugin renders
that participant's screen-share track (source .screenShareVideo) on the
tile with layoutMode .fit (contain, no crop) instead of the camera.

Outgoing screen-share from iOS is still unsupported (no getDisplayMedia /
ReplayKit broadcast extension) — toggleScreen now shows a clear toast on
native instead of silently failing.

Needs a Codemagic build (plugin change). Web deployed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 16:39:39 +05:30
parent a5e2ed8a9d
commit e6d3d2d66a
2 changed files with 18 additions and 4 deletions
+4 -3
View File
@@ -5221,6 +5221,7 @@ function meetMakePeer(peerId, name){
// (no extra tiles, the peer's video just shows the screen). Falls back to addTrack+renegotiate if
// no video sender exists yet (camera never turned on). Stopping restores the camera (or avatar).
async function toggleScreen(){
if(meetNative){ toast('Sharing your screen from iPhone isnt supported yet — but youll see others shared screens.'); return; } // iOS has no getDisplayMedia / ReplayKit ext wired
if(meetScreen){ stopScreen(); return; }
if(!meetMultiShare && meetSharers.size>0){ toast('Someone is already sharing their screen'); return; }
if(SFU.on){
@@ -5378,11 +5379,11 @@ function bzNativeSyncTiles(){
document.querySelectorAll('#meetGrid .meet-tile').forEach(el=>{
const id=el.id ? el.id.replace('meet-tile-','') : ''; if(!id || id==='__waiting') return;
const r=el.getBoundingClientRect(); if(r.width<2||r.height<2) return;
let uid, local=false, name='', muted=false;
let uid, local=false, name='', muted=false, screen=false;
if(id==='__local'){ uid=(ME&&ME.id)||''; local=true; name=(ME&&ME.name)||'You'; muted=!meetMic; }
else { uid=meetPeerUids.get(id)||''; name=meetNames.get(id)||'Guest'; muted=!!meetMuted.get(id); }
else { uid=meetPeerUids.get(id)||''; name=meetNames.get(id)||'Guest'; muted=!!meetMuted.get(id); screen=meetSharers.has(id); } // sharer's tile → render their screen, not camera
if(!uid) return;
tiles.push({ uid, local, name, muted, x:r.left, y:r.top, w:r.width, h:r.height });
tiles.push({ uid, local, name, muted, screen, x:r.left, y:r.top, w:r.width, h:r.height });
});
try{ NC.syncVideoTiles({ tiles }); }catch(_){}
}