From fde08cd55c9d7f141d02afd7fc4b2211c52fff81 Mon Sep 17 00:00:00 2001 From: ciregenz Date: Fri, 26 Jun 2026 04:40:50 -0700 Subject: [PATCH] [eric] browser: derive active dashboardId synchronously from route so a switched-away browser parks instantly (no 1-frame bleed) --- .../src/shared/hooks/useLastDashboardId.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/frontend/src/shared/hooks/useLastDashboardId.ts b/frontend/src/shared/hooks/useLastDashboardId.ts index da83eb63..287129b9 100644 --- a/frontend/src/shared/hooks/useLastDashboardId.ts +++ b/frontend/src/shared/hooks/useLastDashboardId.ts @@ -15,17 +15,20 @@ export function useLastDashboardId(): [string | null, (id: string | null) => voi } }); - // Watch URL; update sticky id on /dashboard/:id. Do NOT clear when URL stops matching. + // The id from the CURRENT url, read synchronously in render: a dashboard switch must update dashboardId on the SAME render the route changes. Deferring it to the effect below left a one-frame window where the OLD dashboard was still the active id, so a kept-alive browser card from it flashed onto the new dashboard before parking off-screen (the cross-dashboard bleed). + const routeId = location.pathname.match(/^\/dashboard\/([^/]+)/)?.[1] ?? null; + const effectiveId = routeId ?? lastId; + + // Persist the route id so it stays sticky when the url stops matching a dashboard (settings etc.). Do NOT clear when it stops matching. useEffect(() => { - const match = location.pathname.match(/^\/dashboard\/([^/]+)/); - if (match && match[1] && match[1] !== lastId) { - setLastIdState(match[1]); + if (routeId && routeId !== lastId) { + setLastIdState(routeId); try { - localStorage.setItem(STORAGE_KEY, match[1]); + localStorage.setItem(STORAGE_KEY, routeId); } catch {} - setLastDashboardId(match[1]); + setLastDashboardId(routeId); } - }, [location.pathname, lastId]); + }, [routeId, lastId]); const setLastId = useCallback((id: string | null) => { setLastIdState(id); @@ -39,5 +42,5 @@ export function useLastDashboardId(): [string | null, (id: string | null) => voi setLastDashboardId(id); }, []); - return [lastId, setLastId]; + return [effectiveId, setLastId]; }