@@ -9,9 +9,12 @@ import { GestureHandlerRootView } from "react-native-gesture-handler";
99import { KeyboardProvider } from "react-native-keyboard-controller" ;
1010import { SafeAreaProvider } from "react-native-safe-area-context" ;
1111import {
12+ CommonActions ,
13+ createPathConfigForStaticNavigation ,
1214 createStaticNavigation ,
1315 getActionFromState ,
1416 getStateFromPath ,
17+ type NavigationAction ,
1518 type NavigationState ,
1619} from "@react-navigation/native" ;
1720
@@ -21,12 +24,24 @@ import { ThreadArrangementHost } from "./features/threads/ThreadArrangementSheet
2124import * as Dialog from "./components/ui/Dialog" ;
2225import { CloudAuthProvider } from "./features/cloud/CloudAuthProvider" ;
2326import { prepareNativeShowcaseCapture } from "./features/showcase/nativeShowcaseScene" ;
24- import { IncomingShareProvider } from "./features/sharing/IncomingShareProvider" ;
27+ import {
28+ presentPendingIncomingShare ,
29+ startIncomingShareInbox ,
30+ } from "./features/sharing/IncomingShareProvider" ;
31+ import {
32+ installAgentNotificationNavigation ,
33+ setAgentNotificationPathname ,
34+ } from "./features/agent-awareness/notificationNavigation" ;
35+ import {
36+ installAppShortcuts ,
37+ recordAppShortcutNavigationState ,
38+ } from "./features/shortcuts/appShortcutsRuntime" ;
2539import {
2640 AppearancePreferencesProvider ,
41+ installAppearanceRuntime ,
2742 useAppearancePreferences ,
2843} from "./features/settings/appearance/AppearancePreferencesProvider" ;
29- import { RootStack } from "./Stack" ;
44+ import { RootStack , workspaceLocationFromState } from "./Stack" ;
3045import { appAtomRegistry } from "./state/atom-registry" ;
3146import { subscribeComposerDraftModelReconciliation } from "./state/use-composer-drafts" ;
3247import { environmentThreadShells } from "./state/threads" ;
@@ -53,7 +68,12 @@ import {
5368} from "./features/workspace/workspace-selection-store" ;
5469import { workspaceDetailLinkAction } from "./features/workspace/workspace-detail-selection" ;
5570import { NativeLayoutMetricsProvider } from "./native/native-layout-metrics" ;
56- import { attachRootNavigation , rootNavigationRef } from "./lib/rootNavigation" ;
71+ import {
72+ attachRootNavigation ,
73+ flushRootNavigationQueue ,
74+ linkToRootPath ,
75+ rootNavigationRef ,
76+ } from "./lib/rootNavigation" ;
5777import { pruneNewTaskBranchCheckouts } from "./features/threads/NewTaskDraftRouteScreen" ;
5878
5979import "../global.css" ;
@@ -65,6 +85,20 @@ if (process.env.EXPO_PUBLIC_SHOWCASE === "1") {
6585void SplashScreen . preventAutoHideAsync ( ) . catch ( ( ) => { } ) ;
6686void hydrateWorkspaceSelections ( ) ;
6787
88+ const linkingConfig = {
89+ initialRouteName : "Home" ,
90+ screens : createPathConfigForStaticNavigation ( RootStack , { initialRouteName : "Home" } ) ?? { } ,
91+ } as const ;
92+
93+ function getAppStateFromPath ( path : string , options : Parameters < typeof getStateFromPath > [ 1 ] ) {
94+ return takeScheduledTaskNewLink (
95+ restoreSettingsLinkState (
96+ restoreDraftLinkState ( getStateFromPath ( path , options ) , path ) ,
97+ settingsLinkPage ( ) ,
98+ ) ,
99+ ) ;
100+ }
101+
68102const appLinking = {
69103 prefixes : [ Linking . createURL ( "/" ) , "t3code://" , "t3code-dev://" , "t3code-preview://" ] ,
70104 config : { initialRouteName : "Home" } ,
@@ -77,24 +111,33 @@ const appLinking = {
77111 // Our router handles the selection; React Navigation's type only lists its own actions.
78112 ( workspaceDetailLinkAction ( state ) as ReturnType < typeof getActionFromState > ) ??
79113 getActionFromState ( state , options ) ,
80- getStateFromPath : ( path : string , options : Parameters < typeof getStateFromPath > [ 1 ] ) =>
81- takeScheduledTaskNewLink (
82- restoreSettingsLinkState (
83- restoreDraftLinkState ( getStateFromPath ( path , options ) , path ) ,
84- settingsLinkPage ( ) ,
85- ) ,
86- ) ,
114+ getStateFromPath : getAppStateFromPath ,
87115} ;
88116
117+ function appLinkAction ( href : string ) : NavigationAction {
118+ const state = getAppStateFromPath ( href , linkingConfig ) ;
119+ if ( ! state ) throw new Error ( `Failed to parse the href to a navigation state (${ href } ).` ) ;
120+ return appLinking . getActionFromState ( state , linkingConfig ) ?? CommonActions . reset ( state ) ;
121+ }
122+
123+ function linkToAppPath ( href : string ) : void {
124+ linkToRootPath ( href , appLinkAction ) ;
125+ }
126+
89127const Navigation = createStaticNavigation ( RootStack ) ;
90128
91129function handleNavigationStateChange ( state : NavigationState | undefined ) : void {
92130 recordWorkspaceSelections ( state ) ;
93- if ( state ) pruneNewTaskBranchCheckouts ( state ) ;
131+ presentPendingIncomingShare ( ) ;
132+ if ( ! state ) return ;
133+ setAgentNotificationPathname ( workspaceLocationFromState ( state ) . pathname ) ;
134+ recordAppShortcutNavigationState ( state ) ;
135+ pruneNewTaskBranchCheckouts ( state ) ;
94136}
95137
96138function handleNavigationReady ( ) : void {
97139 handleNavigationStateChange ( rootNavigationRef . getRootState ( ) ) ;
140+ flushRootNavigationQueue ( ) ;
98141}
99142
100143declare const module : { readonly hot ?: FoundationHotModule } | undefined ;
@@ -107,10 +150,14 @@ const appServiceDisposers = [
107150 threadRefsAtom : environmentThreadShells . threadRefsAtom ,
108151 shellStateAtom : environmentShell . stateAtom ,
109152 } ) ,
153+ installAppearanceRuntime ( ) ,
110154 installSubscriptionUsageRefresh ( ) ,
111155 installPermissionUpdateNotice ( ) ,
112156 installThreadOutboxDelivery ( ) ,
113157 installComposerAttachmentUploads ( ) ,
158+ startIncomingShareInbox ( ) ,
159+ installAgentNotificationNavigation ( linkToAppPath ) ,
160+ installAppShortcuts ( linkToAppPath ) ,
114161] ;
115162disposeOnFoundationReplace ( typeof module === "undefined" ? undefined : module . hot , ( ) => {
116163 for ( const dispose of appServiceDisposers ) dispose ( ) ;
@@ -153,15 +200,13 @@ function AppContent() {
153200 { /* native-stack needs the theme's dark flag to select dark native headers. */ }
154201 < GlobalVoiceInputControl >
155202 < NativeLayoutMetricsProvider >
156- < IncomingShareProvider >
157- < Navigation
158- ref = { attachRootNavigation }
159- linking = { appLinking }
160- onReady = { handleNavigationReady }
161- theme = { navigationTheme }
162- onStateChange = { handleNavigationStateChange }
163- />
164- </ IncomingShareProvider >
203+ < Navigation
204+ ref = { attachRootNavigation }
205+ linking = { appLinking }
206+ onReady = { handleNavigationReady }
207+ theme = { navigationTheme }
208+ onStateChange = { handleNavigationStateChange }
209+ />
165210 < Dialog . Host />
166211 < ThreadArrangementHost />
167212 < ProjectChipIconRasterizer />
0 commit comments