1import type { NavigationState } from "@react-navigation/native";
2import { createContext, use, type ReactNode } from "react";
3import { Platform } from "react-native";
4import { androidWorkspaceSettingsOpen } from "./android-workspace-tabs";
5import { WorkspaceTabsProvider } from "./WorkspaceTabsContext";
6import { workspaceTabOf } from "./workspace-tabs-state";
7
8interface AndroidWorkspaceRoot {
9 /**
10 * The rail's `useNavigation()` dispatches to the focused navigator, which may be nested Settings.
11 * Target the root stack's key (and read `rootNavigationRef`'s state) so a tab press resets the root.
12 */
13 readonly key: string;
14 /** Settings is derived from navigation rather than kept in the tab reducer. */
15 readonly settingsOpen: boolean;
16 readonly settingsRoute: NavigationState["routes"][number] | undefined;
17 readonly settingsPage: string | null;
18}
19
20const AndroidWorkspaceRootContext = createContext<AndroidWorkspaceRoot | null>(null);
21
22export function useAndroidWorkspaceRoot() {
23 return use(AndroidWorkspaceRootContext);
24}
25
26/** Android keeps one tab controller above the root navigator and split sidebar. */
27export function AndroidWorkspaceTabsProvider(props: {
28 readonly state: NavigationState;
29 readonly children: ReactNode;
30}) {
31 const key = props.state.key;
32 const settingsOpen = Platform.OS === "android" && androidWorkspaceSettingsOpen(props.state);
33 const settingsIndex = props.state.routes.findIndex((route) => route.name === "Settings");
34 const settingsRoute = settingsIndex < 0 ? undefined : props.state.routes[settingsIndex];
35 const settingsPage =
36 settingsIndex < 0 ? null : (props.state.routes[settingsIndex + 1]?.name ?? null);
37 const root = { key, settingsOpen, settingsRoute, settingsPage };
38 return Platform.OS === "android" ? (
39 // A cold-start link lands on a page with no list selection; start on that page's list.
40 <WorkspaceTabsProvider
41 initialTab={workspaceTabOf(props.state.routes.find((route) => route.name !== "Home")?.name)}
42 >
43 <AndroidWorkspaceRootContext value={root}>{props.children}</AndroidWorkspaceRootContext>
44 </WorkspaceTabsProvider>
45 ) : (
46 props.children
47 );
48}