import { NavigationContainer } from '@react-native-bedrock/native/@react-navigation/native'; import { useMemo, type ComponentProps, type ComponentType, type PropsWithChildren } from 'react'; import { getSchemeUri } from '../../native-modules'; import { BedrockStack } from '../components/BedrockStack'; import { RESERVED_KEYWORDS } from '../constants'; import { RequireContext } from '../types/RequireContext'; import { getRouteScreens, getScreenPathMapConfig } from '../utils'; import { createParentRouteScreenMap } from '../utils/createParentRouteScreenMap'; import { mergeParentLayoutScreen } from '../utils/mergeParentLayoutScreen'; import { getFileNameFromPath } from '../utils/path'; type NavigationContainerProps = ComponentProps; export interface RouterControlsConfig { prefix: string; context: RequireContext; screenContainer?: ComponentType>; } export function useBedrockRouterControls({ prefix, context, screenContainer: ScreenContainer }: RouterControlsConfig) { const routeScreens = useMemo(() => getRouteScreens(context), [context]); const registerScreens = useMemo(() => { return routeScreens.filter( (screen) => !RESERVED_KEYWORDS.includes(getFileNameFromPath(screen.path, { withExtension: false })) ); }, [routeScreens]); const layoutScreenMap = useMemo(() => createParentRouteScreenMap(routeScreens, '_layout'), [routeScreens]); const BedrockScreens = useMemo(() => { return registerScreens.map((routeScreen) => { const Layout = mergeParentLayoutScreen(layoutScreenMap, routeScreen.path); const Component = function Component() { const element = ( ); return ScreenContainer == null ? element : {element}; }; const routePath = routeScreen.path; const screenOptions = routeScreen.component?.screenOptions ?? {}; return ; }); }, [registerScreens, layoutScreenMap, ScreenContainer]); const linkingOptions: NavigationContainerProps['linking'] = useMemo(() => { return { prefixes: [prefix], config: { screens: getScreenPathMapConfig(registerScreens), }, async getInitialURL() { const initialURL = getSchemeUri(); if (initialURL == null) { return; } /** @NOTE 한글 path 의 경우 decode 해야합니다. */ return decodeURI(initialURL); }, }; }, [prefix, registerScreens]); return { BedrockScreens, linkingOptions }; }