From 71ced2577d76448626db71606fb96e443074eaff Mon Sep 17 00:00:00 2001 From: pyshx Date: Tue, 14 Nov 2023 13:22:34 +0530 Subject: [PATCH] chore(web): move doubleClick with debounce to utils --- .../tabs/map/BottomPanel/LayerStyleCard.tsx | 37 +++++-------------- .../tabs/map/LeftPanel/Layers/LayerItem.tsx | 28 ++++---------- web/src/beta/utils/use-double-click.ts | 33 +++++++++++++++++ 3 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 web/src/beta/utils/use-double-click.ts diff --git a/web/src/beta/features/Editor/tabs/map/BottomPanel/LayerStyleCard.tsx b/web/src/beta/features/Editor/tabs/map/BottomPanel/LayerStyleCard.tsx index 1202db753e..a5c44ddd23 100644 --- a/web/src/beta/features/Editor/tabs/map/BottomPanel/LayerStyleCard.tsx +++ b/web/src/beta/features/Editor/tabs/map/BottomPanel/LayerStyleCard.tsx @@ -1,10 +1,11 @@ -import { ReactNode, useCallback, useRef, useState } from "react"; +import { ReactNode, useCallback, useState } from "react"; import TextInput from "@reearth/beta/components/fields/common/TextInput"; import Icon from "@reearth/beta/components/Icon"; import * as Popover from "@reearth/beta/components/Popover"; import Text from "@reearth/beta/components/Text"; import type { LayerStyleNameUpdateProps } from "@reearth/beta/features/Editor/useLayerStyles"; +import useDoubleClick from "@reearth/beta/utils/use-double-click"; import { styled } from "@reearth/services/theme"; type Props = { @@ -32,31 +33,11 @@ const LayerStyleCard: React.FC = ({ const [isHovered, setIsHovered] = useState(false); const [isEditing, setIsEditing] = useState(false); const [newName, setNewName] = useState(name); - const clickTimeoutRef = useRef(); - const clickedNameCount = useRef(0); - - const handleClick = useCallback(() => { - console.log(clickedNameCount.current); - if (clickTimeoutRef.current) { - clearTimeout(clickTimeoutRef.current); - } - clickTimeoutRef.current = setTimeout(() => { - clickedNameCount.current = 0; - onSelect?.(!selected); - }, 100); - }, [onSelect, selected]); - - const handleNameClick = useCallback(() => { - const newClickCount = clickedNameCount.current + 1; - console.log(newClickCount); - clickedNameCount.current = newClickCount; - // if (clickTimeoutRef.current) { - // clearTimeout(clickTimeoutRef.current); - // } - if (clickedNameCount.current === 2) { - setIsEditing(true); - } - }, []); + + const [handleSingleClick, handleDoubleClick] = useDoubleClick( + () => onSelect?.(!selected), + () => setIsEditing(true), + ); const handleMouseEnter = useCallback(() => { setIsHovered(true); @@ -100,7 +81,7 @@ const LayerStyleCard: React.FC = ({ @@ -129,7 +110,7 @@ const LayerStyleCard: React.FC = ({ onExit={handleEditExit} /> ) : ( - + {name} )} diff --git a/web/src/beta/features/Editor/tabs/map/LeftPanel/Layers/LayerItem.tsx b/web/src/beta/features/Editor/tabs/map/LeftPanel/Layers/LayerItem.tsx index be99dfb256..2c6c2190b9 100644 --- a/web/src/beta/features/Editor/tabs/map/LeftPanel/Layers/LayerItem.tsx +++ b/web/src/beta/features/Editor/tabs/map/LeftPanel/Layers/LayerItem.tsx @@ -8,6 +8,7 @@ import type { LayerNameUpdateProps, LayerVisibilityUpdateProps, } from "@reearth/beta/features/Editor/useLayers"; +import useDoubleClick from "@reearth/beta/utils/use-double-click"; import { styled } from "@reearth/services/theme"; type LayerItemProps = { @@ -36,28 +37,13 @@ const LayerItem = ({ const [newValue, setNewValue] = useState(layerTitle); const [isVisible, setIsVisible] = useState(visible); const [value, setValue] = useState(isVisible ? "V" : ""); - const [clickTimeoutId, setClickTimeoutId] = useState(null); const handleActionMenuToggle = useCallback(() => setActionOpen(prev => !prev), []); - const handleClick = useCallback(() => { - if (clickTimeoutId) { - clearTimeout(clickTimeoutId); - setClickTimeoutId(null); - } - const timeoutId = setTimeout(() => { - onSelect(); - }, 200); - setClickTimeoutId(timeoutId); - }, [onSelect, clickTimeoutId]); - - const handleLayerTitleClick = useCallback(() => { - if (clickTimeoutId) { - clearTimeout(clickTimeoutId); - setClickTimeoutId(null); - } - setIsEditing(true); - }, [clickTimeoutId]); + const [handleSingleClick, handleDoubleClick] = useDoubleClick( + () => onSelect?.(), + () => setIsEditing(true), + ); const handleChange = useCallback((newTitle: string) => setNewValue(newTitle), []); @@ -96,7 +82,7 @@ const LayerItem = ({ isSelected={isSelected} isOpenAction={isActionOpen} actionPlacement="bottom-end" - onItemClick={handleClick} + onItemClick={handleSingleClick} onActionClick={handleActionMenuToggle} onOpenChange={isOpen => setActionOpen(!!isOpen)} actionContent={ @@ -122,7 +108,7 @@ const LayerItem = ({ onBlur={handleEditExit} /> ) : ( - {layerTitle} + {layerTitle} )} {value} diff --git a/web/src/beta/utils/use-double-click.ts b/web/src/beta/utils/use-double-click.ts new file mode 100644 index 0000000000..636ab85fa9 --- /dev/null +++ b/web/src/beta/utils/use-double-click.ts @@ -0,0 +1,33 @@ +import { useCallback, useRef } from "react"; + +const useDoubleClick = ( + onClick: (() => void) | undefined, + onDoubleClick: (() => void) | undefined, + delay = 200, +): [() => void, () => void] => { + const timerRef = useRef(null); + + const singleClickHandler = useCallback(() => { + if (timerRef.current) { + clearTimeout(timerRef.current); + timerRef.current = null; + } else if (onClick) { + timerRef.current = setTimeout(() => { + onClick(); + timerRef.current = null; + }, delay); + } + }, [onClick, delay]); + + const doubleClickHandler = useCallback(() => { + if (timerRef.current) { + clearTimeout(timerRef.current); + timerRef.current = null; + } + onDoubleClick?.(); + }, [onDoubleClick]); + + return [singleClickHandler, doubleClickHandler]; +}; + +export default useDoubleClick;