diff --git a/web/src/components/mobile/MobilePage.tsx b/web/src/components/mobile/MobilePage.tsx index 8330f0a64d..524e0839cd 100644 --- a/web/src/components/mobile/MobilePage.tsx +++ b/web/src/components/mobile/MobilePage.tsx @@ -1,4 +1,10 @@ -import { createContext, useContext, useEffect, useState } from "react"; +import { + createContext, + useContext, + useEffect, + useState, + useCallback, +} from "react"; import { createPortal } from "react-dom"; import { motion, AnimatePresence } from "framer-motion"; import { IoMdArrowRoundBack } from "react-icons/io"; @@ -6,6 +12,7 @@ import { cn } from "@/lib/utils"; import { isPWA } from "@/utils/isPWA"; import { Button } from "@/components/ui/button"; import { useTranslation } from "react-i18next"; +import { useLocation } from "react-router-dom"; const MobilePageContext = createContext<{ open: boolean; @@ -24,15 +31,47 @@ export function MobilePage({ onOpenChange, }: MobilePageProps) { const [uncontrolledOpen, setUncontrolledOpen] = useState(false); + const location = useLocation(); const open = controlledOpen ?? uncontrolledOpen; - const setOpen = (value: boolean) => { - if (onOpenChange) { - onOpenChange(value); - } else { - setUncontrolledOpen(value); + const setOpen = useCallback( + (value: boolean) => { + if (onOpenChange) { + onOpenChange(value); + } else { + setUncontrolledOpen(value); + } + }, + [onOpenChange, setUncontrolledOpen], + ); + + useEffect(() => { + let isActive = true; + + if (open && isActive) { + window.history.pushState({ isMobilePage: true }, "", location.pathname); } - }; + + const handlePopState = (event: PopStateEvent) => { + if (open && isActive) { + event.preventDefault(); + setOpen(false); + // Delay replaceState to ensure state updates are processed + setTimeout(() => { + if (isActive) { + window.history.replaceState(null, "", location.pathname); + } + }, 0); + } + }; + + window.addEventListener("popstate", handlePopState); + + return () => { + isActive = false; + window.removeEventListener("popstate", handlePopState); + }; + }, [open, setOpen, location.pathname]); return (