diff --git a/native/chat/thread-screen-pruner.react.js b/native/chat/thread-screen-pruner.react.js --- a/native/chat/thread-screen-pruner.react.js +++ b/native/chat/thread-screen-pruner.react.js @@ -1,17 +1,26 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import { Alert } from 'react-native'; import { threadIsPending } from 'lib/shared/thread-utils'; import { clearThreadsActionType } from '../navigation/action-types'; -import { useActiveThread } from '../navigation/nav-selectors'; +import { + getChildRouteFromNavigatorRoute, + useActiveThread, +} from '../navigation/nav-selectors'; import { NavContext } from '../navigation/navigation-context'; import { getStateFromNavigatorRoute, getThreadIDFromRoute, } from '../navigation/navigation-utils'; +import { + AppRouteName, + ChatRouteName, + TabNavigatorRouteName, +} from '../navigation/route-names'; import { useSelector } from '../redux/redux-utils'; import type { AppState } from '../redux/state-types'; @@ -23,29 +32,41 @@ const navContext = React.useContext(NavContext); - const chatRoute = React.useMemo(() => { + const chatRouteState = React.useMemo(() => { if (!navContext) { return null; } const { state } = navContext; - const appState = getStateFromNavigatorRoute(state.routes[0]); - const tabState = getStateFromNavigatorRoute(appState.routes[0]); - return getStateFromNavigatorRoute(tabState.routes[1]); + const appRoute = state.routes.find(route => route.name === AppRouteName); + invariant( + appRoute, + 'Navigation context should contain route for AppNavigator ' + + 'when ThreadScreenPruner is rendered', + ); + const tabRoute = getChildRouteFromNavigatorRoute( + appRoute, + TabNavigatorRouteName, + ); + const chatRoute = getChildRouteFromNavigatorRoute( + tabRoute, + ChatRouteName, + ); + return getStateFromNavigatorRoute(chatRoute); }, [navContext]); const inStackThreadIDs = React.useMemo(() => { const threadIDs = new Set(); - if (!chatRoute) { + if (!chatRouteState) { return threadIDs; } - for (const route of chatRoute.routes) { + for (const route of chatRouteState.routes) { const threadID = getThreadIDFromRoute(route); if (threadID && !threadIsPending(threadID)) { threadIDs.add(threadID); } } return threadIDs; - }, [chatRoute]); + }, [chatRouteState]); const pruneThreadIDs = React.useMemo(() => { const threadIDs = []; diff --git a/native/navigation/nav-selectors.js b/native/navigation/nav-selectors.js --- a/native/navigation/nav-selectors.js +++ b/native/navigation/nav-selectors.js @@ -1,6 +1,10 @@ // @flow -import type { PossiblyStaleNavigationState } from '@react-navigation/native'; +import type { + PossiblyStaleNavigationState, + PossiblyStaleRoute, +} from '@react-navigation/native'; +import invariant from 'invariant'; import _memoize from 'lodash/memoize'; import * as React from 'react'; import { createSelector } from 'reselect'; @@ -260,6 +264,21 @@ }), ); } + +function getChildRouteFromNavigatorRoute( + parentRoute: PossiblyStaleRoute<>, + childRouteName: string, +): PossiblyStaleRoute<> { + const parentState = getStateFromNavigatorRoute(parentRoute); + const childRoute = parentState.routes.find( + route => route.name === childRouteName, + ); + invariant( + childRoute, + `parentRoute should contain route for ${childRouteName}`, + ); + return childRoute; +} export { createIsForegroundSelector, useIsAppLoggedIn, @@ -274,4 +293,5 @@ nativeCalendarQuery, nonThreadCalendarQuery, useCalendarQuery, + getChildRouteFromNavigatorRoute, };