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