Format code

This commit is contained in:
Robin
2023-10-11 10:42:04 -04:00
parent b28e465122
commit 614bc82402
112 changed files with 628 additions and 602 deletions

View File

@@ -78,7 +78,7 @@ export interface SparseGrid {
export function getPaths(
g: SparseGrid,
dest: number,
avoid: (cell: number) => boolean = (): boolean => false
avoid: (cell: number) => boolean = (): boolean => false,
): (number | null)[] {
const destRow = row(dest, g);
const destColumn = column(dest, g);
@@ -145,7 +145,7 @@ function inArea(
index: number,
start: number,
end: number,
g: SparseGrid
g: SparseGrid,
): boolean {
const indexColumn = column(index, g);
const indexRow = row(index, g);
@@ -160,7 +160,7 @@ function inArea(
function* cellsInArea(
start: number,
end: number,
g: SparseGrid
g: SparseGrid,
): Generator<number, void, unknown> {
const startColumn = column(start, g);
const endColumn = column(end, g);
@@ -179,7 +179,7 @@ export function forEachCellInArea<G extends Grid | SparseGrid>(
start: number,
end: number,
g: G,
fn: (c: G["cells"][0], i: number) => void
fn: (c: G["cells"][0], i: number) => void,
): void {
for (const i of cellsInArea(start, end, g)) fn(g.cells[i], i);
}
@@ -188,7 +188,7 @@ function allCellsInArea<G extends Grid | SparseGrid>(
start: number,
end: number,
g: G,
fn: (c: G["cells"][0], i: number) => boolean
fn: (c: G["cells"][0], i: number) => boolean,
): boolean {
for (const i of cellsInArea(start, end, g)) {
if (!fn(g.cells[i], i)) return false;
@@ -204,7 +204,7 @@ function countCellsInArea<G extends Grid | SparseGrid>(
start: number,
end: number,
g: G,
predicate: (c: G["cells"][0], i: number) => boolean
predicate: (c: G["cells"][0], i: number) => boolean,
): number {
let count = 0;
for (const i of cellsInArea(start, end, g)) {
@@ -217,7 +217,7 @@ const areaEnd = (
start: number,
columns: number,
rows: number,
g: SparseGrid
g: SparseGrid,
): number => start + columns - 1 + g.columns * (rows - 1);
const cloneGrid = <G extends Grid | SparseGrid>(g: G): G => ({
@@ -231,7 +231,7 @@ const cloneGrid = <G extends Grid | SparseGrid>(g: G): G => ({
*/
function getNextGap(
g: SparseGrid,
ignoreGap: (cell: number) => boolean
ignoreGap: (cell: number) => boolean,
): number | null {
const last1By1Index = findLast1By1Index(g);
if (last1By1Index === null) return null;
@@ -278,13 +278,13 @@ function moveTileUnchecked(g: SparseGrid, from: number, to: number): void {
to,
toEnd,
g,
(_c, i) => (g.cells[i] = movingCells.shift())
(_c, i) => (g.cells[i] = movingCells.shift()),
);
forEachCellInArea(
from,
fromEnd,
g,
(_c, i) => (g.cells[i] ??= displacedTiles.shift())
(_c, i) => (g.cells[i] ??= displacedTiles.shift()),
);
}
@@ -294,7 +294,7 @@ function moveTileUnchecked(g: SparseGrid, from: number, to: number): void {
export function moveTile<G extends Grid | SparseGrid>(
g: G,
from: number,
to: number
to: number,
): G {
const tile = g.cells[from]!;
@@ -333,7 +333,7 @@ function pushTileUp(
g: SparseGrid,
from: number,
rows: number,
avoid: (cell: number) => boolean = (): boolean => false
avoid: (cell: number) => boolean = (): boolean => false,
): number {
const tile = g.cells[from]!;
@@ -347,7 +347,7 @@ function pushTileUp(
to,
Math.min(from - g.columns + tile.columns - 1, toEnd),
g,
(c, i) => (c === undefined || is1By1(c)) && !avoid(i)
(c, i) => (c === undefined || is1By1(c)) && !avoid(i),
);
if (cellsAboveAreDisplacable) {
@@ -376,7 +376,7 @@ function canVacateArea(g: SparseGrid, start: number, end: number): boolean {
start,
end - newFullRows * g.columns,
g,
(c) => c === undefined || is1By1(c)
(c) => c === undefined || is1By1(c),
);
}
@@ -391,7 +391,7 @@ function vacateArea(g: SparseGrid, start: number, end: number): SparseGrid {
start,
end,
g,
(c, i) => c !== undefined || i >= g.cells.length
(c, i) => c !== undefined || i >= g.cells.length,
);
const newFullRows = Math.floor(newCellCount / g.columns);
const endRow = row(end, g);
@@ -452,7 +452,7 @@ function vacateArea(g: SparseGrid, start: number, end: number): SparseGrid {
const inputStructure = fillGaps(
outputStructure,
false,
(i) => inArea(i, start, end, g) && g.cells[i] === undefined
(i) => inArea(i, start, end, g) && g.cells[i] === undefined,
);
// We exploit the fact that g and inputStructure have the same structure to
@@ -464,7 +464,7 @@ function vacateArea(g: SparseGrid, start: number, end: number): SparseGrid {
return {
columns: g.columns,
cells: outputStructure.cells.map((placeholder) =>
structureMapping.get(placeholder)
structureMapping.get(placeholder),
),
};
}
@@ -475,21 +475,21 @@ function vacateArea(g: SparseGrid, start: number, end: number): SparseGrid {
export function fillGaps(
g: SparseGrid,
packLargeTiles?: true,
ignoreGap?: () => false
ignoreGap?: () => false,
): Grid;
export function fillGaps(
g: SparseGrid,
packLargeTiles?: boolean,
ignoreGap?: (cell: number) => boolean
ignoreGap?: (cell: number) => boolean,
): SparseGrid;
export function fillGaps(
g: SparseGrid,
packLargeTiles = true,
ignoreGap: (cell: number) => boolean = (): boolean => false
ignoreGap: (cell: number) => boolean = (): boolean => false,
): SparseGrid {
const lastGap = findLastIndex(
g.cells,
(c, i) => c === undefined && !ignoreGap(i)
(c, i) => c === undefined && !ignoreGap(i),
);
if (lastGap === null) return g; // There are no gaps to fill
const lastGapRow = row(lastGap, g);
@@ -500,10 +500,10 @@ export function fillGaps(
// allowed to pack the large tiles into the rest of the grid as necessary)
let idealLength = count(
result.cells,
(c, i) => c !== undefined || ignoreGap(i)
(c, i) => c !== undefined || ignoreGap(i),
);
const fullRowsRemoved = Math.floor(
(g.cells.length - idealLength) / g.columns
(g.cells.length - idealLength) / g.columns,
);
// Step 1: Push all large tiles below the last gap upwards, so that they move
@@ -620,7 +620,7 @@ function createRows(g: SparseGrid, count: number, atRow: number): SparseGrid {
g,
(c, i) => {
result.cells[i + offset] = c;
}
},
);
}
});
@@ -633,7 +633,7 @@ function createRows(g: SparseGrid, count: number, atRow: number): SparseGrid {
*/
export function addItems(
items: TileDescriptor<unknown>[],
g: SparseGrid
g: SparseGrid,
): SparseGrid {
let result: SparseGrid = cloneGrid(g);
@@ -655,7 +655,7 @@ export function addItems(
// This item wants to be placed near another; let's put it on a row
// directly below the related tile
const placeNear = result.cells.findIndex(
(c) => c?.item.id === item.placeNear
(c) => c?.item.id === item.placeNear,
);
if (placeNear === -1) {
// Can't find the related tile, so let's give up and place it at the end
@@ -666,7 +666,7 @@ export function addItems(
placeNear,
placeNearCell.columns,
placeNearCell.rows,
result
result,
);
result = createRows(result, 1, row(placeNearEnd, result) + 1);
@@ -699,7 +699,7 @@ const extraLargeTileDimensions = (g: SparseGrid): [number, number] =>
export function cycleTileSize<G extends Grid | SparseGrid>(
g: G,
tile: TileDescriptor<unknown>
tile: TileDescriptor<unknown>,
): G {
const from = g.cells.findIndex((c) => c?.item === tile);
if (from === -1) return g; // Tile removed, no change
@@ -727,7 +727,7 @@ function findNearestCell<G extends Grid | SparseGrid>(
g: G,
nearestTo: number,
shouldScan: (index: number) => boolean,
predicate: (cell: G["cells"][0], index: number) => boolean
predicate: (cell: G["cells"][0], index: number) => boolean,
): number | null {
const scanLocations = new Set([nearestTo]);
@@ -758,7 +758,7 @@ export function setTileSize<G extends Grid | SparseGrid>(
g: G,
from: number,
toWidth: number,
toHeight: number
toHeight: number,
): G {
const fromCell = g.cells[from]!;
const fromWidth = fromCell.columns;
@@ -771,12 +771,12 @@ export function setTileSize<G extends Grid | SparseGrid>(
0,
Math.min(
g.columns - toWidth,
column(from, g) + Math.trunc((fromWidth - toWidth) / 2)
)
column(from, g) + Math.trunc((fromWidth - toWidth) / 2),
),
);
const toRow = Math.max(
0,
row(from, g) + Math.trunc((fromHeight - toHeight) / 2)
row(from, g) + Math.trunc((fromHeight - toHeight) / 2),
);
const targetDest = toColumn + toRow * g.columns;
@@ -788,7 +788,7 @@ export function setTileSize<G extends Grid | SparseGrid>(
const placeTile = (
to: number,
toEnd: number,
grid: Grid | SparseGrid
grid: Grid | SparseGrid,
): void => {
forEachCellInArea(to, toEnd, grid, (_c, i) => {
grid.cells[i] = {
@@ -824,7 +824,7 @@ export function setTileSize<G extends Grid | SparseGrid>(
(_c, i) => {
const end = areaEnd(i, toWidth, toHeight, g);
return end < newGridSize && canVacateArea(gridWithoutTile, i, end);
}
},
);
if (to !== null) {
@@ -848,7 +848,7 @@ export function setTileSize<G extends Grid | SparseGrid>(
(_c, i) => {
const end = areaEnd(i, toWidth, toHeight, g);
return end < newGridSize && canVacateArea(packedGridWithoutTile, i, end);
}
},
);
if (to === null) return g; // There's no space anywhere; give up
@@ -949,7 +949,7 @@ function updateTiles(g: Grid, tiles: TileDescriptor<unknown>[]): Grid {
// Step 2: Add new tiles
const existingItemIds = new Set(
grid1.cells.filter((c) => c !== undefined).map((c) => c!.item.id)
grid1.cells.filter((c) => c !== undefined).map((c) => c!.item.id),
);
const newItems = tiles.filter((i) => !existingItemIds.has(i.id));
const grid2 = addItems(newItems, grid1);
@@ -967,7 +967,7 @@ function updateBounds(g: Grid, bounds: RectReadOnly): Grid {
const Slots: FC<{ s: Grid }> = memo(({ s: g }) => {
const areas = new Array<(number | null)[]>(
Math.ceil(g.cells.length / g.columns)
Math.ceil(g.cells.length / g.columns),
);
for (let i = 0; i < areas.length; i++)
areas[i] = new Array<number | null>(g.columns).fill(null);
@@ -981,7 +981,7 @@ const Slots: FC<{ s: Grid }> = memo(({ s: g }) => {
i,
slotEnd,
g,
(_c, j) => (areas[row(j, g)][column(j, g)] = slotCount)
(_c, j) => (areas[row(j, g)][column(j, g)] = slotCount),
);
slotCount++;
}
@@ -993,7 +993,7 @@ const Slots: FC<{ s: Grid }> = memo(({ s: g }) => {
(row) =>
`'${row
.map((slotId) => (slotId === null ? "." : `s${slotId}`))
.join(" ")}'`
.join(" ")}'`,
)
.join(" "),
gridTemplateColumns: `repeat(${g.columns}, 1fr)`,
@@ -1019,7 +1019,7 @@ function positionOnTileToCell(
g: SparseGrid,
tileOriginIndex: number,
xPositionOnTile: number,
yPositionOnTile: number
yPositionOnTile: number,
): number {
const tileOrigin = g.cells[tileOriginIndex]!;
const columnOnTile = Math.floor(xPositionOnTile * tileOrigin.columns);
@@ -1034,7 +1034,7 @@ function dragTile(
xPositionOnFrom: number,
yPositionOnFrom: number,
xPositionOnTo: number,
yPositionOnTo: number
yPositionOnTo: number,
): Grid {
const fromOrigin = g.cells.findIndex((c) => c.item === from);
const toOrigin = g.cells.findIndex((c) => c.item === to);
@@ -1042,13 +1042,13 @@ function dragTile(
g,
fromOrigin,
xPositionOnFrom,
yPositionOnFrom
yPositionOnFrom,
);
const toCell = positionOnTileToCell(
g,
toOrigin,
xPositionOnTo,
yPositionOnTo
yPositionOnTo,
);
return moveTile(g, fromOrigin, fromOrigin + toCell - fromCell);

View File

@@ -61,7 +61,7 @@ export interface Layout<State> {
xPositionOnFrom: number,
yPositionOnFrom: number,
xPositionOnTo: number,
yPositionOnTo: number
yPositionOnTo: number,
) => State;
/**
* Toggles the focus of the given tile (if this layout has the concept of
@@ -109,7 +109,7 @@ interface UseLayout<State, T> {
xPositionOnFrom: number,
yPositionOnFrom: number,
xPositionOnTo: number,
yPositionOnTo: number
yPositionOnTo: number,
) => void;
toggleFocus: ((tile: TileDescriptor<T>) => void) | undefined;
slots: ReactNode;
@@ -123,7 +123,7 @@ export function useLayout<State, T>(
layout: Layout<State>,
items: TileDescriptor<T>[],
bounds: RectReadOnly,
layoutStates: LayoutStatesMap
layoutStates: LayoutStatesMap,
): UseLayout<State, T> {
const prevLayout = useRef<Layout<unknown>>();
const prevState = layoutStates.get(layout);
@@ -159,7 +159,7 @@ export function useLayout<State, T>(
generation: generation.current,
canDragTile: useCallback(
(tile: TileDescriptor<T>) => layout.canDragTile(state, tile),
[layout, state]
[layout, state],
),
dragTile: useCallback(
(
@@ -168,7 +168,7 @@ export function useLayout<State, T>(
xPositionOnFrom: number,
yPositionOnFrom: number,
xPositionOnTo: number,
yPositionOnTo: number
yPositionOnTo: number,
) =>
setState((s) =>
layout.dragTile(
@@ -178,17 +178,17 @@ export function useLayout<State, T>(
xPositionOnFrom,
yPositionOnFrom,
xPositionOnTo,
yPositionOnTo
)
yPositionOnTo,
),
),
[layout, setState]
[layout, setState],
),
toggleFocus: useMemo(
() =>
layout.toggleFocus &&
((tile: TileDescriptor<T>): void =>
setState((s) => layout.toggleFocus!(s, tile))),
[layout, setState]
[layout, setState],
),
slots: <layout.Slots s={state} />,
};

View File

@@ -98,13 +98,13 @@ export function NewVideoGrid<T>({
useEffect(() => {
if (slotsRoot !== null) {
setRenderedGeneration(
parseInt(slotsRoot.getAttribute("data-generation")!)
parseInt(slotsRoot.getAttribute("data-generation")!),
);
const observer = new MutationObserver((mutations) => {
if (mutations.some((m) => m.type === "attributes")) {
setRenderedGeneration(
parseInt(slotsRoot.getAttribute("data-generation")!)
parseInt(slotsRoot.getAttribute("data-generation")!),
);
}
});
@@ -158,13 +158,13 @@ export function NewVideoGrid<T>({
if (renderedGeneration !== generation) return prevTiles ?? [];
const tileRects = new Map(
zip(orderedItems, slotRects) as [TileDescriptor<T>, Rect][]
zip(orderedItems, slotRects) as [TileDescriptor<T>, Rect][],
);
// In order to not break drag gestures, it's critical that we render tiles
// in a stable order (that of 'items')
return items.map((item) => ({ ...tileRects.get(item)!, item }));
},
[slotRects, grid, renderedGeneration]
[slotRects, grid, renderedGeneration],
);
// Drag state is stored in a ref rather than component state, because we use
@@ -200,7 +200,7 @@ export function NewVideoGrid<T>({
},
leave: { opacity: 0, scale: 0, immediate: disableAnimations },
config: { mass: 0.7, tension: 252, friction: 25 },
})
}),
// react-spring's types are bugged and can't infer the spring type
) as unknown as [TransitionFn<Tile<T>, TileSpring>, SpringRef<TileSpring>];
@@ -242,7 +242,7 @@ export function NewVideoGrid<T>({
disableAnimations ||
((key): boolean =>
key === "zIndex" || key === "x" || key === "y"),
}
},
);
const overTile = tiles.find(
@@ -250,7 +250,7 @@ export function NewVideoGrid<T>({
cursorX >= t.x &&
cursorX < t.x + t.width &&
cursorY >= t.y &&
cursorY < t.y + t.height
cursorY < t.y + t.height,
);
if (overTile !== undefined)
@@ -260,7 +260,7 @@ export function NewVideoGrid<T>({
(cursorX - tileX) / tile.width,
(cursorY - tileY) / tile.height,
(cursorX - overTile.x) / overTile.width,
(cursorY - overTile.y) / overTile.height
(cursorY - overTile.y) / overTile.height,
);
};
@@ -287,7 +287,7 @@ export function NewVideoGrid<T>({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
last,
}: Parameters<Handler<"drag", EventTypes["drag"]>>[0]
}: Parameters<Handler<"drag", EventTypes["drag"]>>[0],
): void => {
if (tap) {
const now = Date.now();
@@ -303,7 +303,7 @@ export function NewVideoGrid<T>({
}
} else {
const tileController = springRef.current.find(
(c) => (c.item as Tile<T>).item.id === tileId
(c) => (c.item as Tile<T>).item.id === tileId,
)!;
if (canDragTile((tileController.item as Tile<T>).item)) {
@@ -347,7 +347,7 @@ export function NewVideoGrid<T>({
animateDraggedTile(false);
}
},
{ target: gridRef2 }
{ target: gridRef2 },
);
// Render nothing if the grid has yet to be generated

View File

@@ -25,7 +25,7 @@ interface Props<T> {
onDragRef: RefObject<
(
tileId: string,
state: Parameters<Handler<"drag", EventTypes["drag"]>>[0]
state: Parameters<Handler<"drag", EventTypes["drag"]>>[0],
) => void
>;
targetWidth: number;
@@ -87,7 +87,7 @@ export const TileWrapper = memo(
height,
boxShadow: to(
[shadow, shadowSpread],
(s, ss) => `rgba(0, 0, 0, 0.5) 0px ${s}px ${2 * s}px ${ss}px`
(s, ss) => `rgba(0, 0, 0, 0.5) 0px ${s}px ${2 * s}px ${ss}px`,
),
},
targetWidth,
@@ -96,7 +96,7 @@ export const TileWrapper = memo(
})}
</>
);
}
},
// We pretend this component is a simple function rather than a
// NamedExoticComponent, because that's the only way we can fit in a type
// parameter

View File

@@ -151,7 +151,7 @@ function getTilePositions(
gridHeight: number,
pipXRatio: number,
pipYRatio: number,
layout: Layout
layout: Layout,
): TilePosition[] {
if (layout === "grid") {
if (tileCount === 2 && focusedTileCount === 0) {
@@ -159,7 +159,7 @@ function getTilePositions(
gridWidth,
gridHeight,
pipXRatio,
pipYRatio
pipYRatio,
);
}
@@ -167,7 +167,7 @@ function getTilePositions(
tileCount,
focusedTileCount,
gridWidth,
gridHeight
gridHeight,
);
} else {
return getSpotlightLayoutTilePositions(tileCount, gridWidth, gridHeight);
@@ -178,13 +178,13 @@ function getOneOnOneLayoutTilePositions(
gridWidth: number,
gridHeight: number,
pipXRatio: number,
pipYRatio: number
pipYRatio: number,
): TilePosition[] {
const [remotePosition] = getFreedomLayoutTilePositions(
1,
0,
gridWidth,
gridHeight
gridHeight,
);
const gridAspectRatio = gridWidth / gridHeight;
@@ -196,7 +196,7 @@ function getOneOnOneLayoutTilePositions(
const pipScaleFactor = Math.min(
1,
remotePosition.width / 3 / maxPipWidth,
remotePosition.height / 3 / maxPipHeight
remotePosition.height / 3 / maxPipHeight,
);
const pipWidth = maxPipWidth * pipScaleFactor;
const pipHeight = maxPipHeight * pipScaleFactor;
@@ -223,7 +223,7 @@ function getOneOnOneLayoutTilePositions(
function getSpotlightLayoutTilePositions(
tileCount: number,
gridWidth: number,
gridHeight: number
gridHeight: number,
): TilePosition[] {
const tilePositions: TilePosition[] = [];
@@ -293,7 +293,7 @@ function getFreedomLayoutTilePositions(
tileCount: number,
focusedTileCount: number,
gridWidth: number,
gridHeight: number
gridHeight: number,
): TilePosition[] {
if (tileCount === 0) {
return [];
@@ -307,7 +307,7 @@ function getFreedomLayoutTilePositions(
tileCount,
focusedTileCount,
gridWidth,
gridHeight
gridHeight,
);
let itemGridWidth;
@@ -335,7 +335,7 @@ function getFreedomLayoutTilePositions(
itemRowCount,
itemTileAspectRatio,
itemGridWidth,
itemGridHeight
itemGridHeight,
);
const itemGridBounds = getSubGridBoundingBox(itemGridPositions);
@@ -367,7 +367,7 @@ function getFreedomLayoutTilePositions(
focusedRowCount,
focusedTileAspectRatio,
focusedGridWidth,
focusedGridHeight
focusedGridHeight,
);
const tilePositions = [...focusedGridPositions, ...itemGridPositions];
@@ -380,7 +380,7 @@ function getFreedomLayoutTilePositions(
gridWidth,
gridHeight - focusedGridHeight,
0,
focusedGridHeight
focusedGridHeight,
);
} else {
centerTiles(
@@ -388,7 +388,7 @@ function getFreedomLayoutTilePositions(
gridWidth - focusedGridWidth,
gridHeight,
focusedGridWidth,
0
0,
);
}
@@ -454,7 +454,7 @@ function getGridLayout(
tileCount: number,
focusedTileCount: number,
gridWidth: number,
gridHeight: number
gridHeight: number,
): { itemGridRatio: number; layoutDirection: LayoutDirection } {
let layoutDirection: LayoutDirection = "horizontal";
let itemGridRatio = 1;
@@ -479,7 +479,7 @@ function centerTiles(
gridWidth: number,
gridHeight: number,
offsetLeft: number,
offsetTop: number
offsetTop: number,
): TilePosition[] {
const bounds = getSubGridBoundingBox(positions);
@@ -494,7 +494,7 @@ function centerTiles(
function applyTileOffsets(
positions: TilePosition[],
leftOffset: number,
topOffset: number
topOffset: number,
): TilePosition[] {
for (const position of positions) {
position.x += leftOffset;
@@ -507,7 +507,7 @@ function applyTileOffsets(
function getSubGridLayout(
tileCount: number,
gridWidth: number,
gridHeight: number
gridHeight: number,
): { columnCount: number; rowCount: number; tileAspectRatio: number } {
const gridAspectRatio = gridWidth / gridHeight;
@@ -624,7 +624,7 @@ function getSubGridPositions(
rowCount: number,
tileAspectRatio: number,
gridWidth: number,
gridHeight: number
gridHeight: number,
): TilePosition[] {
if (tileCount === 0) {
return [];
@@ -633,7 +633,7 @@ function getSubGridPositions(
const newTilePositions: TilePosition[] = [];
const boxWidth = Math.round(
(gridWidth - GAP * (columnCount + 1)) / columnCount
(gridWidth - GAP * (columnCount + 1)) / columnCount,
);
const boxHeight = Math.round((gridHeight - GAP * (rowCount + 1)) / rowCount);
@@ -675,7 +675,7 @@ function getSubGridPositions(
const subgridWidth = tileWidth * columnCount + (GAP * columnCount - 1);
centeringPadding = Math.round(
(subgridWidth - (tileWidth * rowItemCount + (GAP * rowItemCount - 1))) /
2
2,
);
}
@@ -699,7 +699,7 @@ function displayedTileCount(
layout: Layout,
tileCount: number,
gridWidth: number,
gridHeight: number
gridHeight: number,
): number {
let displayedTile = -1;
if (layout === "grid") {
@@ -731,7 +731,7 @@ function displayedTileCount(
function reorderTiles<T>(
tiles: Tile<T>[],
layout: Layout,
displayedTile = -1
displayedTile = -1,
): void {
// We use a special layout for 1:1 to always put the local tile first.
// We only do this if there are two tiles (obviously) and exactly one
@@ -919,7 +919,7 @@ export function VideoGrid<T>({
for (const item of items) {
const existingTileIndex = newTiles.findIndex(
({ key }) => item.id === key
({ key }) => item.id === key,
);
const existingTile = newTiles[existingTileIndex];
@@ -956,7 +956,7 @@ export function VideoGrid<T>({
layout,
newTiles.length,
gridBounds.width,
gridBounds.height
gridBounds.height,
);
}
@@ -976,7 +976,7 @@ export function VideoGrid<T>({
const focusedTileCount = newTiles.reduce(
(count, tile) => count + (tile.focused ? 1 : 0),
0
0,
);
return {
@@ -989,7 +989,7 @@ export function VideoGrid<T>({
gridBounds.height,
pipXRatio,
pipYRatio,
layout
layout,
),
};
});
@@ -998,7 +998,7 @@ export function VideoGrid<T>({
const focusedTileCount = newTiles.reduce(
(count, tile) => count + (tile.focused ? 1 : 0),
0
0,
);
lastLayoutRef.current = layout;
@@ -1013,7 +1013,7 @@ export function VideoGrid<T>({
gridBounds.height,
pipXRatio,
pipYRatio,
layout
layout,
),
};
});
@@ -1066,7 +1066,7 @@ export function VideoGrid<T>({
} else {
const isMobile = isMobileBreakpoint(
gridBounds.width,
gridBounds.height
gridBounds.height,
);
const x =
@@ -1127,7 +1127,7 @@ export function VideoGrid<T>({
}
};
},
[tilePositions, disableAnimations, scrollPosition, layout, gridBounds]
[tilePositions, disableAnimations, scrollPosition, layout, gridBounds],
);
const [springs, api] = useSprings(tiles.length, animate(tiles), [
@@ -1179,12 +1179,12 @@ export function VideoGrid<T>({
gridBounds.height,
pipXRatio,
pipYRatio,
layout
layout,
),
};
});
},
[tiles, layout, gridBounds.width, gridBounds.height, pipXRatio, pipYRatio]
[tiles, layout, gridBounds.width, gridBounds.height, pipXRatio, pipYRatio],
);
// Callback for useDrag. We could call useDrag here, but the default
@@ -1213,7 +1213,7 @@ export function VideoGrid<T>({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
event,
}: Parameters<Handler<"drag", EventTypes["drag"]>>[0]
}: Parameters<Handler<"drag", EventTypes["drag"]>>[0],
): void => {
event.preventDefault();
@@ -1243,7 +1243,7 @@ export function VideoGrid<T>({
const pipGap = getPipGap(
gridBounds.width / gridBounds.height,
gridBounds.width
gridBounds.width,
);
const pipMinX = remotePosition.x + pipGap;
const pipMinY = remotePosition.y + pipGap;
@@ -1270,7 +1270,7 @@ export function VideoGrid<T>({
const hoverTile = tiles.find(
(tile) =>
tile.key !== tileId &&
isInside(cursorPosition, tilePositions[tile.order])
isInside(cursorPosition, tilePositions[tile.order]),
);
if (hoverTile) {
@@ -1331,7 +1331,7 @@ export function VideoGrid<T>({
e:
| Omit<FullGestureState<"wheel">, "event">
| Omit<FullGestureState<"drag">, "event">,
isWheel: boolean
isWheel: boolean,
) => {
if (layout !== "spotlight") {
return;
@@ -1355,10 +1355,10 @@ export function VideoGrid<T>({
}
setScrollPosition((scrollPosition) =>
Math.min(Math.max(movement + scrollPosition, min), 0)
Math.min(Math.max(movement + scrollPosition, min), 0),
);
},
[layout, gridBounds, tilePositions]
[layout, gridBounds, tilePositions],
);
const bindGrid = useGesture(
@@ -1370,7 +1370,7 @@ export function VideoGrid<T>({
// @ts-ignore
onDrag: (e) => onGridGesture(e, false),
},
{}
{},
);
return (

View File

@@ -24,7 +24,9 @@ limitations under the License.
overflow: hidden;
cursor: pointer;
outline: 2px solid rgba(0, 0, 0, 0);
transition: outline-radius ease 0.15s, outline-color ease 0.15s;
transition:
outline-radius ease 0.15s,
outline-color ease 0.15s;
}
.videoTile * {

View File

@@ -84,7 +84,7 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
showSpeakingIndicator,
showConnectionStats,
},
tileRef
tileRef,
) => {
const { t } = useTranslation();
@@ -93,7 +93,7 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
// Handle display name changes.
const [displayName, setDisplayName] = useReactiveState(
() => member?.rawDisplayName ?? "[👻]",
[member]
[member],
);
useEffect(() => {
if (member) {
@@ -113,7 +113,7 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
content === TileContent.UserMedia
? Track.Source.Microphone
: Track.Source.ScreenShareAudio,
sfuParticipant
sfuParticipant,
).isMuted !== false;
const MicIcon = muted ? MicOffSolidIcon : MicOnSolidIcon;
@@ -126,11 +126,11 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
useState(false);
const openVideoTileSettingsModal = useCallback(
() => setVideoTileSettingsModalOpen(true),
[setVideoTileSettingsModalOpen]
[setVideoTileSettingsModalOpen],
);
const closeVideoTileSettingsModal = useCallback(
() => setVideoTileSettingsModalOpen(false),
[setVideoTileSettingsModalOpen]
[setVideoTileSettingsModalOpen],
);
const toolbarButtons: JSX.Element[] = [];
@@ -141,7 +141,7 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
className={styles.button}
volume={(sfuParticipant as RemoteParticipant).getVolume() ?? 0}
onPress={openVideoTileSettingsModal}
/>
/>,
);
if (content === TileContent.ScreenShare) {
@@ -151,7 +151,7 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
className={styles.button}
fullscreen={fullscreen}
onPress={onFullscreen}
/>
/>,
);
}
}
@@ -228,5 +228,5 @@ export const VideoTile = forwardRef<HTMLDivElement, Props>(
)}
</animated.div>
);
}
},
);

View File

@@ -39,7 +39,7 @@ const LocalVolume: FC<LocalVolumeProps> = ({
: Track.Source.ScreenShareAudio;
const [localVolume, setLocalVolume] = useState<number>(
participant.getVolume(source) ?? 0
participant.getVolume(source) ?? 0,
);
const onLocalVolumeChanged = (event: ChangeEvent<HTMLInputElement>): void => {