Add double tap to focus
This commit is contained in:
parent
1cfb7a6c5d
commit
b0d5acd780
1 changed files with 88 additions and 69 deletions
|
|
@ -403,6 +403,7 @@ export function VideoGrid({ participants }) {
|
||||||
tilePositions: [],
|
tilePositions: [],
|
||||||
});
|
});
|
||||||
const draggingTileRef = useRef(null);
|
const draggingTileRef = useRef(null);
|
||||||
|
const lastTappedRef = useRef({});
|
||||||
const isMounted = useIsMounted();
|
const isMounted = useIsMounted();
|
||||||
|
|
||||||
const [gridRef, gridBounds] = useMeasure();
|
const [gridRef, gridBounds] = useMeasure();
|
||||||
|
|
@ -543,67 +544,29 @@ export function VideoGrid({ participants }) {
|
||||||
tiles,
|
tiles,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const bind = useDrag(({ args: [key], active, xy, movement }) => {
|
const onTap = useCallback(
|
||||||
const dragTileIndex = tiles.findIndex((tile) => tile.key === key);
|
(tileKey) => {
|
||||||
const dragTile = tiles[dragTileIndex];
|
const lastTapped = lastTappedRef.current[tileKey];
|
||||||
const dragTilePosition = tilePositions[dragTileIndex];
|
|
||||||
|
|
||||||
let newTiles = tiles;
|
if (!lastTapped) {
|
||||||
|
lastTappedRef.current[tileKey] = Date.now();
|
||||||
const cursorPosition = [xy[0] - gridBounds.left, xy[1] - gridBounds.top];
|
return;
|
||||||
|
|
||||||
for (
|
|
||||||
let hoverTileIndex = 0;
|
|
||||||
hoverTileIndex < tiles.length;
|
|
||||||
hoverTileIndex++
|
|
||||||
) {
|
|
||||||
const hoverTile = tiles[hoverTileIndex];
|
|
||||||
const hoverTilePosition = tilePositions[hoverTileIndex];
|
|
||||||
|
|
||||||
if (hoverTile.key === key) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInside(cursorPosition, hoverTilePosition)) {
|
if (Date.now() - lastTapped > 500) {
|
||||||
newTiles = moveArrItem(tiles, dragTileIndex, hoverTileIndex);
|
return;
|
||||||
|
|
||||||
newTiles = newTiles.map((tile) => {
|
|
||||||
if (tile === hoverTile) {
|
|
||||||
return { ...tile, presenter: dragTile.presenter };
|
|
||||||
} else if (tile === dragTile) {
|
|
||||||
return { ...tile, presenter: hoverTile.presenter };
|
|
||||||
} else {
|
|
||||||
return tile;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
newTiles.sort((a, b) => (b.presenter ? 1 : 0) - (a.presenter ? 1 : 0));
|
|
||||||
|
|
||||||
setTileState((state) => ({ ...state, tiles: newTiles }));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active) {
|
lastTappedRef.current[tileKey] = 0;
|
||||||
if (!draggingTileRef.current) {
|
|
||||||
draggingTileRef.current = {
|
const tile = tiles.find((tile) => tile.key === tileKey);
|
||||||
key: dragTile.key,
|
|
||||||
offsetX: dragTilePosition.x,
|
if (!tile) {
|
||||||
offsetY: dragTilePosition.y,
|
return;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
draggingTileRef.current.x = movement[0];
|
const participant = tile.participant;
|
||||||
draggingTileRef.current.y = movement[1];
|
|
||||||
} else {
|
|
||||||
draggingTileRef.current = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
api.start(animate(newTiles));
|
|
||||||
});
|
|
||||||
|
|
||||||
const onClickNameTag = useCallback(
|
|
||||||
(participant) => {
|
|
||||||
setTileState((state) => {
|
setTileState((state) => {
|
||||||
let presenterTileCount = 0;
|
let presenterTileCount = 0;
|
||||||
|
|
||||||
|
|
@ -637,7 +600,76 @@ export function VideoGrid({ participants }) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[gridBounds]
|
[tiles, gridBounds]
|
||||||
|
);
|
||||||
|
|
||||||
|
const bind = useDrag(
|
||||||
|
({ args: [key], active, xy, movement, tap }) => {
|
||||||
|
if (tap) {
|
||||||
|
onTap(key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dragTileIndex = tiles.findIndex((tile) => tile.key === key);
|
||||||
|
const dragTile = tiles[dragTileIndex];
|
||||||
|
const dragTilePosition = tilePositions[dragTileIndex];
|
||||||
|
|
||||||
|
let newTiles = tiles;
|
||||||
|
|
||||||
|
const cursorPosition = [xy[0] - gridBounds.left, xy[1] - gridBounds.top];
|
||||||
|
|
||||||
|
for (
|
||||||
|
let hoverTileIndex = 0;
|
||||||
|
hoverTileIndex < tiles.length;
|
||||||
|
hoverTileIndex++
|
||||||
|
) {
|
||||||
|
const hoverTile = tiles[hoverTileIndex];
|
||||||
|
const hoverTilePosition = tilePositions[hoverTileIndex];
|
||||||
|
|
||||||
|
if (hoverTile.key === key) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isInside(cursorPosition, hoverTilePosition)) {
|
||||||
|
newTiles = moveArrItem(tiles, dragTileIndex, hoverTileIndex);
|
||||||
|
|
||||||
|
newTiles = newTiles.map((tile) => {
|
||||||
|
if (tile === hoverTile) {
|
||||||
|
return { ...tile, presenter: dragTile.presenter };
|
||||||
|
} else if (tile === dragTile) {
|
||||||
|
return { ...tile, presenter: hoverTile.presenter };
|
||||||
|
} else {
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newTiles.sort(
|
||||||
|
(a, b) => (b.presenter ? 1 : 0) - (a.presenter ? 1 : 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
setTileState((state) => ({ ...state, tiles: newTiles }));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
if (!draggingTileRef.current) {
|
||||||
|
draggingTileRef.current = {
|
||||||
|
key: dragTile.key,
|
||||||
|
offsetX: dragTilePosition.x,
|
||||||
|
offsetY: dragTilePosition.y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
draggingTileRef.current.x = movement[0];
|
||||||
|
draggingTileRef.current.y = movement[1];
|
||||||
|
} else {
|
||||||
|
draggingTileRef.current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
api.start(animate(newTiles));
|
||||||
|
},
|
||||||
|
{ filterTaps: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -656,7 +688,6 @@ export function VideoGrid({ participants }) {
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
{...tile}
|
{...tile}
|
||||||
onClickNameTag={onClickNameTag}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
@ -664,14 +695,7 @@ export function VideoGrid({ participants }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ParticipantTile({
|
function ParticipantTile({ style, participant, remove, presenter, ...rest }) {
|
||||||
style,
|
|
||||||
participant,
|
|
||||||
remove,
|
|
||||||
presenter,
|
|
||||||
onClickNameTag,
|
|
||||||
...rest
|
|
||||||
}) {
|
|
||||||
const videoRef = useRef();
|
const videoRef = useRef();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -696,11 +720,6 @@ function ParticipantTile({
|
||||||
className={classNames(styles.participantName, {
|
className={classNames(styles.participantName, {
|
||||||
[styles.speaking]: participant.speaking,
|
[styles.speaking]: participant.speaking,
|
||||||
})}
|
})}
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
onClickNameTag(participant);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{participant.speaking ? (
|
{participant.speaking ? (
|
||||||
<MicIcon />
|
<MicIcon />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue