diff --git a/src/state/CallViewModel/CallViewModel.test.ts b/src/state/CallViewModel/CallViewModel.test.ts index 76be5f65..ef59270f 100644 --- a/src/state/CallViewModel/CallViewModel.test.ts +++ b/src/state/CallViewModel/CallViewModel.test.ts @@ -267,7 +267,7 @@ describe("CallViewModel", () => { }); }); - it.skip("screen sharing activates spotlight layout", () => { + test("screen sharing activates spotlight layout", () => { withTestScheduler(({ behavior, schedule, expectObservable }) => { // Start with no screen shares, then have Alice and Bob share their screens, // then return to no screen shares, then have just Alice share for a bit diff --git a/src/state/CallViewModel/CallViewModel.ts b/src/state/CallViewModel/CallViewModel.ts index 506eca1b..55e004df 100644 --- a/src/state/CallViewModel/CallViewModel.ts +++ b/src/state/CallViewModel/CallViewModel.ts @@ -15,9 +15,9 @@ import { } from "livekit-client"; import { type Room as MatrixRoom } from "matrix-js-sdk"; import { + BehaviorSubject, combineLatest, distinctUntilChanged, - EMPTY, filter, fromEvent, map, @@ -28,7 +28,6 @@ import { pairwise, race, scan, - skip, skipWhile, startWith, Subject, @@ -992,7 +991,7 @@ export function createCallViewModel$( spotlightExpandedToggle$.pipe(accumulate(false, (expanded) => !expanded)), ); - const gridModeUserSelection$ = new Subject(); + const gridModeUserSelection$ = new BehaviorSubject("grid"); /** * The layout mode of the media tile grid. */ @@ -1001,20 +1000,30 @@ export function createCallViewModel$( // automatically switch to spotlight mode and reset when screen sharing ends scope.behavior( gridModeUserSelection$.pipe( - switchMap((userSelection) => - (userSelection === "spotlight" - ? EMPTY - : combineLatest([hasRemoteScreenShares$, windowMode$]).pipe( - skip(userSelection === null ? 0 : 1), - map( - ([hasScreenShares, windowMode]): GridMode => - hasScreenShares || windowMode === "flat" - ? "spotlight" - : "grid", - ), - ) - ).pipe(startWith(userSelection ?? "grid")), - ), + switchMap((userSelection): Observable => { + if (userSelection === "spotlight") { + // If already in spotlight mode, stay there + return of("spotlight"); + } else { + // Otherwise, check if there is a remote screen share active + // as this could force us into spotlight mode. + return combineLatest([hasRemoteScreenShares$, windowMode$]).pipe( + map(([hasScreenShares, windowMode]): GridMode => { + const isFlatMode = windowMode === "flat"; + if (hasScreenShares || isFlatMode) { + logger.debug( + `Forcing spotlight mode, hasScreenShares=${hasScreenShares} windowMode=${windowMode}`, + ); + // override to spotlight mode + return "spotlight"; + } else { + // respect user choice + return "grid"; + } + }), + ); + } + }), ), "grid", );