import { LOCATION_CHANGE as LOCATION_CHANGE_SUCCESS } from '@common-stack/remix-router-redux'; import { NavigationContainer, LinkingOptions } from '@react-navigation/native'; import { cloneDeep, merge } from 'lodash-es'; import React, { MutableRefObject, ReactElement, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { navigationRef } from '@common-stack/client-react'; import { isUserAuthenticated } from '@adminide-stack/user-auth0-client'; interface INavigationContainerComponentProps { children: ReactElement[]; configurableRoutes: Record[]; independent?: boolean; linking?: LinkingOptions; } interface INavigationContainerRef { name: string; key: string; params?: Readonly; } export const getPath = (routeName: string, configurableRoutes: Record[]) => { let resultantPath = ''; configurableRoutes.forEach((item) => { if (item.children?.length) { const value = getPath(routeName, item.children); if (value) { resultantPath = value; } } if (item.navigationRouteName === routeName) { resultantPath = item.path; } }); return resultantPath; }; export const configurableRoutesWithNavigationRouteName = ( configurableRoutes: Record[], parentName: string = '', ) => { return configurableRoutes.map((item) => { const resultantName = parentName; const navigationRouteName = resultantName.length ? `${resultantName}.${item.name}` : item.name; item.navigationRouteName = navigationRouteName; if (item.children) { item.children = configurableRoutesWithNavigationRouteName(item.children, navigationRouteName); } return item; }); }; export const useLocationChange = () => { const dispatch = useDispatch(); const { authenticated } = isUserAuthenticated(); const [locationChange, setLocationChange] = React.useState(null); const platformState = useSelector((state) => (state as any).platform); React.useEffect(() => { if (locationChange) setLocation(locationChange); }, [locationChange]); const setLocation = ({ configurableRoutes, previousRoute = null, orgName = null }: any) => { const currentRoute: any = navigationRef.isReady() ? navigationRef?.getCurrentRoute() : null; const currentRouteName = currentRoute ? currentRoute!?.name : null; const configuredRoutes = configurableRoutesWithNavigationRouteName(configurableRoutes); const currentPath = currentRouteName ? getPath(currentRouteName as string, configuredRoutes) : null; const previousPath = previousRoute ? getPath(previousRoute?.current!.name, configuredRoutes) : null; const currentOrgName = authenticated ? orgName ? orgName : currentRoute!.params?.orgName || platformState?.orgName || previousRoute?.current?.params?.orgName : null; const currParams = { ...(currentRoute!.params || {}), orgName: currentOrgName, }; navigationRef?.setParams(currParams); dispatch({ type: LOCATION_CHANGE_SUCCESS, payload: { currentRoute: { path: currentPath, params: currParams, }, previousRoute: { path: previousPath, params: previousRoute?.current?.params ?? { orgName: '' }, }, }, }); }; return { setLocationChange }; }; export const NavigationContainerComponent = ({ children, configurableRoutes, independent, linking, }: INavigationContainerComponentProps): ReactElement => { const routeNameRef = useRef(undefined) as MutableRefObject< INavigationContainerRef | undefined >; const dispatch = useDispatch(); const platformState = useSelector((state) => (state as any).platform); const { setLocationChange } = useLocationChange(); //const user = useSelector((state: any) => state.user); return ( { routeNameRef.current = navigationRef.isReady() ? navigationRef?.getCurrentRoute() : null; const currentRoute: any = routeNameRef?.current; setLocationChange({ configurableRoutes, orgName: platformState?.orgName ?? currentRoute?.params?.orgName ?? '', }); }} onStateChange={async () => { const previousRoute: any = routeNameRef?.current ? cloneDeep(routeNameRef) : null; const currentRoute: any = navigationRef.isReady() ? navigationRef?.getCurrentRoute() : null; const previousRouteName = previousRoute ? previousRoute?.current!.name : null; const currentRouteName = currentRoute ? currentRoute!?.name : null; const configuredRoutes = configurableRoutesWithNavigationRouteName(configurableRoutes); const currentPath = currentRouteName ? getPath(currentRouteName as string, configuredRoutes) : null; const previousPath = previousRoute ? getPath(previousRoute?.current!.name, configuredRoutes) : null; const currParams = { ...(currentRoute!.params || {}), orgName: currentRoute!.params?.orgName || platformState?.orgName, }; //if (previousRouteName && currentRouteName && previousRouteName !== currentRouteName) { if (previousPath !== currentPath) { routeNameRef.current = currentRoute; setLocationChange({ configurableRoutes, previousRoute }); // dispatch({ // type: LOCATION_CHANGE_SUCCESS, // payload: { // currentRoute: { // path: currentPath, // params: currParams, // }, // previousRoute: { // path: previousPath, // params: previousRoute?.current?.params ?? { orgName: '' }, // }, // }, // }); } }} > {children} ); };