From fdc66a1d62bce8e38b0d89192eba0b70056e2f3c Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 3 Dec 2025 18:36:51 +0100 Subject: [PATCH] fix: existing screenshare switching twice --- src/state/CallViewModel/LayoutSwitch.test.ts | 25 ++++++++++++++++ src/state/CallViewModel/LayoutSwitch.ts | 30 ++++++++++++++------ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/state/CallViewModel/LayoutSwitch.test.ts b/src/state/CallViewModel/LayoutSwitch.test.ts index d0034743..c1941eb8 100644 --- a/src/state/CallViewModel/LayoutSwitch.test.ts +++ b/src/state/CallViewModel/LayoutSwitch.test.ts @@ -144,6 +144,31 @@ test("Should switch back to grid mode when the remote screen share ends", () => }); }); +test("can switch manually to grid after screen share while manually in spotlight", () => { + withTestScheduler(({ cold, behavior, schedule, expectObservable }): void => { + // Initially, no one is sharing. Then the user manually switches to + // spotlight. After a screen share starts, the user manually switches to + // grid. + const shareMarbles = " f-t-"; + const setModeMarbles = "-s-g"; + const expectation = " gs-g"; + const { gridMode$, setGridMode } = createLayoutModeSwitch( + scope, + behavior("n", { n: "normal" }), + cold(shareMarbles, { f: false, t: true }), + ); + schedule(setModeMarbles, { + g: () => setGridMode("grid"), + s: () => setGridMode("spotlight"), + }); + + expectObservable(gridMode$).toBe(expectation, { + g: "grid", + s: "spotlight", + }); + }); +}); + test("Should auto-switch to spotlight when in flat window mode", () => { withTestScheduler(({ cold, behavior, expectObservable }): void => { const { gridMode$ } = createLayoutModeSwitch( diff --git a/src/state/CallViewModel/LayoutSwitch.ts b/src/state/CallViewModel/LayoutSwitch.ts index cfb31d53..65c6bcb1 100644 --- a/src/state/CallViewModel/LayoutSwitch.ts +++ b/src/state/CallViewModel/LayoutSwitch.ts @@ -59,7 +59,13 @@ export function createLayoutModeSwitch( // To allow the user to override the auto-switch by selecting grid mode again. scan< [GridMode, boolean, WindowMode], - { mode: GridMode; hasAutoSwitched: boolean } + { + mode: GridMode; + /** Remember if the change was user driven or not */ + hasAutoSwitched: boolean; + /** To know if it is new screen share or an already handled */ + prevShare: boolean; + } >( (acc, [userSelection, hasScreenShares, windowMode]) => { const isFlatMode = windowMode === "flat"; @@ -73,6 +79,7 @@ export function createLayoutModeSwitch( return { mode: "spotlight", hasAutoSwitched: acc.hasAutoSwitched, + prevShare: hasScreenShares, }; } @@ -82,6 +89,7 @@ export function createLayoutModeSwitch( return { mode: "spotlight", hasAutoSwitched: acc.hasAutoSwitched, + prevShare: hasScreenShares, }; } @@ -89,20 +97,26 @@ export function createLayoutModeSwitch( // auto-switch to spotlight mode for better experience. // But we only do it once, if the user switches back to grid mode, // we respect that choice until they explicitly change it again. - if (hasScreenShares && !acc.hasAutoSwitched) { - logger.debug( - `Auto-switching to spotlight mode, hasScreenShares=${hasScreenShares}`, - ); - return { mode: "spotlight", hasAutoSwitched: true }; + const isNewShare = hasScreenShares && !acc.prevShare; + if (isNewShare && !acc.hasAutoSwitched) { + return { + mode: "spotlight", + hasAutoSwitched: true, + prevShare: true, + }; } // Respect user's grid choice // XXX If we want to forbid switching automatically again after we can // return hasAutoSwitched: acc.hasAutoSwitched here instead of setting to false. - return { mode: "grid", hasAutoSwitched: false }; + return { + mode: "grid", + hasAutoSwitched: false, + prevShare: hasScreenShares, + }; }, // initial value - { mode: "grid", hasAutoSwitched: false }, + { mode: "grid", hasAutoSwitched: false, prevShare: false }, ), map(({ mode }) => mode), ),