usePositionNavigator.jsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import React from "react";
  2. import { useTranslation } from "react-i18next";
  3. import { toast } from "react-toastify";
  4. import { useSetRecoilState, useRecoilCallback } from "recoil";
  5. import { PanZoomRotateAtom } from "./";
  6. const digitCodes = [...Array(5).keys()].map((id) => `Digit${id}`);
  7. const usePositionNavigator = () => {
  8. const { t } = useTranslation();
  9. const setDim = useSetRecoilState(PanZoomRotateAtom);
  10. const [positions, setPositions] = React.useState({});
  11. const onKeyDown = useRecoilCallback(
  12. ({ snapshot }) => async (e) => {
  13. // Block shortcut if we are typing in a textarea or input
  14. if (["INPUT", "TEXTAREA"].includes(e.target.tagName)) return;
  15. if (digitCodes.includes(e.code)) {
  16. const positionKey = e.code;
  17. const dim = await snapshot.getPromise(PanZoomRotateAtom);
  18. if (e.altKey || e.metaKey || e.ctrlKey) {
  19. setPositions((prev) => ({ ...prev, [positionKey]: { ...dim } }));
  20. toast.info(t("Position saved!"), {
  21. autoClose: 800,
  22. hideProgressBar: true,
  23. });
  24. } else {
  25. if (positions[positionKey]) {
  26. setDim((prev) => ({ ...prev, ...positions[positionKey] }));
  27. }
  28. }
  29. e.preventDefault();
  30. }
  31. },
  32. [positions, setDim, t]
  33. );
  34. React.useEffect(() => {
  35. document.addEventListener("keydown", onKeyDown);
  36. return () => {
  37. document.removeEventListener("keydown", onKeyDown);
  38. };
  39. }, [onKeyDown]);
  40. return null;
  41. };
  42. export default usePositionNavigator;