From 18651104922168bf381502f7e6228a00c1c6222a Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 20 May 2026 13:08:11 +0200 Subject: [PATCH 1/3] reproduce bug internal #578 Regression: Controls are shown in Mobile PIP --- src/state/CallViewModel/CallViewModel.test.ts | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/state/CallViewModel/CallViewModel.test.ts b/src/state/CallViewModel/CallViewModel.test.ts index 02a0a351..fc25df48 100644 --- a/src/state/CallViewModel/CallViewModel.test.ts +++ b/src/state/CallViewModel/CallViewModel.test.ts @@ -85,6 +85,14 @@ vi.mock("../e2ee/matrixKeyProvider"); const getUrlParams = vi.hoisted(() => vi.fn(() => ({}))); vi.mock("../UrlParams", () => ({ getUrlParams })); +const getPlatform = vi.hoisted(() => vi.fn(() => "desktop")); +vi.mock("../../Platform", () => ({ + get platform(): string { + return getPlatform(); + }, + isFirefox: (): boolean => false, +})); + vi.mock( "../state/CallViewModel/localMember/localTransport", async (importOriginal) => ({ @@ -838,6 +846,59 @@ describe.each([ }); }); + // Test cases for footer visibility in PIP mode across different platforms + const PIP_FOOTER_VISIBILITY_TEST_CASES: Array<{ + platform: "ios" | "android" | "desktop"; + expectedMarbles: string; + description: string; + }> = [ + { + platform: "ios", + expectedMarbles: "tf", + description: "hidden on iOS", + }, + { + platform: "android", + expectedMarbles: "tf", + description: "hidden on Android", + }, + { + platform: "desktop", + expectedMarbles: "t", + description: "visible on desktop", + }, + ]; + + it.each(PIP_FOOTER_VISIBILITY_TEST_CASES)( + "footer is $description in PIP mode", + ({ platform: testPlatform, expectedMarbles }) => { + withTestScheduler(({ schedule, expectObservable }) => { + // Set platform for this test case + getPlatform.mockReturnValue(testPlatform); + + // Enable PIP mode after initial render + const pipControlInputMarbles = "-e"; + + withCallViewModel( + { + remoteParticipants$: constant([aliceParticipant]), + rtcMembers$: constant([localRtcMember, aliceRtcMember]), + }, + (vm) => { + schedule(pipControlInputMarbles, { + e: () => window.controls.enablePip(), + }); + + expectObservable(vm.showFooter$).toBe(expectedMarbles, { + t: true, + f: false, + }); + }, + ); + }); + }, + ); + test("PiP tile in expanded spotlight layout switches speakers without layout shifts", () => { withTestScheduler(({ behavior, schedule, expectObservable }) => { // Switch to spotlight immediately From 265781ea5e25190479484eff252748af91f44bb6 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 20 May 2026 13:08:51 +0200 Subject: [PATCH 2/3] fix(regression): control buttons should be hidden on mobile PIP --- src/state/CallViewModel/CallViewModel.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/state/CallViewModel/CallViewModel.ts b/src/state/CallViewModel/CallViewModel.ts index 504875d2..63214a4a 100644 --- a/src/state/CallViewModel/CallViewModel.ts +++ b/src/state/CallViewModel/CallViewModel.ts @@ -1341,6 +1341,10 @@ export function createCallViewModel$( // Layout is edge-to-edge; show/hide the footer in response to interactions return windowMode$.pipe( switchMap((mode) => { + if (mode == "pip" && platform != "desktop") { + // No controls are shown in mobile pip as interactions are disabled + return of(false); + } const showInitially = mode !== "flat"; const timeout$ = mode === "flat" ? timer(showFooterMs) : NEVER; From 2fb5de3ba28d0936f25ea99feb16afe66aa53597 Mon Sep 17 00:00:00 2001 From: Valere Fedronic Date: Wed, 20 May 2026 14:50:56 +0200 Subject: [PATCH 3/3] review: eqeqe Co-authored-by: Robin --- src/state/CallViewModel/CallViewModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state/CallViewModel/CallViewModel.ts b/src/state/CallViewModel/CallViewModel.ts index 63214a4a..3a3e57d7 100644 --- a/src/state/CallViewModel/CallViewModel.ts +++ b/src/state/CallViewModel/CallViewModel.ts @@ -1341,7 +1341,7 @@ export function createCallViewModel$( // Layout is edge-to-edge; show/hide the footer in response to interactions return windowMode$.pipe( switchMap((mode) => { - if (mode == "pip" && platform != "desktop") { + if (mode === "pip" && platform !== "desktop") { // No controls are shown in mobile pip as interactions are disabled return of(false); }