fix(app): gate open-intent consumption on navigation readiness

After moving host routes outside Stack.Protected, the workspace layout
could mount before the root navigator was ready. router.replace() would
silently fail, but consumedIntentRef was already set, preventing retries.
Gate the effect on rootNavigationState.key so the intent is only consumed
once Expo Router can actually process the replace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mohamed Boudra
2026-04-11 09:33:19 +00:00
parent 68c245c2d0
commit 86d812418e

View File

@@ -1,5 +1,10 @@
import { useEffect, useRef } from "react";
import { useGlobalSearchParams, useLocalSearchParams, useRouter } from "expo-router";
import {
useGlobalSearchParams,
useLocalSearchParams,
useRootNavigationState,
useRouter,
} from "expo-router";
import type { WorkspaceTabTarget } from "@/stores/workspace-tabs-store";
import { WorkspaceScreen } from "@/screens/workspace/workspace-screen";
import {
@@ -36,6 +41,7 @@ function getOpenIntentTarget(openIntent: WorkspaceOpenIntent): WorkspaceTabTarge
export default function HostWorkspaceLayout() {
const router = useRouter();
const rootNavigationState = useRootNavigationState();
const consumedIntentRef = useRef<string | null>(null);
const params = useLocalSearchParams<{
serverId?: string | string[];
@@ -55,6 +61,9 @@ export default function HostWorkspaceLayout() {
if (!openValue) {
return;
}
if (!rootNavigationState?.key) {
return;
}
const consumptionKey = `${serverId}:${workspaceId}:${openValue}`;
if (consumedIntentRef.current === consumptionKey) {
@@ -73,7 +82,7 @@ export default function HostWorkspaceLayout() {
: buildHostWorkspaceRoute(serverId, workspaceId);
router.replace(route as any);
}, [openValue, router, serverId, workspaceId]);
}, [openValue, rootNavigationState?.key, router, serverId, workspaceId]);
if (openValue) {
return null;