Merge pull request #708 from robintown/join-polish
Improve the visual experience of joining a call
This commit is contained in:
commit
02e1d602d9
2 changed files with 91 additions and 60 deletions
|
@ -126,6 +126,7 @@ export function InCallView({
|
||||||
|
|
||||||
const containerRef1 = useRef<HTMLDivElement | null>(null);
|
const containerRef1 = useRef<HTMLDivElement | null>(null);
|
||||||
const [containerRef2, bounds] = useMeasure({ polyfill: ResizeObserver });
|
const [containerRef2, bounds] = useMeasure({ polyfill: ResizeObserver });
|
||||||
|
const boundsValid = bounds.height > 0;
|
||||||
// Merge the refs so they can attach to the same element
|
// Merge the refs so they can attach to the same element
|
||||||
const containerRef = useCallback(
|
const containerRef = useCallback(
|
||||||
(el: HTMLDivElement) => {
|
(el: HTMLDivElement) => {
|
||||||
|
@ -238,15 +239,15 @@ export function InCallView({
|
||||||
const maximisedParticipant = useMemo(
|
const maximisedParticipant = useMemo(
|
||||||
() =>
|
() =>
|
||||||
fullscreenParticipant ??
|
fullscreenParticipant ??
|
||||||
(bounds.height <= 400 && bounds.width <= 400
|
(boundsValid && bounds.height <= 400 && bounds.width <= 400
|
||||||
? items.find((item) => item.focused) ??
|
? items.find((item) => item.focused) ??
|
||||||
items.find((item) => item.callFeed) ??
|
items.find((item) => item.callFeed) ??
|
||||||
null
|
null
|
||||||
: null),
|
: null),
|
||||||
[fullscreenParticipant, bounds, items]
|
[fullscreenParticipant, boundsValid, bounds, items]
|
||||||
);
|
);
|
||||||
|
|
||||||
const reducedControls = bounds.width <= 400;
|
const reducedControls = boundsValid && bounds.width <= 400;
|
||||||
|
|
||||||
const renderAvatar = useCallback(
|
const renderAvatar = useCallback(
|
||||||
(roomMember: RoomMember, width: number, height: number) => {
|
(roomMember: RoomMember, width: number, height: number) => {
|
||||||
|
|
|
@ -859,13 +859,21 @@ export function VideoGrid({
|
||||||
});
|
});
|
||||||
}, [items, gridBounds, layout, isMounted, pipXRatio, pipYRatio]);
|
}, [items, gridBounds, layout, isMounted, pipXRatio, pipYRatio]);
|
||||||
|
|
||||||
|
const tilePositionsValid = useRef(false);
|
||||||
|
|
||||||
const animate = useCallback(
|
const animate = useCallback(
|
||||||
(tiles: Tile[]) => (tileIndex: number) => {
|
(tiles: Tile[]) => {
|
||||||
|
// Whether the tile positions were valid at the time of the previous
|
||||||
|
// animation
|
||||||
|
const tilePositionsWereValid = tilePositionsValid.current;
|
||||||
|
|
||||||
|
return (tileIndex: number) => {
|
||||||
const tile = tiles[tileIndex];
|
const tile = tiles[tileIndex];
|
||||||
const tilePosition = tilePositions[tile.order];
|
const tilePosition = tilePositions[tile.order];
|
||||||
const draggingTile = draggingTileRef.current;
|
const draggingTile = draggingTileRef.current;
|
||||||
const dragging = draggingTile && tile.key === draggingTile.key;
|
const dragging = draggingTile && tile.key === draggingTile.key;
|
||||||
const remove = tile.remove;
|
const remove = tile.remove;
|
||||||
|
tilePositionsValid.current = tilePosition.height > 0;
|
||||||
|
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
return {
|
return {
|
||||||
|
@ -896,36 +904,58 @@ export function VideoGrid({
|
||||||
gridBounds.height
|
gridBounds.height
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
const x =
|
||||||
x:
|
|
||||||
tilePosition.x +
|
tilePosition.x +
|
||||||
(layout === "spotlight" && tile.order !== 0 && isMobile
|
(layout === "spotlight" && tile.order !== 0 && isMobile
|
||||||
? scrollPosition
|
? scrollPosition
|
||||||
: 0),
|
: 0);
|
||||||
y:
|
const y =
|
||||||
tilePosition.y +
|
tilePosition.y +
|
||||||
(layout === "spotlight" && tile.order !== 0 && !isMobile
|
(layout === "spotlight" && tile.order !== 0 && !isMobile
|
||||||
? scrollPosition
|
? scrollPosition
|
||||||
: 0),
|
: 0);
|
||||||
|
const from: {
|
||||||
|
shadow: number;
|
||||||
|
scale: number;
|
||||||
|
opacity: number;
|
||||||
|
x?: number;
|
||||||
|
y?: number;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
} = { shadow: 1, scale: 0, opacity: 0 };
|
||||||
|
let reset = false;
|
||||||
|
|
||||||
|
if (!tilePositionsWereValid) {
|
||||||
|
// This indicates that the component just mounted. We discard the
|
||||||
|
// previous keyframe by resetting the tile's position, so that it
|
||||||
|
// animates in from the right place on screen, rather than wherever
|
||||||
|
// the zero-height grid placed it.
|
||||||
|
from.x = x;
|
||||||
|
from.y = y;
|
||||||
|
from.width = tilePosition.width;
|
||||||
|
from.height = tilePosition.height;
|
||||||
|
reset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
width: tilePosition.width,
|
width: tilePosition.width,
|
||||||
height: tilePosition.height,
|
height: tilePosition.height,
|
||||||
scale: remove ? 0 : 1,
|
scale: remove ? 0 : 1,
|
||||||
opacity: remove ? 0 : 1,
|
opacity: remove ? 0 : 1,
|
||||||
zIndex: tilePosition.zIndex,
|
zIndex: tilePosition.zIndex,
|
||||||
shadow: 1,
|
shadow: 1,
|
||||||
from: {
|
from,
|
||||||
shadow: 1,
|
reset,
|
||||||
scale: 0,
|
|
||||||
opacity: 0,
|
|
||||||
},
|
|
||||||
reset: false,
|
|
||||||
immediate: (key: string) =>
|
immediate: (key: string) =>
|
||||||
disableAnimations || key === "zIndex" || key === "shadow",
|
disableAnimations || key === "zIndex" || key === "shadow",
|
||||||
// If we just stopped dragging a tile, give it time for its animation
|
// If we just stopped dragging a tile, give it time for the
|
||||||
// to settle before pushing its z-index back down
|
// animation to settle before pushing its z-index back down
|
||||||
delay: (key: string) => (key === "zIndex" ? 500 : 0),
|
delay: (key: string) => (key === "zIndex" ? 500 : 0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
[tilePositions, disableAnimations, scrollPosition, layout, gridBounds]
|
[tilePositions, disableAnimations, scrollPosition, layout, gridBounds]
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue