import { ChainTypeEnum } from '@bit-ui-libs/common'; import type { EventArg, NavigationState } from '@react-navigation/native'; import { create } from 'zustand'; interface ChainTypeStoreState { type: ChainTypeEnum; setType: (type: ChainTypeEnum) => void; } export const useChainTypeStore = create((set) => ({ type: ChainTypeEnum.Objects, setType: (type) => set({ type }), })); /** * React Navigation routes listener to check every route for the `chainType` param. * * If this route exists, then we update our zustand store * so that components can obtain `chainType` without prop drilling. * * @param e Event passed by React Navigation, which contains `NavigationState` and possibly `chainType` * @returns {void} */ export const chainTypeNavigationListener = (e: EventArg<'state', undefined, { state?: NavigationState }>) => { const navigationState = e.data?.state; if (!navigationState) { return; } const lastRoute = navigationState.routes[navigationState.routes.length]; if (lastRoute?.params && 'chainType' in lastRoute.params) { useChainTypeStore.setState({ type: lastRoute.params.chainType as ChainTypeEnum }); } }; interface ObjectWithChainType { /** * This is the ideal property that describes the Chain Type. * Most screens involving a chained token should have this. */ chainType?: ChainTypeEnum; } /** * This function tries to figure out what the Chain Type is * no matter where you are - if in a component, screen, or hook * * Order of checking for Chain Type starts from specific (screen params) to general (global state) */ export function useInferChainType(opts?: ObjectWithChainType) { const chainType = useChainTypeStore((s) => s.type); /** * Round One: Chain Type from our Chain Type Store (zustand) * We attach a listener to `` for `chainType` in `route.params`. * A store is needed for other components to be able to manipulate `chainType` without having to change routes. */ if (chainType) { return chainType; } /** * Round Three: Chain Type in "component's props" * Some components do receive "chainType" as a prop * (which probably came from route params). * If they pass their props to us, we can look for it now */ if (opts?.chainType) { return opts.chainType; } /** Round Five (last resort !) - fall back to `OBJECTS` Chain Type */ return ChainTypeEnum.Objects; }