Skip to content

Commit

Permalink
Always deal with MediaItem at the LayoutMedia layer
Browse files Browse the repository at this point in the history
That way we only convert to the view model when we do LayoutMedia => Layout
  • Loading branch information
hughns committed Nov 14, 2024
1 parent 84e172a commit cfea4bd
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 44 deletions.
71 changes: 36 additions & 35 deletions src/state/CallViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,37 +91,37 @@ const showFooterMs = 4000;

export interface GridLayoutMedia {
type: "grid";
spotlight?: MediaViewModel[];
grid: UserMediaViewModel[];
spotlight?: MediaItem[];
grid: UserMedia[];
}

export interface SpotlightLandscapeLayoutMedia {
type: "spotlight-landscape";
spotlight: MediaViewModel[];
grid: UserMediaViewModel[];
spotlight: MediaItem[];
grid: UserMedia[];
}

export interface SpotlightPortraitLayoutMedia {
type: "spotlight-portrait";
spotlight: MediaViewModel[];
grid: UserMediaViewModel[];
spotlight: MediaItem[];
grid: UserMedia[];
}

export interface SpotlightExpandedLayoutMedia {
type: "spotlight-expanded";
spotlight: MediaViewModel[];
pip?: UserMediaViewModel;
spotlight: MediaItem[];
pip?: UserMedia;
}

export interface OneOnOneLayoutMedia {
type: "one-on-one";
local: UserMediaViewModel;
remote: UserMediaViewModel;
local: UserMedia;
remote: UserMedia;
}

export interface PipLayoutMedia {
type: "pip";
spotlight: MediaViewModel[];
spotlight: MediaItem[];
}

export type LayoutMedia =
Expand Down Expand Up @@ -478,10 +478,9 @@ export class CallViewModel extends ViewModel {
),
);

private readonly localUserMedia: Observable<LocalUserMediaViewModel> =
this.mediaItems.pipe(
map((ms) => ms.find((m) => m.vm.local)!.vm as LocalUserMediaViewModel),
);
private readonly localUserMedia: Observable<UserMedia> = this.userMedia.pipe(
map((ms) => ms.find((m) => m.vm.local) as UserMedia),
);

