Refactor layout selection into smaller chunks

This commit is contained in:
Robin
2024-07-25 17:51:00 -04:00
parent f89342713a
commit 0bfec65405

View File

@@ -561,76 +561,84 @@ export class CallViewModel extends ViewModel {
this.gridModeUserSelection.next(value); this.gridModeUserSelection.next(value);
} }
private readonly oneOnOne: Observable<boolean> = combineLatest(
[this.grid, this.screenShares],
(grid, screenShares) =>
grid.length == 2 &&
// There might not be a remote tile if only the local user is in the call
// and they're using the duplicate tiles option
grid.some((vm) => !vm.local) &&
screenShares.length === 0,
);
private readonly gridLayout: Observable<Layout> = combineLatest(
[this.grid, this.spotlight],
(grid, spotlight) => ({
type: "grid",
spotlight: spotlight.some((vm) => vm instanceof ScreenShareViewModel)
? spotlight
: undefined,
grid,
}),
);
private readonly spotlightLandscapeLayout: Observable<Layout> = combineLatest(
[this.grid, this.spotlight],
(grid, spotlight) => ({ type: "spotlight-landscape", spotlight, grid }),
);
private readonly spotlightPortraitLayout: Observable<Layout> = combineLatest(
[this.grid, this.spotlight],
(grid, spotlight) => ({ type: "spotlight-portrait", spotlight, grid }),
);
private readonly spotlightExpandedLayout: Observable<Layout> = combineLatest(
[this.spotlight, this.pip],
(spotlight, pip) => ({
type: "spotlight-expanded",
spotlight,
pip: pip ?? undefined,
}),
);
private readonly oneOnOneLayout: Observable<Layout> = this.grid.pipe(
map((grid) => ({
type: "one-on-one",
local: grid.find((vm) => vm.local) as LocalUserMediaViewModel,
remote: grid.find((vm) => !vm.local) as RemoteUserMediaViewModel,
})),
);
private readonly pipLayout: Observable<Layout> = this.spotlight.pipe(
map((spotlight): Layout => ({ type: "pip", spotlight })),
);
public readonly layout: Observable<Layout> = this.windowMode.pipe( public readonly layout: Observable<Layout> = this.windowMode.pipe(
switchMap((windowMode) => { switchMap((windowMode) => {
const spotlightLandscapeLayout = combineLatest(
[this.grid, this.spotlight],
(grid, spotlight): Layout => ({
type: "spotlight-landscape",
spotlight,
grid,
}),
);
const spotlightExpandedLayout = combineLatest(
[this.spotlight, this.pip],
(spotlight, pip): Layout => ({
type: "spotlight-expanded",
spotlight,
pip: pip ?? undefined,
}),
);
switch (windowMode) { switch (windowMode) {
case "normal": case "normal":
return this.gridMode.pipe( return this.gridMode.pipe(
switchMap((gridMode) => { switchMap((gridMode) => {
switch (gridMode) { switch (gridMode) {
case "grid": case "grid":
return combineLatest( return this.oneOnOne.pipe(
[this.grid, this.spotlight, this.screenShares], switchMap((oneOnOne) =>
(grid, spotlight, screenShares): Layout => oneOnOne ? this.oneOnOneLayout : this.gridLayout,
grid.length == 2 && ),
// There might not be a remote tile if only the local user
// is in the call and they're using the duplicate tiles
// option
grid.some((vm) => !vm.local) &&
screenShares.length === 0
? {
type: "one-on-one",
local: grid.find(
(vm) => vm.local,
) as LocalUserMediaViewModel,
remote: grid.find(
(vm) => !vm.local,
) as RemoteUserMediaViewModel,
}
: {
type: "grid",
spotlight:
screenShares.length > 0 ? spotlight : undefined,
grid,
},
); );
case "spotlight": case "spotlight":
return this.spotlightExpanded.pipe( return this.spotlightExpanded.pipe(
switchMap((expanded) => switchMap((expanded) =>
expanded expanded
? spotlightExpandedLayout ? this.spotlightExpandedLayout
: spotlightLandscapeLayout, : this.spotlightLandscapeLayout,
), ),
); );
} }
}), }),
); );
case "narrow": case "narrow":
return combineLatest( return this.spotlightPortraitLayout;
[this.grid, this.spotlight],
(grid, spotlight): Layout => ({
type: "spotlight-portrait",
spotlight,
grid,
}),
);
case "flat": case "flat":
return this.gridMode.pipe( return this.gridMode.pipe(
switchMap((gridMode) => { switchMap((gridMode) => {
@@ -638,16 +646,14 @@ export class CallViewModel extends ViewModel {
case "grid": case "grid":
// Yes, grid mode actually gets you a "spotlight" layout in // Yes, grid mode actually gets you a "spotlight" layout in
// this window mode. // this window mode.
return spotlightLandscapeLayout; return this.spotlightLandscapeLayout;
case "spotlight": case "spotlight":
return spotlightExpandedLayout; return this.spotlightExpandedLayout;
} }
}), }),
); );
case "pip": case "pip":
return this.spotlight.pipe( return this.pipLayout;
map((spotlight): Layout => ({ type: "pip", spotlight })),
);
} }
}), }),
shareReplay(1), shareReplay(1),