From 4c88f90a15107e126d6749a57f9101275be3fa9f Mon Sep 17 00:00:00 2001 From: asharonbaltazar <58940073+asharonbaltazar@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:49:49 -0500 Subject: [PATCH] feat(ui): disable menu buttons with `locked` param (#1332) * feat: add lock icon when param `locked=true` * chore: move `isViewLocked` logic up the component tree * chore: remove extra container from lock icon * chore: move fading logic into separate hook * chore: move locked icon into separate component * chore: rename variables --- .../navigation-menu/FloatingNavigation.tsx | 29 ++--------------- .../NavigationMenu.module.scss | 10 ++++++ .../navigation-menu/ViewLockedIcon.tsx | 15 +++++++++ .../navigation-menu/ViewNavigationMenu.tsx | 9 ++++++ .../common/hooks/useFadeOutOnInactivity.tsx | 31 +++++++++++++++++++ 5 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 apps/client/src/common/components/navigation-menu/ViewLockedIcon.tsx create mode 100644 apps/client/src/common/hooks/useFadeOutOnInactivity.tsx diff --git a/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx b/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx index a4b692a9c..026c7a76d 100644 --- a/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx +++ b/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx @@ -1,8 +1,7 @@ -import { useEffect, useState } from 'react'; import { IoApps } from '@react-icons/all-files/io5/IoApps'; import { IoSettingsOutline } from '@react-icons/all-files/io5/IoSettingsOutline'; -import { debounce } from '../../utils/debounce'; +import { useFadeOutOnInactivity } from '../../../common/hooks/useFadeOutOnInactivity'; import style from './NavigationMenu.module.scss'; @@ -13,32 +12,10 @@ interface FloatingNavigationProps { export default function FloatingNavigation(props: FloatingNavigationProps) { const { toggleMenu, toggleSettings } = props; - const [showButton, setShowButton] = useState(false); - - // show on mouse move - useEffect(() => { - let fadeOut: NodeJS.Timeout | null = null; - const setShowMenuTrue = () => { - setShowButton(true); - if (fadeOut) { - clearTimeout(fadeOut); - } - fadeOut = setTimeout(() => setShowButton(false), 3000); - }; - - const debouncedShowMenu = debounce(setShowMenuTrue, 1000); - - document.addEventListener('mousemove', debouncedShowMenu); - return () => { - document.removeEventListener('mousemove', debouncedShowMenu); - if (fadeOut) { - clearTimeout(fadeOut); - } - }; - }, []); + const isButtonShown = useFadeOutOnInactivity(); return ( -
+
+ ); +} diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx index 3cb203ac4..021d2aaf1 100644 --- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx @@ -2,13 +2,18 @@ import { memo, useCallback } from 'react'; import { useSearchParams } from 'react-router-dom'; import { useDisclosure } from '@chakra-ui/react'; +import { isStringBoolean } from '../../../features/viewers/common/viewUtils'; + import FloatingNavigation from './FloatingNavigation'; import NavigationMenu from './NavigationMenu'; +import ViewLockedIcon from './ViewLockedIcon'; function ViewNavigationMenu() { const [searchParams, setSearchParams] = useSearchParams(); const { isOpen: isMenuOpen, onOpen: onMenuOpen, onClose: onMenuClose } = useDisclosure(); + const isViewLocked = isStringBoolean(searchParams.get('locked')); + const showEditFormDrawer = useCallback(() => { searchParams.set('edit', 'true'); setSearchParams(searchParams); @@ -16,6 +21,10 @@ function ViewNavigationMenu() { const toggleMenu = () => (isMenuOpen ? onMenuClose() : onMenuOpen()); + if (isViewLocked) { + return ; + } + return ( <> diff --git a/apps/client/src/common/hooks/useFadeOutOnInactivity.tsx b/apps/client/src/common/hooks/useFadeOutOnInactivity.tsx new file mode 100644 index 000000000..44e589245 --- /dev/null +++ b/apps/client/src/common/hooks/useFadeOutOnInactivity.tsx @@ -0,0 +1,31 @@ +import { useEffect, useState } from 'react'; + +import { debounce } from '../../common/utils/debounce'; + +export const useFadeOutOnInactivity = () => { + const [isMouseMoved, setIsMouseMoved] = useState(false); + + // show on mouse move + useEffect(() => { + let fadeOut: NodeJS.Timeout | null = null; + const setShowMenuTrue = () => { + setIsMouseMoved(true); + if (fadeOut) { + clearTimeout(fadeOut); + } + fadeOut = setTimeout(() => setIsMouseMoved(false), 3000); + }; + + const debouncedShowMenu = debounce(setShowMenuTrue, 1000); + + document.addEventListener('mousemove', debouncedShowMenu); + return () => { + document.removeEventListener('mousemove', debouncedShowMenu); + if (fadeOut) { + clearTimeout(fadeOut); + } + }; + }, []); + + return isMouseMoved; +};