Only show layout switch when it has an effect on the layout

This commit is contained in:
Robin
2026-07-27 18:19:01 +02:00
parent a443a55bec
commit 5a96d1769e
2 changed files with 62 additions and 33 deletions

View File

@@ -541,6 +541,10 @@ describe.each([
// Starts in one-on-one mobile layout, then goes to spotlight layout for // Starts in one-on-one mobile layout, then goes to spotlight layout for
// the screen sharing and group call cases // the screen sharing and group call cases
const expectedLayoutMarbles = " ab-c"; const expectedLayoutMarbles = " ab-c";
// Whether the layout switch is visible. It should be hidden while in
// one-on-one layout.
const expectedLayoutSwitchMarbles = "ny--";
withCallViewModel( withCallViewModel(
{ {
remoteParticipants$: behavior(participantInputMarbles, { remoteParticipants$: behavior(participantInputMarbles, {
@@ -579,6 +583,9 @@ describe.each([
}, },
}, },
); );
expectObservable(
vm.layoutSwitchVm$.pipe(map((vm) => vm !== null)),
).toBe(expectedLayoutSwitchMarbles, yesNo);
}, },
); );
}); });

View File

@@ -1108,10 +1108,11 @@ export function createCallViewModel$(
), ),
); );
const oneOnOneLayoutMedia$: Observable<{ const oneOnOneLayoutMedia$: Behavior<{
local: LocalUserMediaViewModel; local: LocalUserMediaViewModel;
remote: UserMediaViewModel | RingingMediaViewModel; remote: UserMediaViewModel | RingingMediaViewModel;
} | null> = combineLatest([userMedia$, screenShares$]).pipe( } | null> = scope.behavior(
combineLatest([userMedia$, screenShares$]).pipe(
switchMap(([userMedia, screenShares]) => { switchMap(([userMedia, screenShares]) => {
// One-on-one layout only supports 2 user media, no screen shares // One-on-one layout only supports 2 user media, no screen shares
if (userMedia.length <= 2 && screenShares.length === 0) { if (userMedia.length <= 2 && screenShares.length === 0) {
@@ -1122,7 +1123,9 @@ export function createCallViewModel$(
if (local !== undefined) { if (local !== undefined) {
const remote = userMedia.find( const remote = userMedia.find(
(vm): vm is WrappedUserMediaViewModel & RemoteUserMediaViewModel => (
vm,
): vm is WrappedUserMediaViewModel & RemoteUserMediaViewModel =>
vm.type === "user" && !vm.local, vm.type === "user" && !vm.local,
); );
@@ -1143,6 +1146,7 @@ export function createCallViewModel$(
return of(null); return of(null);
}), }),
),
); );
const oneOnOneDesktopLayoutMedia$: Observable<OneOnOneDesktopLayoutMedia | null> = const oneOnOneDesktopLayoutMedia$: Observable<OneOnOneDesktopLayoutMedia | null> =
@@ -1358,6 +1362,22 @@ export function createCallViewModel$(
layoutMedia$.pipe(map(({ edgeToEdge }) => edgeToEdge)), layoutMedia$.pipe(map(({ edgeToEdge }) => edgeToEdge)),
); );
// Only show the layout switch in cases where it has an effect on the layout
const showLayoutSwitch$ = windowMode$.pipe(
switchMap((windowMode) => {
switch (windowMode) {
case "normal":
return of(true);
case "flat":
return oneOnOneLayoutMedia$.pipe(
map((oneOnOne) => oneOnOne === null),
);
default:
return of(false);
}
}),
);
const screenTap$ = new Subject<void>(); const screenTap$ = new Subject<void>();
const controlsTap$ = new Subject<void>(); const controlsTap$ = new Subject<void>();
const screenHover$ = new Subject<void>(); const screenHover$ = new Subject<void>();
@@ -1775,7 +1795,9 @@ export function createCallViewModel$(
spotlightExpanded$: spotlightExpanded$, spotlightExpanded$: spotlightExpanded$,
toggleSpotlightExpanded$: toggleSpotlightExpanded$, toggleSpotlightExpanded$: toggleSpotlightExpanded$,
layoutSwitchVm$: constant(layoutSwitchVm), layoutSwitchVm$: scope.behavior(
showLayoutSwitch$.pipe(map((show) => (show ? layoutSwitchVm : null))),
),
layout$: layout$, layout$: layout$,
localMatrixLivekitMember$, localMatrixLivekitMember$,
remoteMatrixLivekitMembers$: scope.behavior( remoteMatrixLivekitMembers$: scope.behavior(