private readonly screenShares: Observable<ScreenShare[]> =
this.mediaItems.pipe(
Expand All @@ -491,7 +490,7 @@ export class CallViewModel extends ViewModel {
this.scope.state(),
);

private readonly spotlightSpeaker: Observable<UserMediaViewModel> =
private readonly spotlightSpeaker: Observable<UserMedia> =
this.userMedia.pipe(
switchMap((mediaItems) =>
mediaItems.length === 0
Expand Down Expand Up @@ -523,11 +522,10 @@ export class CallViewModel extends ViewModel {
},
null,
),
map((speaker) => speaker.vm),
this.scope.state(),
);

private readonly grid: Observable<UserMediaViewModel[]> = this.userMedia.pipe(
private readonly grid: Observable<UserMedia[]> = this.userMedia.pipe(
switchMap((mediaItems) => {
const bins = mediaItems.map((m) =>
combineLatest(
Expand Down Expand Up @@ -558,27 +556,27 @@ export class CallViewModel extends ViewModel {
return bins.length === 0
? of([])
: combineLatest(bins, (...bins) =>
bins.sort(([, bin1], [, bin2]) => bin1 - bin2).map(([m]) => m.vm),
bins.sort(([, bin1], [, bin2]) => bin1 - bin2).map(([m]) => m),
);
}),
);

private readonly spotlightAndPip: Observable<
[Observable<MediaViewModel[]>, Observable<UserMediaViewModel | null>]
[Observable<MediaItem[]>, Observable<UserMedia | null>]
> = this.screenShares.pipe(
map((screenShares) =>
screenShares.length > 0
? ([of(screenShares.map((m) => m.vm)), this.spotlightSpeaker] as const)
? ([of(screenShares.map((m) => m)), this.spotlightSpeaker] as const)
: ([
this.spotlightSpeaker.pipe(map((speaker) => [speaker!])),
this.spotlightSpeaker.pipe(
switchMap((speaker) =>
speaker.local
speaker.vm.local
? of(null)
: this.localUserMedia.pipe(
switchMap((vm) =>
vm.alwaysShow.pipe(
map((alwaysShow) => (alwaysShow ? vm : null)),
switchMap((lm) =>
(lm.vm as LocalUserMediaViewModel).alwaysShow.pipe(
map((alwaysShow) => (alwaysShow ? lm : null)),
),
),
),
Expand All @@ -588,7 +586,7 @@ export class CallViewModel extends ViewModel {
),
);

private readonly spotlight: Observable<MediaViewModel[]> =
private readonly spotlight: Observable<MediaItem[]> =
this.spotlightAndPip.pipe(
switchMap(([spotlight]) => spotlight),
this.scope.state(),
Expand All @@ -597,12 +595,14 @@ export class CallViewModel extends ViewModel {
private readonly hasRemoteScreenShares: Observable<boolean> =
this.spotlight.pipe(
map((spotlight) =>
spotlight.some((vm) => !vm.local && vm instanceof ScreenShareViewModel),
spotlight.some(
(m) => !m.vm.local && m.vm instanceof ScreenShareViewModel,
),
),
distinctUntilChanged(),
);

private readonly pip: Observable<UserMediaViewModel | null> =
private readonly pip: Observable<UserMedia | null> =
this.spotlightAndPip.pipe(switchMap(([, pip]) => pip));

private readonly pipEnabled: Observable<boolean> = setPipEnabled.pipe(
Expand Down Expand Up @@ -676,7 +676,7 @@ export class CallViewModel extends ViewModel {
[this.grid, this.spotlight],
(grid, spotlight) => ({
type: "grid",
spotlight: spotlight.some((vm) => vm instanceof ScreenShareViewModel)
spotlight: spotlight.some((m) => m.vm instanceof ScreenShareViewModel)
? spotlight
: undefined,
grid,
Expand Down Expand Up @@ -708,15 +708,16 @@ export class CallViewModel extends ViewModel {
this.mediaItems.pipe(
map((mediaItems) => {
if (mediaItems.length !== 2) return null;
const local = mediaItems.find((vm) => vm.vm.local)!
.vm as LocalUserMediaViewModel;
const remote = mediaItems.find((vm) => !vm.vm.local)?.vm as
| RemoteUserMediaViewModel
| undefined;
const local = mediaItems.find(
(m) => m instanceof UserMedia && m.vm.local,
) as UserMedia | undefined;
const remote = mediaItems.find(
(m) => m instanceof UserMedia && !m.vm.local,
) as UserMedia | undefined;
// There might not be a remote tile if there are screen shares, or if
// only the local user is in the call and they're using the duplicate
// tiles option
if (remote === undefined) return null;
if (!local || !remote) return null;

return { type: "one-on-one", local, remote };
}),
Expand Down
4 changes: 2 additions & 2 deletions src/state/GridLikeLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ export function gridLikeLayout(
const update = prevTiles.from(visibleTiles);
if (media.spotlight !== undefined)
update.registerSpotlight(
media.spotlight,
media.spotlight.map((m) => m.vm),
media.type === "spotlight-portrait",
);
for (const mediaVm of media.grid) update.registerGridTile(mediaVm);
for (const mediaVm of media.grid) update.registerGridTile(mediaVm.vm);
const tiles = update.build();

return [
Expand Down
8 changes: 4 additions & 4 deletions src/state/OneOnOneLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ export function oneOnOneLayout(
prevTiles: TileStore,
): [OneOnOneLayout, TileStore] {
const update = prevTiles.from(visibleTiles);
update.registerGridTile(media.local);
update.registerGridTile(media.remote);
update.registerGridTile(media.local.vm);
update.registerGridTile(media.remote.vm);
const tiles = update.build();
return [
{
type: media.type,
local: tiles.gridTilesByMedia.get(media.local)!,
remote: tiles.gridTilesByMedia.get(media.remote)!,
local: tiles.gridTilesByMedia.get(media.local.vm)!,
remote: tiles.gridTilesByMedia.get(media.remote.vm)!,
},
tiles,
];
Expand Down
5 changes: 4 additions & 1 deletion src/state/PipLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export function pipLayout(
prevTiles: TileStore,
): [PipLayout, TileStore] {
const update = prevTiles.from(visibleTiles);
update.registerSpotlight(media.spotlight, true);
update.registerSpotlight(
media.spotlight.map((m) => m.vm),
true,
);
const tiles = update.build();
return [
{
Expand Down
7 changes: 5 additions & 2 deletions src/state/SpotlightExpandedLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ export function spotlightExpandedLayout(
prevTiles: TileStore,
): [SpotlightExpandedLayout, TileStore] {
const update = prevTiles.from(visibleTiles);
update.registerSpotlight(media.spotlight, true);
if (media.pip !== undefined) update.registerGridTile(media.pip);
update.registerSpotlight(
media.spotlight.map((m) => m.vm),
true,
);
if (media.pip !== undefined) update.registerGridTile(media.pip.vm);
const tiles = update.build();

return [
Expand Down

0 comments on commit cfea4bd

Please sign in to comment.