-
Notifications
You must be signed in to change notification settings - Fork 3.1k
/
Copy pathuseStateWithSearch.ts
80 lines (70 loc) · 2.98 KB
/
useStateWithSearch.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import type {ParamListBase} from '@react-navigation/native';
import {useMemo} from 'react';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute';
import type {CustomStateHookProps, PlatformStackNavigationState, PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types';
import type {RootStackParamList, State} from '@libs/Navigation/types';
import {isCentralPaneName} from '@libs/NavigationUtils';
import SCREENS from '@src/SCREENS';
type Routes = PlatformStackNavigationState<ParamListBase>['routes'];
function reduceCentralPaneRoutes(routes: Routes): Routes {
const result: Routes = [];
let count = 0;
const reverseRoutes = [...routes].reverse();
reverseRoutes.forEach((route) => {
if (isCentralPaneName(route.name)) {
// Remove all central pane routes except the last 3. This will improve performance.
if (count < 3) {
result.push(route);
count++;
}
} else {
result.push(route);
}
});
return result.reverse();
}
function useStateWithSearch({state}: CustomStateHookProps) {
const {shouldUseNarrowLayout} = useResponsiveLayout();
return useMemo(() => {
const routes = reduceCentralPaneRoutes(state.routes);
if (shouldUseNarrowLayout) {
const isSearchCentralPane = (route: PlatformStackRouteProp<ParamListBase>) =>
getTopmostCentralPaneRoute({routes: [route]} as State<RootStackParamList>)?.name === SCREENS.SEARCH.CENTRAL_PANE;
const lastRoute = routes.at(-1);
const lastSearchCentralPane = lastRoute && isSearchCentralPane(lastRoute) ? lastRoute : undefined;
const filteredRoutes = routes.filter((route) => !isSearchCentralPane(route));
// On narrow layout, if we are on /search route we want to hide all central pane routes and show only the bottom tab navigator.
if (lastSearchCentralPane) {
const filteredRoute = filteredRoutes.at(0);
if (filteredRoute) {
return {
stateToRender: {
...state,
index: 0,
routes: [filteredRoute],
},
searchRoute: lastSearchCentralPane,
};
}
}
return {
stateToRender: {
...state,
index: filteredRoutes.length - 1,
routes: filteredRoutes,
},
searchRoute: undefined,
};
}
return {
stateToRender: {
...state,
index: routes.length - 1,
routes: [...routes],
},
searchRoute: undefined,
};
}, [state, shouldUseNarrowLayout]);
}
export default useStateWithSearch;