From d6fba3ad13d18e9402ab1cc5111b7e439531dc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Fri, 16 Aug 2024 17:41:51 +0200 Subject: [PATCH] DropdownMenu: close on navigation back, i don't understand this code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../dropdown-menu/dropdown-menu.tsx | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/components/dropdown-menu/dropdown-menu.tsx b/src/components/dropdown-menu/dropdown-menu.tsx index dec0a5960..8a2d0da4e 100644 --- a/src/components/dropdown-menu/dropdown-menu.tsx +++ b/src/components/dropdown-menu/dropdown-menu.tsx @@ -3,6 +3,7 @@ import clsx from 'clsx'; import { supportsPassiveEvents } from 'detect-passive-events'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import { FormattedMessage } from 'react-intl'; +import { useHistory } from 'react-router-dom'; import { closeDropdownMenu as closeDropdownMenuRedux, openDropdownMenu } from 'soapbox/actions/dropdown-menu'; import { useAppDispatch } from 'soapbox/hooks'; @@ -47,6 +48,7 @@ const DropdownMenu = (props: IDropdownMenu) => { } = props; const dispatch = useAppDispatch(); + const history = useHistory(); const [isOpen, setIsOpen] = useState(false); const [isDisplayed, setIsDisplayed] = useState(false); @@ -54,6 +56,8 @@ const DropdownMenu = (props: IDropdownMenu) => { const touching = userTouching.matches; const arrowRef = useRef(null); + const dropdownHistoryKey = useRef(); + const unlistenHistory = useRef>(); const { x, y, strategy, refs, middlewareData, placement } = useFloating({ placement: initialPlacement, @@ -97,9 +101,18 @@ const DropdownMenu = (props: IDropdownMenu) => { } }; - const handleClose = () => { + const handleClose = (goBack: any = true) => { (refs.reference.current as HTMLButtonElement)?.focus(); + if (unlistenHistory.current) { + unlistenHistory.current(); + unlistenHistory.current = undefined; + } + const { state } = history.location; + if (goBack && state && (state as any).soapboxDropdownKey === dropdownHistoryKey.current) { + history.goBack(); + } + closeDropdownMenu(); setIsOpen(false); @@ -221,6 +234,22 @@ const DropdownMenu = (props: IDropdownMenu) => { useEffect(() => { setTimeout(() => setIsDisplayed(isOpen), isOpen ? 0 : 150); + + if (isOpen && touching) { + const { pathname, state } = history.location; + + dropdownHistoryKey.current = Date.now(); + + history.push(pathname, { ...(state as any), soapboxDropdownKey: dropdownHistoryKey.current }); + + unlistenHistory.current = history.listen(({ state }, action) => { + if (!(state as any)?.soapboxModalKey) { + handleClose(); + } else if (action === 'POP') { + handleClose(false); + } + }); + } }, [isOpen]); if (items?.length === 0 && !Component) { @@ -284,7 +313,6 @@ const DropdownMenu = (props: IDropdownMenu) => { 'opacity-60': (isOpen && isDisplayed), })} role='button' - onClick={handleClose} /> )}