Promote speakers to the first page of the grid

This commit is contained in:
Robin Townsend 2023-06-18 11:32:21 -04:00
parent 4e5a75074a
commit ddeb36db47
5 changed files with 36 additions and 1 deletions

View file

@ -216,6 +216,7 @@ export function InCallView({
focused: screenshareFeeds.length === 0 && callFeed === activeSpeaker, focused: screenshareFeeds.length === 0 && callFeed === activeSpeaker,
isLocal: member.userId === localUserId && deviceId === localDeviceId, isLocal: member.userId === localUserId && deviceId === localDeviceId,
presenter, presenter,
isSpeaker: callFeed === activeSpeaker,
largeBaseSize: false, largeBaseSize: false,
connectionState, connectionState,
}); });
@ -244,6 +245,7 @@ export function InCallView({
focused: true, focused: true,
isLocal: screenshareFeed.isLocal(), isLocal: screenshareFeed.isLocal(),
presenter: false, presenter: false,
isSpeaker: screenshareFeed === activeSpeaker,
largeBaseSize: true, largeBaseSize: true,
placeNear: `${member.userId} ${deviceId}`, placeNear: `${member.userId} ${deviceId}`,
connectionState, connectionState,

View file

@ -46,6 +46,7 @@ import {
addItems, addItems,
tryMoveTile, tryMoveTile,
resize, resize,
promoteSpeakers,
} from "./model"; } from "./model";
import { TileWrapper } from "./TileWrapper"; import { TileWrapper } from "./TileWrapper";
@ -96,6 +97,9 @@ const useGridState = (
const newItems = items.filter((i) => !existingItemIds.has(i.id)); const newItems = items.filter((i) => !existingItemIds.has(i.id));
const grid3 = addItems(newItems, grid2); const grid3 = addItems(newItems, grid2);
// Step 4: Promote speakers to the top
promoteSpeakers(grid3);
return { ...grid3, generation: prevGrid.generation + 1 }; return { ...grid3, generation: prevGrid.generation + 1 };
}, },
[columns, items] [columns, items]

View file

@ -26,6 +26,7 @@ export interface TileDescriptor {
member: RoomMember; member: RoomMember;
focused: boolean; focused: boolean;
presenter: boolean; presenter: boolean;
isSpeaker: boolean;
callFeed?: CallFeed; callFeed?: CallFeed;
isLocal?: boolean; isLocal?: boolean;
largeBaseSize: boolean; largeBaseSize: boolean;

View file

@ -668,3 +668,31 @@ export function resize(g: Grid, columns: number): Grid {
return fillGaps(result); return fillGaps(result);
} }
/**
* Promotes speakers to the first page of the grid.
*/
export function promoteSpeakers(g: Grid) {
// This is all a bit of a hack right now, because we don't know if the designs
// will stick with this approach in the long run
// We assume that 4 rows are probably about 1 page
const firstPageEnd = g.columns * 4;
for (let from = firstPageEnd; from < g.cells.length; from++) {
const fromCell = g.cells[from];
// Don't bother trying to promote enlarged tiles
if (
fromCell?.item.isSpeaker &&
fromCell.columns === 1 &&
fromCell.rows === 1
) {
// Promote this tile by making 10 attempts to place it on the first page
for (let j = 0; j < 10; j++) {
const to = Math.floor(Math.random() * firstPageEnd);
const toCell = g.cells[to];
if (toCell === undefined || (toCell.columns === 1 && toCell.rows === 1))
moveTile(g, from, to);
}
}
}
}

View file

@ -33,7 +33,7 @@ import { TileDescriptor } from "../../src/video-grid/TileDescriptor";
function mkGrid(spec: string): Grid { function mkGrid(spec: string): Grid {
const secondNewline = spec.indexOf("\n", 1); const secondNewline = spec.indexOf("\n", 1);
const columns = secondNewline === -1 ? spec.length : secondNewline - 1; const columns = secondNewline === -1 ? spec.length : secondNewline - 1;
const cells = spec.match(/[a-z ]/g) ?? []; const cells = spec.match(/[a-z ]/g) ?? ([] as string[]);
const areas = new Set(cells); const areas = new Set(cells);
areas.delete(" "); // Space represents an empty cell, not an area areas.delete(" "); // Space represents an empty cell, not an area
const grid: Grid = { columns, cells: new Array(cells.length) }; const grid: Grid = { columns, cells: new Array(cells.length) };