fix(nav): Back steps through sub-views and closes modals before leaving a page

In-app history only tracked the top-level page, so Back from a module sub-view
(e.g. a Messages thread) or with a modal open jumped straight to the previous
module. Add two history primitives: useHistorySubview (a module's sub-view rides
in history.state, so Back returns to its root first) and useBackToClose (a
mounted overlay occupies one history entry; Back closes the topmost, nesting-safe
so a button-close doesn't trip the modals underneath). Apply to the Messages page
views and to PlayerModal + the shared Modal. setPage now pushes a clean entry so
each page starts at its root.
This commit is contained in:
npeter83 2026-06-26 01:37:43 +02:00
parent ad77a1751e
commit 71f79fc73d
5 changed files with 93 additions and 6 deletions

View file

@ -1,6 +1,7 @@
import { useEffect, useRef, type ReactNode } from "react";
import { createPortal } from "react-dom";
import { X } from "lucide-react";
import { useBackToClose } from "../lib/history";
// Stack of open modals so ESC only closes the topmost one — e.g. an error dialog over the
// tag editor: pressing ESC dismisses just the error and returns to the editor underneath.
@ -19,6 +20,9 @@ export default function Modal({
children: ReactNode;
maxWidth?: string;
}) {
// Browser/mouse Back closes the topmost modal instead of navigating away.
useBackToClose(onClose);
// Keep a stable handler across renders so the stack id is assigned once per mount.
const onCloseRef = useRef(onClose);
onCloseRef.current = onClose;