From 7b0675f1ba22f8509e4997b651b95b6de365a9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n=20Svitek?= Date: Wed, 17 Jul 2024 16:41:56 +0200 Subject: [PATCH 1/9] Renamed file of BasicTooltip component && created separate file for its props --- web/src/components/app-header/LoginAppHeader.tsx | 2 +- web/src/components/button/button.tsx | 13 +++---------- web/src/components/icon/icon.tsx | 13 +++---------- .../tooltip/{tooltip.tsx => BasicTooltip.tsx} | 13 +++---------- web/src/components/tooltip/tooltip-props.ts | 9 +++++++++ web/src/containers/views/games/GameActionsPanel.tsx | 2 +- .../containers/views/games/game-draw/game-draw.tsx | 2 +- .../containers/views/view-photogallery/Lightbox.tsx | 2 +- .../ActionsPanel/AudioButton.tsx | 2 +- .../ActionsPanel/EditorButton.tsx | 2 +- .../view-screen-overlay/ActionsPanel/PlayButton.tsx | 2 +- .../ActionsPanel/ReactivateTutorialButton.tsx | 2 +- .../ActionsPanel/SettingsButton.tsx | 2 +- 13 files changed, 27 insertions(+), 39 deletions(-) rename web/src/components/tooltip/{tooltip.tsx => BasicTooltip.tsx} (68%) create mode 100644 web/src/components/tooltip/tooltip-props.ts diff --git a/web/src/components/app-header/LoginAppHeader.tsx b/web/src/components/app-header/LoginAppHeader.tsx index c736e785..785a1159 100644 --- a/web/src/components/app-header/LoginAppHeader.tsx +++ b/web/src/components/app-header/LoginAppHeader.tsx @@ -12,7 +12,7 @@ import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { MdEdit } from "react-icons/md"; import { MdEditOff } from "react-icons/md"; -import { BasicTooltip } from "components/tooltip/tooltip"; +import { BasicTooltip } from "components/tooltip/BasicTooltip"; // Models import { ActiveExpo, Screen } from "models"; diff --git a/web/src/components/button/button.tsx b/web/src/components/button/button.tsx index c0828178..156546cd 100644 --- a/web/src/components/button/button.tsx +++ b/web/src/components/button/button.tsx @@ -3,15 +3,8 @@ import { CSSProperties, forwardRef } from "react"; import { useExpoDesignData } from "hooks/view-hooks/expo-design-data-hook"; import cx from "classnames"; -import { BasicTooltip } from "components/tooltip/tooltip"; -import { PlacesType } from "react-tooltip"; - -type TooltipOption = { - id: string; - content: string; - variant?: "light" | "dark"; // if undefined, based on selected theme - place?: PlacesType; -}; +import { BasicTooltip } from "components/tooltip/BasicTooltip"; +import { BasicTooltipProps } from "components/tooltip/tooltip-props"; interface ButtonProps { color?: "default" | "primary" | "secondary" | "white" | "expoTheme"; @@ -27,7 +20,7 @@ interface ButtonProps { shadow?: boolean; iconBefore?: React.ReactNode; iconAfter?: React.ReactNode; - tooltip?: TooltipOption; + tooltip?: BasicTooltipProps; children?: React.ReactNode; } diff --git a/web/src/components/icon/icon.tsx b/web/src/components/icon/icon.tsx index 89637cd8..e99c39eb 100644 --- a/web/src/components/icon/icon.tsx +++ b/web/src/components/icon/icon.tsx @@ -5,18 +5,11 @@ import { useExpoDesignData } from "hooks/view-hooks/expo-design-data-hook"; import { Icon as MuiIcon } from "@mui/material"; import FontIcon from "react-md/lib/FontIcons/FontIcon"; -import { BasicTooltip } from "components/tooltip/tooltip"; -import { PlacesType } from "react-tooltip"; +import { BasicTooltip } from "components/tooltip/BasicTooltip"; +import { BasicTooltipProps } from "components/tooltip/tooltip-props"; import cx from "classnames"; -type TooltipOption = { - id: string; - content: string; - variant?: "light" | "dark"; // if undefined, based on selected theme - place?: PlacesType; -}; - interface IconProps { name: string | ReactNode; // name either for FontIcon from 'react-md' or Icon from 'material-ui' useMaterialUiIcon?: boolean; @@ -32,7 +25,7 @@ interface IconProps { noCenterPlace?: boolean; // by default, icon should be inside some container and centered className?: string; style?: CSSProperties; - tooltip?: TooltipOption; + tooltip?: BasicTooltipProps; } export const Icon = ({ diff --git a/web/src/components/tooltip/tooltip.tsx b/web/src/components/tooltip/BasicTooltip.tsx similarity index 68% rename from web/src/components/tooltip/tooltip.tsx rename to web/src/components/tooltip/BasicTooltip.tsx index 5485e1c3..5cb50e4e 100644 --- a/web/src/components/tooltip/tooltip.tsx +++ b/web/src/components/tooltip/BasicTooltip.tsx @@ -1,13 +1,6 @@ -import { Tooltip as ReactTooltip, PlacesType } from "react-tooltip"; +import { Tooltip as ReactTooltip } from "react-tooltip"; import { useExpoDesignData } from "hooks/view-hooks/expo-design-data-hook"; - -type TooltipProps = { - id: string; - content: string; - variant?: "light" | "dark"; - place?: PlacesType; - className?: string; -}; +import { BasicTooltipProps } from "./tooltip-props"; /** * Basic tooltip which listens to theme changes if variant is not overridden by prop @@ -18,7 +11,7 @@ export const BasicTooltip = ({ variant, place, className, -}: TooltipProps) => { +}: BasicTooltipProps) => { const { isLightMode } = useExpoDesignData(); return ( Date: Wed, 17 Jul 2024 16:57:23 +0200 Subject: [PATCH 2/9] Replaced manual BasicTooltip component with tooltip props on button and icon component --- .../views/games/GameActionsPanel.tsx | 27 +++----- .../views/games/game-draw/game-draw.tsx | 50 ++++++-------- .../views/view-photogallery/Lightbox.tsx | 68 +++++++++++-------- .../ActionsPanel/AudioButton.tsx | 39 +++++------ .../ActionsPanel/EditorButton.tsx | 36 +++++----- .../ActionsPanel/PlayButton.tsx | 40 ++++++----- .../ActionsPanel/ReactivateTutorialButton.tsx | 36 +++++----- .../ActionsPanel/SettingsButton.tsx | 39 +++++------ 8 files changed, 156 insertions(+), 179 deletions(-) diff --git a/web/src/containers/views/games/GameActionsPanel.tsx b/web/src/containers/views/games/GameActionsPanel.tsx index c66cf232..34f8d513 100644 --- a/web/src/containers/views/games/GameActionsPanel.tsx +++ b/web/src/containers/views/games/GameActionsPanel.tsx @@ -1,6 +1,5 @@ import { Button } from "components/button/button"; import { Icon } from "components/icon/icon"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import { useDrawerPanel } from "context/drawer-panel-provider/drawer-panel-provider"; import { useTranslation } from "react-i18next"; @@ -42,37 +41,31 @@ export const GameActionsPanel = ({ )} {/* Play again button */} -
+
{/* Done button */} -
+
diff --git a/web/src/containers/views/games/game-draw/game-draw.tsx b/web/src/containers/views/games/game-draw/game-draw.tsx index 29a90c96..fecd3cd8 100644 --- a/web/src/containers/views/games/game-draw/game-draw.tsx +++ b/web/src/containers/views/games/game-draw/game-draw.tsx @@ -17,7 +17,6 @@ import { Button } from "components/button/button"; import { useBoolean } from "hooks/boolean-hook"; import { Popper } from "components/popper/popper"; import { GameActionsPanel } from "../GameActionsPanel"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import { useTutorial } from "context/tutorial-provider/use-tutorial"; import { configureContext } from "./configureContext"; @@ -253,48 +252,41 @@ export const GameDraw = ({ onGameFinish={onGameFinish} onGameReset={onGameReset} gameActions={[ -
+
, -
+
, -
- -
, ]} />, diff --git a/web/src/containers/views/view-photogallery/Lightbox.tsx b/web/src/containers/views/view-photogallery/Lightbox.tsx index 1e2bdfc3..f24b4b2a 100644 --- a/web/src/containers/views/view-photogallery/Lightbox.tsx +++ b/web/src/containers/views/view-photogallery/Lightbox.tsx @@ -11,7 +11,6 @@ import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch"; import { Button } from "components/button/button"; import { Icon } from "components/icon/icon"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import { InformationDialog } from "components/dialogs/information-dialog/information-dialog"; @@ -138,8 +137,14 @@ const Toolbar = ({ style={{ opacity: overlayOpacityAnimation.opacity }} >
-
- -
-
- -
-
- -
{currPhotoObj.photoDescription && ( -
- -
)}
-
- -
diff --git a/web/src/containers/views/view-screen-overlay/ActionsPanel/AudioButton.tsx b/web/src/containers/views/view-screen-overlay/ActionsPanel/AudioButton.tsx index a0e695c2..13c94b1f 100644 --- a/web/src/containers/views/view-screen-overlay/ActionsPanel/AudioButton.tsx +++ b/web/src/containers/views/view-screen-overlay/ActionsPanel/AudioButton.tsx @@ -3,7 +3,6 @@ import { useTranslation } from "react-i18next"; import { Button } from "components/button/button"; import { Icon } from "components/icon/icon"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import { RefCallback } from "context/tutorial-provider/use-tutorial"; @@ -25,28 +24,24 @@ const AudioButton = ({ const { openNewTopDialog } = useDialogRef(); return ( - <> -
+ -
- - - + + +
); }; diff --git a/web/src/containers/views/view-screen-overlay/ActionsPanel/EditorButton.tsx b/web/src/containers/views/view-screen-overlay/ActionsPanel/EditorButton.tsx index 1db703f8..125bce6d 100644 --- a/web/src/containers/views/view-screen-overlay/ActionsPanel/EditorButton.tsx +++ b/web/src/containers/views/view-screen-overlay/ActionsPanel/EditorButton.tsx @@ -2,7 +2,6 @@ import { useTranslation } from "react-i18next"; import { Button } from "components/button/button"; import { Icon } from "components/icon/icon"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import { RefCallback } from "context/tutorial-provider/use-tutorial"; @@ -24,25 +23,24 @@ const EditorButton = ({ const { t } = useTranslation("view-screen", { keyPrefix: "overlay" }); return ( - <> -
+ -
- - - + + +
); }; diff --git a/web/src/containers/views/view-screen-overlay/ActionsPanel/PlayButton.tsx b/web/src/containers/views/view-screen-overlay/ActionsPanel/PlayButton.tsx index 188df1a1..996edfd5 100644 --- a/web/src/containers/views/view-screen-overlay/ActionsPanel/PlayButton.tsx +++ b/web/src/containers/views/view-screen-overlay/ActionsPanel/PlayButton.tsx @@ -1,6 +1,5 @@ import { Button } from "components/button/button"; import { Icon } from "components/icon/icon"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import { RefCallback } from "context/tutorial-provider/use-tutorial"; @@ -27,27 +26,26 @@ const PlayButton = ({ const { t } = useTranslation("view-screen", { keyPrefix: "overlay" }); return ( - <> -
+ -
- - - + + +
); }; diff --git a/web/src/containers/views/view-screen-overlay/ActionsPanel/ReactivateTutorialButton.tsx b/web/src/containers/views/view-screen-overlay/ActionsPanel/ReactivateTutorialButton.tsx index 19e4fed3..3eb57ebf 100644 --- a/web/src/containers/views/view-screen-overlay/ActionsPanel/ReactivateTutorialButton.tsx +++ b/web/src/containers/views/view-screen-overlay/ActionsPanel/ReactivateTutorialButton.tsx @@ -2,7 +2,6 @@ import { useTranslation } from "react-i18next"; import { Button } from "components/button/button"; import { Icon } from "components/icon/icon"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import cx from "classnames"; import { RefCallback } from "context/tutorial-provider/use-tutorial"; @@ -23,25 +22,24 @@ const ReactivateTutorialButton = ({ const { t } = useTranslation("view-screen", { keyPrefix: "overlay" }); return ( - <> -
+ -
- - - + + + ); }; diff --git a/web/src/containers/views/view-screen-overlay/ActionsPanel/SettingsButton.tsx b/web/src/containers/views/view-screen-overlay/ActionsPanel/SettingsButton.tsx index 73cedc95..1c74786d 100644 --- a/web/src/containers/views/view-screen-overlay/ActionsPanel/SettingsButton.tsx +++ b/web/src/containers/views/view-screen-overlay/ActionsPanel/SettingsButton.tsx @@ -4,7 +4,6 @@ import { DialogRefType } from "context/dialog-ref-provider/dialog-ref-types"; import { Button } from "components/button/button"; import { Icon } from "components/icon/icon"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; import { RefCallback } from "context/tutorial-provider/use-tutorial"; @@ -25,28 +24,24 @@ const SettingsButton = ({ const { t } = useTranslation("view-screen", { keyPrefix: "overlay" }); return ( - <> -
+ -
- - - + + + ); }; From 912af6535860c49e9040066168f67a018183d631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n=20Svitek?= Date: Wed, 17 Jul 2024 17:01:42 +0200 Subject: [PATCH 3/9] Used custom icon component for permissions icon in LoginAppHeader component --- .../components/app-header/LoginAppHeader.tsx | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/web/src/components/app-header/LoginAppHeader.tsx b/web/src/components/app-header/LoginAppHeader.tsx index 785a1159..94eeff0e 100644 --- a/web/src/components/app-header/LoginAppHeader.tsx +++ b/web/src/components/app-header/LoginAppHeader.tsx @@ -12,8 +12,6 @@ import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { MdEdit } from "react-icons/md"; import { MdEditOff } from "react-icons/md"; -import { BasicTooltip } from "components/tooltip/BasicTooltip"; - // Models import { ActiveExpo, Screen } from "models"; import { AppDispatch } from "store/store"; @@ -24,6 +22,7 @@ import { signOut } from "actions/user-actions"; import { openInNewTab } from "utils"; import { mapScreenTypeValuesToKeys } from "enums/screen-type"; import { useActiveExpoAccess } from "context/active-expo-access-provider/active-expo-access-provider"; +import { Icon } from "components/icon/icon"; // - - @@ -117,25 +116,36 @@ const LoginAppHeader = ({
{isReadWriteAccess ? (
- + + } + tooltip={{ + id: "md-edit-on", + content: t("read-write-permission-tooltip"), + variant: "dark", + }} + />
) : (
- + + } + tooltip={{ + id: "md-edit-off", + content: t("read-only-permission-tooltip"), + variant: "dark", + }} + />
)}
- - - )} From f1705aa9cb53140ce6a1fec80fc802af89a2078d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n=20Svitek?= Date: Thu, 18 Jul 2024 12:25:15 +0200 Subject: [PATCH 4/9] Used prepared tooltip props on icon and button components instead of manual tooltip component --- .../dialogs/audio-dialog/audio-dialog.tsx | 18 ++----- .../share-expo-dialog/CopyClipboardBox.tsx | 29 +++++----- .../GlassMagnifierButton.tsx | 53 +++++++++---------- 3 files changed, 42 insertions(+), 58 deletions(-) diff --git a/web/src/components/dialogs/audio-dialog/audio-dialog.tsx b/web/src/components/dialogs/audio-dialog/audio-dialog.tsx index b0466891..deeadc2a 100644 --- a/web/src/components/dialogs/audio-dialog/audio-dialog.tsx +++ b/web/src/components/dialogs/audio-dialog/audio-dialog.tsx @@ -12,8 +12,6 @@ import { Icon } from "components/icon/icon"; import { Divider } from "components/divider/divider"; import { Slider } from "@mui/material"; -import { Tooltip } from "react-tooltip"; - // Actions import { setExpoVolumes, @@ -160,17 +158,12 @@ const AudioSlider = ({ }) ); }} + tooltip={{ + id: `tooltip-${volumeKey}`, + content: tooltipContent ?? "", + }} > -
- -
+
{volumeObj.actualVolume}
- ); }; diff --git a/web/src/components/dialogs/share-expo-dialog/CopyClipboardBox.tsx b/web/src/components/dialogs/share-expo-dialog/CopyClipboardBox.tsx index f8bfb542..8f36ef99 100644 --- a/web/src/components/dialogs/share-expo-dialog/CopyClipboardBox.tsx +++ b/web/src/components/dialogs/share-expo-dialog/CopyClipboardBox.tsx @@ -1,7 +1,6 @@ import { useMemo } from "react"; import Snackbar from "react-md/lib/Snackbars"; import CopyToClipboard from "react-copy-to-clipboard"; -import { Tooltip } from "react-tooltip"; import { Icon } from "components/icon/icon"; import { useBoolean } from "hooks/boolean-hook"; @@ -32,11 +31,7 @@ export const CopyClipboardBox = ({ {text} -
+
{ @@ -44,21 +39,21 @@ export const CopyClipboardBox = ({ onCopy?.(); }} > - +
- {tooltipText && ( - - )} - -
-
- -
- - } - /> +
+
+
- + + } + /> +
); }; From d61a647cfcefcc8dab56c701ed5a3e5ad60ff2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n=20Svitek?= Date: Thu, 18 Jul 2024 12:30:00 +0200 Subject: [PATCH 5/9] Disable tooltips on mobile --- web/src/components/tooltip/BasicTooltip.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web/src/components/tooltip/BasicTooltip.tsx b/web/src/components/tooltip/BasicTooltip.tsx index 5cb50e4e..5b0dc52d 100644 --- a/web/src/components/tooltip/BasicTooltip.tsx +++ b/web/src/components/tooltip/BasicTooltip.tsx @@ -1,6 +1,7 @@ import { Tooltip as ReactTooltip } from "react-tooltip"; import { useExpoDesignData } from "hooks/view-hooks/expo-design-data-hook"; import { BasicTooltipProps } from "./tooltip-props"; +import { useMediaDevice } from "context/media-device-provider/media-device-provider"; /** * Basic tooltip which listens to theme changes if variant is not overridden by prop @@ -13,6 +14,12 @@ export const BasicTooltip = ({ className, }: BasicTooltipProps) => { const { isLightMode } = useExpoDesignData(); + const { isMobile, isMobileLandscape } = useMediaDevice(); + + if (isMobile || isMobileLandscape) { + return null; + } + return ( Date: Thu, 18 Jul 2024 12:39:13 +0200 Subject: [PATCH 6/9] Use tutorial hook now accepts option argument --- .../containers/views/games/game-draw/game-draw.tsx | 7 +++---- .../containers/views/games/game-erase/game-erase.tsx | 7 +++---- .../containers/views/games/game-find/game-find.tsx | 7 +++---- .../containers/views/games/game-move/game-move.tsx | 2 +- .../containers/views/games/game-quiz/game-quiz.tsx | 7 +++---- .../views/games/game-sizing/game-sizing.tsx | 4 +++- .../views/view-image-change/view-image-change.tsx | 9 +++++---- .../views/view-screen-overlay/view-screen-overlay.tsx | 8 ++++---- web/src/context/tutorial-provider/use-tutorial.tsx | 11 ++++++++++- 9 files changed, 35 insertions(+), 27 deletions(-) diff --git a/web/src/containers/views/games/game-draw/game-draw.tsx b/web/src/containers/views/games/game-draw/game-draw.tsx index fecd3cd8..25771cfc 100644 --- a/web/src/containers/views/games/game-draw/game-draw.tsx +++ b/web/src/containers/views/games/game-draw/game-draw.tsx @@ -165,10 +165,9 @@ export const GameDraw = ({ // - - Tutorial stuff - - - const { bind, TutorialTooltip, escapeTutorial } = useTutorial( - "gameDraw", - !isMobileOverlay - ); + const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameDraw", { + shouldOpen: !isMobileOverlay, + }); const onKeydownAction = useCallback( (event) => { diff --git a/web/src/containers/views/games/game-erase/game-erase.tsx b/web/src/containers/views/games/game-erase/game-erase.tsx index 81f2cd65..f980e5ac 100644 --- a/web/src/containers/views/games/game-erase/game-erase.tsx +++ b/web/src/containers/views/games/game-erase/game-erase.tsx @@ -198,10 +198,9 @@ export const GameErase = ({ // - - - const { bind, TutorialTooltip, escapeTutorial } = useTutorial( - "gameWipe", - !isMobileOverlay - ); + const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameWipe", { + shouldOpen: !isMobileOverlay, + }); const onKeydownAction = useCallback( (event) => { diff --git a/web/src/containers/views/games/game-find/game-find.tsx b/web/src/containers/views/games/game-find/game-find.tsx index 81c9b79f..6eced3a0 100644 --- a/web/src/containers/views/games/game-find/game-find.tsx +++ b/web/src/containers/views/games/game-find/game-find.tsx @@ -68,10 +68,9 @@ export const GameFind = ({ // - const { bind, TutorialTooltip, escapeTutorial } = useTutorial( - "gameFind", - !isMobileOverlay - ); + const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameFind", { + shouldOpen: !isMobileOverlay, + }); const onKeydownAction = useCallback( (event) => { diff --git a/web/src/containers/views/games/game-move/game-move.tsx b/web/src/containers/views/games/game-move/game-move.tsx index baea9729..c0bce43c 100644 --- a/web/src/containers/views/games/game-move/game-move.tsx +++ b/web/src/containers/views/games/game-move/game-move.tsx @@ -96,7 +96,7 @@ export const GameMove = ({ bind: bindTutorial, TutorialTooltip, escapeTutorial, - } = useTutorial("gameMove", !isMobileOverlay); + } = useTutorial("gameMove", { shouldOpen: !isMobileOverlay }); const onKeydownAction = useCallback( (event) => { diff --git a/web/src/containers/views/games/game-quiz/game-quiz.tsx b/web/src/containers/views/games/game-quiz/game-quiz.tsx index 6f4fa64c..898a3b9f 100644 --- a/web/src/containers/views/games/game-quiz/game-quiz.tsx +++ b/web/src/containers/views/games/game-quiz/game-quiz.tsx @@ -76,10 +76,9 @@ export const GameQuiz = ({ // - - - const { bind, TutorialTooltip, escapeTutorial } = useTutorial( - "gameOptions", - !isMobileOverlay - ); + const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameOptions", { + shouldOpen: !isMobileOverlay, + }); const onKeydownAction = useCallback( (event: KeyboardEvent) => { diff --git a/web/src/containers/views/games/game-sizing/game-sizing.tsx b/web/src/containers/views/games/game-sizing/game-sizing.tsx index bb0bc028..7d517397 100644 --- a/web/src/containers/views/games/game-sizing/game-sizing.tsx +++ b/web/src/containers/views/games/game-sizing/game-sizing.tsx @@ -103,7 +103,9 @@ export const GameSizing = ({ bind: bindTutorial, TutorialTooltip, escapeTutorial, - } = useTutorial("gameSizing", !isMobileOverlay); + } = useTutorial("gameSizing", { + shouldOpen: !isMobileOverlay, + }); const onKeydownAction = useCallback( (event) => { diff --git a/web/src/containers/views/view-image-change/view-image-change.tsx b/web/src/containers/views/view-image-change/view-image-change.tsx index 0e5aba72..ee3dd18c 100644 --- a/web/src/containers/views/view-image-change/view-image-change.tsx +++ b/web/src/containers/views/view-image-change/view-image-change.tsx @@ -145,10 +145,11 @@ export const ViewImageChange = ({ screenPreloadedFiles }: ScreenProps) => { bind: bindTutorial, TutorialTooltip, isTutorialOpen, - } = useTutorial( - "screenChange", - animation !== "GRADUAL_TRANSITION" && animation !== "FADE_IN_OUT_TWO_IMAGES" - ); + } = useTutorial("screenChange", { + shouldOpen: + animation !== "GRADUAL_TRANSITION" && + animation !== "FADE_IN_OUT_TWO_IMAGES", + }); // - - - diff --git a/web/src/containers/views/view-screen-overlay/view-screen-overlay.tsx b/web/src/containers/views/view-screen-overlay/view-screen-overlay.tsx index 3be51530..25cb18ba 100644 --- a/web/src/containers/views/view-screen-overlay/view-screen-overlay.tsx +++ b/web/src/containers/views/view-screen-overlay/view-screen-overlay.tsx @@ -127,10 +127,10 @@ export const ViewScreenOverlay = ({ getTutorialEnhanceClassnameByStepkeys, reactivateTutorial, isTutorialCompleted, - } = useTutorial( - isMobileOverlay ? "mobile-overlay" : "overlay", - isOverlayActive === true && (isMobileOverlay ? true : !amIGameScreen) - ); + } = useTutorial(isMobileOverlay ? "mobile-overlay" : "overlay", { + shouldOpen: + isOverlayActive === true && (isMobileOverlay ? true : !amIGameScreen), + }); const isAnyTutorialOpen = useIsAnyTutorialOpened(); diff --git a/web/src/context/tutorial-provider/use-tutorial.tsx b/web/src/context/tutorial-provider/use-tutorial.tsx index 3c6d462c..98f25e42 100644 --- a/web/src/context/tutorial-provider/use-tutorial.tsx +++ b/web/src/context/tutorial-provider/use-tutorial.tsx @@ -17,7 +17,16 @@ export type RefCallback = (ref: HTMLElement | null) => void; // - - - - - - - - -export const useTutorial = (tutorialKey: TutorialKey, shouldOpen = true) => { +type UseTutorialOptions = { + shouldOpen?: boolean; +}; + +export const useTutorial = ( + tutorialKey: TutorialKey, + options?: UseTutorialOptions +) => { + const { shouldOpen = true } = options ?? {}; + // Whole object will all tutorials and their info + helper functions to manipulate with them const { store, From 758661a9a5145bdbab971b1900e3976587c66cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n=20Svitek?= Date: Thu, 18 Jul 2024 12:56:16 +0200 Subject: [PATCH 7/9] Game screens are now using closeOnEsc tutorial prop --- .../views/games/game-draw/game-draw.tsx | 17 ++------------ .../views/games/game-erase/game-erase.tsx | 17 ++------------ .../views/games/game-find/game-find.tsx | 19 +++------------ .../views/games/game-move/game-move.tsx | 23 ++++--------------- .../views/games/game-quiz/game-quiz.tsx | 6 ++--- .../views/games/game-sizing/game-sizing.tsx | 23 +++---------------- .../tutorial-provider/use-tutorial.tsx | 20 +++++++++++++++- 7 files changed, 36 insertions(+), 89 deletions(-) diff --git a/web/src/containers/views/games/game-draw/game-draw.tsx b/web/src/containers/views/games/game-draw/game-draw.tsx index 25771cfc..fc76a4c3 100644 --- a/web/src/containers/views/games/game-draw/game-draw.tsx +++ b/web/src/containers/views/games/game-draw/game-draw.tsx @@ -165,22 +165,9 @@ export const GameDraw = ({ // - - Tutorial stuff - - - const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameDraw", { + const { bind, TutorialTooltip } = useTutorial("gameDraw", { shouldOpen: !isMobileOverlay, - }); - - const onKeydownAction = useCallback( - (event) => { - if (event.key === "Escape") { - escapeTutorial(); - } - }, - [escapeTutorial] - ); - - useEffect(() => { - document.addEventListener("keydown", onKeydownAction); - return () => document.removeEventListener("keydown", onKeydownAction); + closeOnEsc: true, }); return ( diff --git a/web/src/containers/views/games/game-erase/game-erase.tsx b/web/src/containers/views/games/game-erase/game-erase.tsx index f980e5ac..3f91a944 100644 --- a/web/src/containers/views/games/game-erase/game-erase.tsx +++ b/web/src/containers/views/games/game-erase/game-erase.tsx @@ -198,22 +198,9 @@ export const GameErase = ({ // - - - const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameWipe", { + const { bind, TutorialTooltip } = useTutorial("gameWipe", { shouldOpen: !isMobileOverlay, - }); - - const onKeydownAction = useCallback( - (event) => { - if (event.key === "Escape") { - escapeTutorial(); - } - }, - [escapeTutorial] - ); - - useEffect(() => { - document.addEventListener("keydown", onKeydownAction); - return () => document.removeEventListener("keydown", onKeydownAction); + closeOnEsc: true, }); return ( diff --git a/web/src/containers/views/games/game-find/game-find.tsx b/web/src/containers/views/games/game-find/game-find.tsx index 6eced3a0..3bd364de 100644 --- a/web/src/containers/views/games/game-find/game-find.tsx +++ b/web/src/containers/views/games/game-find/game-find.tsx @@ -1,5 +1,5 @@ import ReactDOM from "react-dom"; -import { MouseEvent, useCallback, useEffect, useState } from "react"; +import { MouseEvent, useCallback, useState } from "react"; import { animated, useTransition } from "react-spring"; import { ScreenProps } from "models"; import cx from "classnames"; @@ -68,22 +68,9 @@ export const GameFind = ({ // - const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameFind", { + const { bind, TutorialTooltip } = useTutorial("gameFind", { shouldOpen: !isMobileOverlay, - }); - - const onKeydownAction = useCallback( - (event) => { - if (event.key === "Escape") { - escapeTutorial(); - } - }, - [escapeTutorial] - ); - - useEffect(() => { - document.addEventListener("keydown", onKeydownAction); - return () => document.removeEventListener("keydown", onKeydownAction); + closeOnEsc: true, }); return ( diff --git a/web/src/containers/views/games/game-move/game-move.tsx b/web/src/containers/views/games/game-move/game-move.tsx index c0bce43c..7f60707d 100644 --- a/web/src/containers/views/games/game-move/game-move.tsx +++ b/web/src/containers/views/games/game-move/game-move.tsx @@ -1,5 +1,5 @@ import ReactDOM from "react-dom"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useState } from "react"; import { useSelector } from "react-redux"; import { createSelector } from "reselect"; @@ -92,24 +92,9 @@ export const GameMove = ({ // - - - const { - bind: bindTutorial, - TutorialTooltip, - escapeTutorial, - } = useTutorial("gameMove", { shouldOpen: !isMobileOverlay }); - - const onKeydownAction = useCallback( - (event) => { - if (event.key === "Escape") { - escapeTutorial(); - } - }, - [escapeTutorial] - ); - - useEffect(() => { - document.addEventListener("keydown", onKeydownAction); - return () => document.removeEventListener("keydown", onKeydownAction); + const { bind: bindTutorial, TutorialTooltip } = useTutorial("gameMove", { + shouldOpen: !isMobileOverlay, + closeOnEsc: true, }); return ( diff --git a/web/src/containers/views/games/game-quiz/game-quiz.tsx b/web/src/containers/views/games/game-quiz/game-quiz.tsx index 898a3b9f..694f7e99 100644 --- a/web/src/containers/views/games/game-quiz/game-quiz.tsx +++ b/web/src/containers/views/games/game-quiz/game-quiz.tsx @@ -76,18 +76,18 @@ export const GameQuiz = ({ // - - - const { bind, TutorialTooltip, escapeTutorial } = useTutorial("gameOptions", { + const { bind, TutorialTooltip } = useTutorial("gameOptions", { shouldOpen: !isMobileOverlay, + closeOnEsc: true, }); const onKeydownAction = useCallback( (event: KeyboardEvent) => { if (event.key === "Escape") { closeAllInfopoints(viewScreen)(); - escapeTutorial(); } }, - [closeAllInfopoints, escapeTutorial, viewScreen] + [closeAllInfopoints, viewScreen] ); useEffect(() => { diff --git a/web/src/containers/views/games/game-sizing/game-sizing.tsx b/web/src/containers/views/games/game-sizing/game-sizing.tsx index 7d517397..a1e6596c 100644 --- a/web/src/containers/views/games/game-sizing/game-sizing.tsx +++ b/web/src/containers/views/games/game-sizing/game-sizing.tsx @@ -1,5 +1,5 @@ import ReactDOM from "react-dom"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useMemo, useState } from "react"; import { animated, useSpring, useTransition } from "react-spring"; import { createSelector } from "reselect"; import { useDrag } from "@use-gesture/react"; @@ -99,26 +99,9 @@ export const GameSizing = ({ // - - - const { - bind: bindTutorial, - TutorialTooltip, - escapeTutorial, - } = useTutorial("gameSizing", { + const { bind: bindTutorial, TutorialTooltip } = useTutorial("gameSizing", { shouldOpen: !isMobileOverlay, - }); - - const onKeydownAction = useCallback( - (event) => { - if (event.key === "Escape") { - escapeTutorial(); - } - }, - [escapeTutorial] - ); - - useEffect(() => { - document.addEventListener("keydown", onKeydownAction); - return () => document.removeEventListener("keydown", onKeydownAction); + closeOnEsc: true, }); return ( diff --git a/web/src/context/tutorial-provider/use-tutorial.tsx b/web/src/context/tutorial-provider/use-tutorial.tsx index 98f25e42..8c291d0d 100644 --- a/web/src/context/tutorial-provider/use-tutorial.tsx +++ b/web/src/context/tutorial-provider/use-tutorial.tsx @@ -19,13 +19,14 @@ export type RefCallback = (ref: HTMLElement | null) => void; type UseTutorialOptions = { shouldOpen?: boolean; + closeOnEsc?: boolean; }; export const useTutorial = ( tutorialKey: TutorialKey, options?: UseTutorialOptions ) => { - const { shouldOpen = true } = options ?? {}; + const { shouldOpen = true, closeOnEsc = false } = options ?? {}; // Whole object will all tutorials and their info + helper functions to manipulate with them const { @@ -233,6 +234,23 @@ export const useTutorial = ( [currStepObj?.stepKey, isTutorialOpen] ); + // - - + // Register escape tutorial on Esc button press + + const onKeydownAction = useCallback( + (event: KeyboardEvent) => { + if (event.key === "Escape" && closeOnEsc) { + escapeTutorial(); + } + }, + [closeOnEsc, escapeTutorial] + ); + + useEffect(() => { + document.addEventListener("keydown", onKeydownAction); + return () => document.removeEventListener("keydown", onKeydownAction); + }, [onKeydownAction]); + // - - // Returned object From 64de74f407851acc27d82e8989466ec37b051829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n=20Svitek?= Date: Thu, 18 Jul 2024 13:00:16 +0200 Subject: [PATCH 8/9] fix: Styling of permission icons in LoginAppHeader component --- .../components/app-header/LoginAppHeader.tsx | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/web/src/components/app-header/LoginAppHeader.tsx b/web/src/components/app-header/LoginAppHeader.tsx index 94eeff0e..b22c8334 100644 --- a/web/src/components/app-header/LoginAppHeader.tsx +++ b/web/src/components/app-header/LoginAppHeader.tsx @@ -9,9 +9,6 @@ import { IconButton, Menu, MenuItem } from "@mui/material"; import MenuIcon from "@mui/icons-material/Menu"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import { MdEdit } from "react-icons/md"; -import { MdEditOff } from "react-icons/md"; - // Models import { ActiveExpo, Screen } from "models"; import { AppDispatch } from "store/store"; @@ -115,12 +112,14 @@ const LoginAppHeader = ({
{isReadWriteAccess ? ( -
+
- } + name="edit-on" + style={{ + fontSize: "14px", + color: "#cccccc", + }} tooltip={{ id: "md-edit-on", content: t("read-write-permission-tooltip"), @@ -129,14 +128,14 @@ const LoginAppHeader = ({ />
) : ( -
+
- } + name="edit-off" + style={{ + fontSize: "14px", + color: "#cccccc", + }} tooltip={{ id: "md-edit-off", content: t("read-only-permission-tooltip"), From 969b7dc64894fc8c3e7076833525342e48e52927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mari=C3=A1n=20Svitek?= Date: Wed, 10 Jul 2024 15:33:51 +0200 Subject: [PATCH 9/9] Refactoring of glass magnifier hook for better readability --- .../glass-magnifier-hook/GlassMagnifier.tsx | 2 +- .../calculate-positions.ts | 4 +- .../glass-magnifier-hook.tsx | 147 ------------------ .../useGlassMagnifier.tsx | 147 +++++++++--------- 4 files changed, 79 insertions(+), 221 deletions(-) delete mode 100644 web/src/hooks/view-hooks/glass-magnifier-hook/glass-magnifier-hook.tsx diff --git a/web/src/hooks/view-hooks/glass-magnifier-hook/GlassMagnifier.tsx b/web/src/hooks/view-hooks/glass-magnifier-hook/GlassMagnifier.tsx index aa6e6c19..0476b8e9 100644 --- a/web/src/hooks/view-hooks/glass-magnifier-hook/GlassMagnifier.tsx +++ b/web/src/hooks/view-hooks/glass-magnifier-hook/GlassMagnifier.tsx @@ -6,10 +6,10 @@ import { Position } from "models"; // Thats why image container should be positioned relatively and this absolutel type GlassMagnifierProps = { + containedImgSrc: string | undefined; containedImgSize: { width: number; height: number }; cursorPosition: Position; targetPosition: Position; - containedImgSrc: string | undefined; lensContainerStyle?: React.CSSProperties; lensStyle?: React.CSSProperties; }; diff --git a/web/src/hooks/view-hooks/glass-magnifier-hook/calculate-positions.ts b/web/src/hooks/view-hooks/glass-magnifier-hook/calculate-positions.ts index 99483de8..ef9d209c 100644 --- a/web/src/hooks/view-hooks/glass-magnifier-hook/calculate-positions.ts +++ b/web/src/hooks/view-hooks/glass-magnifier-hook/calculate-positions.ts @@ -139,7 +139,7 @@ export const calculatePositions = ( return { containedImgSize, - newContainerCursorPosition, - newTargetPosition, + cursorPosition: newContainerCursorPosition, + targetPosition: newTargetPosition, }; }; diff --git a/web/src/hooks/view-hooks/glass-magnifier-hook/glass-magnifier-hook.tsx b/web/src/hooks/view-hooks/glass-magnifier-hook/glass-magnifier-hook.tsx deleted file mode 100644 index 84da7d59..00000000 --- a/web/src/hooks/view-hooks/glass-magnifier-hook/glass-magnifier-hook.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import { useState, useMemo, useEffect, useCallback } from "react"; -import { calculatePositions } from "./calculate-positions"; -import { useGlassMagnifierConfig } from "context/glass-magnifier-config-provider/glass-magnifier-config-provider"; -import GlassMagnifier from "./GlassMagnifier"; - -import { Position } from "models"; - -export const useGlassMagnifier = ( - imageContainerEl: HTMLDivElement | null, - containedImageEl: HTMLImageElement | null -) => { - const { isGlassMagnifierEnabled, glassMagnifierPxSize } = - useGlassMagnifierConfig(); - - // Cursor position (left and top from image container) - // Cursor is in the middle of the glass magnifier - const [cursorPosition, setCursorPosition] = useState({ - left: 0, - top: 0, - }); - - // Position (left and top) in the natural dimensions of contained img - const [targetPosition, setTargetPosition] = useState({ - left: 0, - top: 0, - }); - - const [containedImgSize, setContainedImgSize] = useState({ - width: 0, - height: 0, - }); - - const containedImgSrc = useMemo( - () => containedImageEl?.src, - [containedImageEl] - ); - - // - - - - // ImageContainerOnMouseMoveHandler - const imgContainerMouseMoveHandler = useCallback( - (event: globalThis.MouseEvent | globalThis.TouchEvent) => { - if (!isGlassMagnifierEnabled) { - return; - } - if (!imageContainerEl || !containedImageEl || !containedImgSrc) { - return; - } - - const { - containedImgSize, - newContainerCursorPosition, - newTargetPosition, - } = calculatePositions( - imageContainerEl, - containedImageEl, - event, - glassMagnifierPxSize - ); - - setContainedImgSize(containedImgSize); - setCursorPosition(newContainerCursorPosition); - setTargetPosition(newTargetPosition); - - return; - }, - [ - containedImageEl, - containedImgSrc, - glassMagnifierPxSize, - imageContainerEl, - isGlassMagnifierEnabled, - ] - ); - - // Apply the required styles for the imageContainer - useEffect(() => { - if (!imageContainerEl) { - return; - } - - imageContainerEl.style.position = "relative"; - imageContainerEl.style.overflow = "hidden"; - imageContainerEl.style.cursor = isGlassMagnifierEnabled ? "none" : "auto"; - imageContainerEl.style.touchAction = isGlassMagnifierEnabled - ? "none" // disable default browser touch actions such as scrolling, zooming, ... - : "auto"; - }, [imageContainerEl, isGlassMagnifierEnabled]); - - // Add the onMouseMove and touchStart handler for the imageContainer - useEffect(() => { - if (!imageContainerEl) { - return; - } - - imageContainerEl.addEventListener( - "mousemove", - imgContainerMouseMoveHandler - ); - - imageContainerEl.addEventListener( - "touchmove", - imgContainerMouseMoveHandler - ); - - return () => { - imageContainerEl.removeEventListener( - "mousemove", - imgContainerMouseMoveHandler - ); - - imageContainerEl.removeEventListener( - "touchmove", - imgContainerMouseMoveHandler - ); - }; - }, [imageContainerEl, imgContainerMouseMoveHandler]); - - // - - - - // Glass Magnifier component with current cursor positions - // Adding this component into viewScreen will render "lens" at the current cursor position - type CalculatedGlassMagnifierProps = { - lensContainerStyle?: React.CSSProperties; - lensStyle?: React.CSSProperties; - }; - - const CalculatedGlassMagnifier = ({ - lensContainerStyle, - lensStyle, - }: CalculatedGlassMagnifierProps) => { - return ( - - ); - }; - - return { - GlassMagnifier: CalculatedGlassMagnifier, - }; -}; diff --git a/web/src/hooks/view-hooks/glass-magnifier-hook/useGlassMagnifier.tsx b/web/src/hooks/view-hooks/glass-magnifier-hook/useGlassMagnifier.tsx index 14ef891d..9ad99d17 100644 --- a/web/src/hooks/view-hooks/glass-magnifier-hook/useGlassMagnifier.tsx +++ b/web/src/hooks/view-hooks/glass-magnifier-hook/useGlassMagnifier.tsx @@ -1,8 +1,16 @@ import { useState, useMemo, useEffect, useCallback } from "react"; -import { calculatePositions } from "./calculate-positions"; import { useGlassMagnifierConfig } from "context/glass-magnifier-config-provider/glass-magnifier-config-provider"; + import GlassMagnifier from "./GlassMagnifier"; -import { Position } from "models"; + +import { Position, Size } from "models"; +import { calculatePositions } from "./calculate-positions"; + +type PositionsInfoObj = { + containedImgSize: Size; + cursorPosition: Position; + targetPosition: Position; +}; export const useGlassMagnifier = ( imageContainerEl: HTMLDivElement | null, @@ -11,56 +19,45 @@ export const useGlassMagnifier = ( const { isGlassMagnifierEnabled, glassMagnifierPxSize } = useGlassMagnifierConfig(); - // Cursor position (left and top from image container) - // Cursor is in the middle of the glass magnifier - const [cursorPosition, setCursorPosition] = useState({ - left: 0, - top: 0, - }); - - // Position (left and top) in the natural dimensions of contained img - const [targetPosition, setTargetPosition] = useState({ - left: 0, - top: 0, - }); - - const [containedImgSize, setContainedImgSize] = useState({ - width: 0, - height: 0, - }); - const containedImgSrc = useMemo( () => containedImageEl?.src, [containedImageEl] ); - // - - - // ImageContainerOnMouseMoveHandler + const [positionsInfo, setPositionsInfo] = useState({ + // Size of the contained image + containedImgSize: { width: 0, height: 0 }, + + // Current position of the cursor relative to the image container (e.g. whole screen) + // Cursor is located in the middle of the glass magnifier and is not visible when glass magnifier is enabled + cursorPosition: { left: 0, top: 0 }, + + // Represents current position of the left-top corner of the lens -> relative to the natural dimensions of contained img + targetPosition: { left: 0, top: 0 }, + }); + + // - - - - - - - - - - - - + // Event Handlers + // - - - - - - - - - - - - + const imageContainerOnMouseMoveHandler = useCallback( (event: globalThis.MouseEvent | globalThis.TouchEvent) => { if (!isGlassMagnifierEnabled) { return; } + if (!imageContainerEl || !containedImageEl || !containedImgSrc) { return; } - const { - containedImgSize, - newContainerCursorPosition, - newTargetPosition, - } = calculatePositions( + const newPositionsInfo = calculatePositions( imageContainerEl, containedImageEl, event, glassMagnifierPxSize ); - setContainedImgSize(containedImgSize); - setCursorPosition(newContainerCursorPosition); - setTargetPosition(newTargetPosition); - - return; + setPositionsInfo(newPositionsInfo); }, [ containedImageEl, @@ -71,31 +68,23 @@ export const useGlassMagnifier = ( ] ); - // Disable default browser behavior, like saving image when long touch and other.. - // const imageContainerElOnTouchStart = useCallback( - // (e: TouchEvent) => { - // if (isGlassMagnifierEnabled) { - // e.preventDefault(); - // } - // }, - // [isGlassMagnifierEnabled] - // ); - - // Apply the required styles for the imageContainer - useEffect(() => { - if (!imageContainerEl) { - return; - } + // Handler responsible for disabling the default browser behavior, e.g. saving image pop-up when long touch + /* + const imageContainerOnTouchStart = useCallback( + (e: TouchEvent) => { + if (isGlassMagnifierEnabled) { + e.preventDefault(); + } + }, + [isGlassMagnifierEnabled] + ); + */ - imageContainerEl.style.position = "relative"; - imageContainerEl.style.overflow = "hidden"; - imageContainerEl.style.cursor = isGlassMagnifierEnabled ? "none" : "auto"; - imageContainerEl.style.touchAction = isGlassMagnifierEnabled - ? "none" // disable default browser touch actions such as scrolling, zooming, ... - : "auto"; - }, [imageContainerEl, isGlassMagnifierEnabled]); + // - - - - - - - - - - - - + // Effects + // - - - - - - - - - - - - - // Add the onMouseMove handler for the imageContainer + // Effect responsible for registration/unregistration of event handlers for imageContainer element useEffect(() => { if (!imageContainerEl) { return; @@ -105,37 +94,53 @@ export const useGlassMagnifier = ( imageContainerOnMouseMoveHandler ); - // imageContainerEl.addEventListener( - // "touchstart", - // imageContainerElOnTouchStart - // ); - imageContainerEl.addEventListener( "touchmove", imageContainerOnMouseMoveHandler ); + // imageContainerEl.addEventListener( + // "touchstart", + // imageContainerOnTouchStart + // ); + return () => { imageContainerEl.removeEventListener( "mousemove", imageContainerOnMouseMoveHandler ); - // imageContainerEl.removeEventListener( - // "touchstart", - // imageContainerElOnTouchStart - // ); - imageContainerEl.removeEventListener( "touchmove", imageContainerOnMouseMoveHandler ); + + // imageContainerEl.removeEventListener( + // "touchstart", + // imageContainerOnTouchStart + // ); }; }, [imageContainerEl, imageContainerOnMouseMoveHandler]); - // - - - // Glass Magnifier component with current cursor positions - // Adding this component into viewScreen will render "lens" at the current cursor position + // Effect responsible for applying all necessary styles for the imageContainer element + useEffect(() => { + if (!imageContainerEl) { + return; + } + + imageContainerEl.style.position = "relative"; + imageContainerEl.style.overflow = "hidden"; + imageContainerEl.style.cursor = isGlassMagnifierEnabled ? "none" : "auto"; + imageContainerEl.style.touchAction = isGlassMagnifierEnabled + ? "none" // disable default browser touch actions such as scrolling, zooming, ... + : "auto"; + }, [imageContainerEl, isGlassMagnifierEnabled]); + + // - - - - - - - - - - - - + // Prepared GlassMagnifier component + // - adding this component into viewScreen will render "glass magnifier lens" at the current cursor position + // - - - - - - - - - - - - + type CalculatedGlassMagnifierProps = { lensContainerStyle?: React.CSSProperties; lensStyle?: React.CSSProperties; @@ -147,10 +152,10 @@ export const useGlassMagnifier = ( }: CalculatedGlassMagnifierProps) => { return (