From 08e191008bae1dea880ef856d6b773ac4f815b6b Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Fri, 24 Jul 2026 19:54:29 -0400 Subject: [PATCH] fix(call): release auto-enabled pip spotlight when returning to the call room MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In picture-in-picture with an active screenshare, spotlight is auto-enabled so the share fills the pip window (tracked via pipAutoSpotlightRef). The release branch sat behind `if (!pipMode) return`, so navigating BACK to the call room (pipMode → false) early-returned and never released it — the spotlight stayed stuck on with the ref latched true. The effect now guards only on `!callEmbed`, computes wantSpotlight = pipMode && pipScreenshare, and releases whenever that's false (screenshare ends OR pip ends). The ref still gates release so we only ever undo a spotlight we enabled, never the user's. Two reviewer-prescribed hardenings folded in: reset the ref when callEmbed is torn down (kills a stale cross-call latch), and a comment that control.spotlight is deliberately not a dep (re-adding it would fight the user). Bug-hunt finding from LOTUS_TODO. Two review agents verified against CallControl.ts (ref-gating, deps, idempotency, cross-embed self-heal); [live] — the code fix is unambiguous but confirming screenshare→pip→back wants a real call. Gate-green (tsc, eslint, prettier, 925 tests, build). Co-Authored-By: Claude Opus 4.8 --- src/app/components/CallEmbedProvider.tsx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/app/components/CallEmbedProvider.tsx b/src/app/components/CallEmbedProvider.tsx index 8ee389ccb..c0621e123 100644 --- a/src/app/components/CallEmbedProvider.tsx +++ b/src/app/components/CallEmbedProvider.tsx @@ -731,8 +731,24 @@ export function CallEmbedProvider({ children }: CallEmbedProviderProps) { // When screenshare ends, release the spotlight we auto-enabled. const pipAutoSpotlightRef = React.useRef(false); useEffect(() => { - if (!pipMode || !callEmbed) return; - if (pipScreenshare) { + if (!callEmbed) { + // The embed (and its spotlight) is torn down with the call; drop the latch + // so a stale ref can't act on the next call's fresh embed. + pipAutoSpotlightRef.current = false; + return; + } + // Spotlight is wanted only while in pip with an active screenshare. Release + // it when EITHER ends — including leaving pip (returning to the call room). + // The release must not sit behind a `!pipMode` early-return, or a + // screenshare→pip→back sequence leaves the auto-enabled spotlight stuck on + // with pipAutoSpotlightRef latched true. The ref gates release so we only + // ever undo a spotlight we turned on (never one the user set). + // NB: `control.spotlight` is read below but deliberately NOT a dependency — + // this effect reacts to pip/screenshare *intent*, not to spotlight changes. + // Adding it as a dep would re-run on every manual spotlight toggle and fight + // the user. + const wantSpotlight = pipMode && pipScreenshare; + if (wantSpotlight) { if (!callEmbed.control.spotlight) { callEmbed.control.toggleSpotlight(); pipAutoSpotlightRef.current = true;