From 3397b34dccd5b9a952aa002f6b12bb9c1519ec1e Mon Sep 17 00:00:00 2001 From: Supra4E8C Date: Sun, 22 Feb 2026 12:37:20 +0800 Subject: [PATCH] fix(editing): narrow allowNextNavigation --- src/hooks/useUnsavedChangesGuard.ts | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/hooks/useUnsavedChangesGuard.ts b/src/hooks/useUnsavedChangesGuard.ts index 8a97508..d98ac09 100644 --- a/src/hooks/useUnsavedChangesGuard.ts +++ b/src/hooks/useUnsavedChangesGuard.ts @@ -24,20 +24,34 @@ export function useUnsavedChangesGuard(options: UseUnsavedChangesGuardOptions) { const { showConfirmation } = useNotificationStore(); const lastBlockedRef = useRef(''); const allowNextNavigationUntilRef = useRef(0); + const allowNextNavigationKeyRef = useRef(''); const location = useLocation(); const allowNextNavigation = useCallback(() => { - // Allow a short window for programmatic navigations after successful save. - // This avoids stale "allow" flags lingering when no navigation happens. + // Allow one programmatic navigation after successful save. + // A short window is used to avoid stale flags lingering when no navigation happens. allowNextNavigationUntilRef.current = Date.now() + 2_000; + allowNextNavigationKeyRef.current = ''; }, []); const shouldBlockFunction = useCallback( (args) => { if (!enabled) return false; - if (allowNextNavigationUntilRef.current > Date.now()) { - return false; + const now = Date.now(); + + if (allowNextNavigationUntilRef.current > now) { + const nextKey = `${args.nextLocation.pathname}${args.nextLocation.search}${args.nextLocation.hash}`; + if (!allowNextNavigationKeyRef.current) { + allowNextNavigationKeyRef.current = nextKey; + } + if (allowNextNavigationKeyRef.current === nextKey) { + return false; + } + } else if (allowNextNavigationUntilRef.current !== 0) { + allowNextNavigationUntilRef.current = 0; + allowNextNavigationKeyRef.current = ''; } + return typeof shouldBlock === 'function' ? shouldBlock(args) : shouldBlock; }, [enabled, shouldBlock] @@ -48,6 +62,7 @@ export function useUnsavedChangesGuard(options: UseUnsavedChangesGuardOptions) { useEffect(() => { if (allowNextNavigationUntilRef.current === 0) return; allowNextNavigationUntilRef.current = 0; + allowNextNavigationKeyRef.current = ''; }, [location.key]); const blockedKey = useMemo(() => {