Fix TileStore's ability to swap spotlight speakers without a layout shift

This was regressed in 79c40f198c because of the overlooked renaming of the 'speaking' field to 'speaking$'.
This commit is contained in:
Robin
2025-10-17 11:23:34 -04:00
parent 1eec7314e8
commit 414322e5d9
2 changed files with 20 additions and 4 deletions

View File

@@ -675,6 +675,21 @@ test("spotlight speakers swap places", () => {
}, },
}, },
); );
// While we expect the media on tiles to change, layout$ itself should
// *never* meaningfully change. That is, we expect there to be no layout
// shifts as the spotlight speaker changes; instead, the same tiles
// should be reused for the whole duration of the test and simply have
// their media swapped out. This is meaningful for keeping the interface
// not too visually distracting during back-and-forth conversations,
// while still animating tiles to express people joining, leaving, etc.
expectObservable(
vm.layout$.pipe(
distinctUntilChanged(deepCompare),
debounceTime(0),
map(() => "x"),
),
).toBe("x"); // Expect just one emission
}, },
); );
}); });

View File

@@ -118,10 +118,11 @@ export class TileStore {
*/ */
export class TileStoreBuilder { export class TileStoreBuilder {
private spotlight: SpotlightTileData | null = null; private spotlight: SpotlightTileData | null = null;
private readonly prevSpotlightSpeaker = private readonly prevSpotlightSpeaker: UserMediaViewModel | null =
this.prevSpotlight?.media.length === 1 && this.prevSpotlight?.media.length === 1 &&
"speaking" in this.prevSpotlight.media[0] && "speaking$" in this.prevSpotlight.media[0]
this.prevSpotlight.media[0]; ? this.prevSpotlight.media[0]
: null;
private readonly prevGridByMedia: Map< private readonly prevGridByMedia: Map<
MediaViewModel, MediaViewModel,
@@ -201,7 +202,7 @@ export class TileStoreBuilder {
if ( if (
media === this.prevSpotlightSpeaker && media === this.prevSpotlightSpeaker &&
this.spotlight.media.length === 1 && this.spotlight.media.length === 1 &&
"speaking" in this.spotlight.media[0] && "speaking$" in this.spotlight.media[0] &&
this.prevSpotlightSpeaker !== this.spotlight.media[0] this.prevSpotlightSpeaker !== this.spotlight.media[0]
) { ) {
const prev = this.prevGridByMedia.get(this.spotlight.media[0]); const prev = this.prevGridByMedia.get(this.spotlight.media[0]);