Skip to content

Commit 3e15245

Browse files
authored
refactor: migrate AppContainer root to React Navigation static config (#7416)
1 parent 5309d3e commit 3e15245

5 files changed

Lines changed: 63 additions & 57 deletions

File tree

app/AppContainer.tsx

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,73 @@
1-
import { useContext, memo, useEffect } from 'react';
2-
import { NavigationContainer } from '@react-navigation/native';
1+
import { useContext, useEffect } from 'react';
2+
import { createStaticNavigation } from '@react-navigation/native';
33
import { createNativeStackNavigator } from '@react-navigation/native-stack';
4+
import { useSelector } from 'react-redux';
45

5-
import type { SetUsernameStackParamList, StackParamList } from './definitions/navigationTypes';
6+
import { type IApplicationState, RootEnum } from './definitions';
67
import Navigation from './lib/navigation/appNavigation';
78
import { useMasterDetail } from './lib/hooks/useMasterDetail';
8-
import { useAppSelector } from './lib/hooks/useAppSelector';
99
import { defaultHeader, getActiveRouteName, navigationTheme } from './lib/methods/helpers/navigation';
10-
import { RootEnum } from './definitions';
11-
// Stacks
12-
import AuthLoadingView from './views/AuthLoadingView';
13-
// SetUsername Stack
14-
import SetUsernameView from './views/SetUsernameView';
1510
import OutsideStack from './stacks/OutsideStack';
1611
import InsideStack from './stacks/InsideStack';
1712
import MasterDetailStack from './stacks/MasterDetailStack';
1813
import ShareExtensionStack from './stacks/ShareExtensionStack';
14+
import AuthLoadingView from './views/AuthLoadingView';
15+
import SetUsernameView from './views/SetUsernameView';
1916
import { ThemeContext } from './theme';
2017
import { setCurrentScreen } from './lib/methods/helpers/log';
2118
import { themes } from './lib/constants/colors';
2219
import { emitter } from './lib/methods/helpers';
2320
import MediaCallHeader from './containers/MediaCallHeader/MediaCallHeader';
2421

25-
const createStackNavigator = createNativeStackNavigator;
22+
const useIsLoading = () =>
23+
useSelector(
24+
(state: IApplicationState) =>
25+
state.app.root === RootEnum.ROOT_LOADING || state.app.root === RootEnum.ROOT_LOADING_SHARE_EXTENSION
26+
);
2627

27-
// SetUsernameStack
28-
const SetUsername = createStackNavigator<SetUsernameStackParamList>();
29-
const SetUsernameStack = () => (
30-
<SetUsername.Navigator screenOptions={defaultHeader}>
31-
<SetUsername.Screen name='SetUsernameView' component={SetUsernameView} />
32-
</SetUsername.Navigator>
33-
);
28+
const useIsOutside = () => useSelector((state: IApplicationState) => state.app.root === RootEnum.ROOT_OUTSIDE);
3429

35-
// App
36-
const Stack = createStackNavigator<StackParamList>();
37-
const App = memo(() => {
38-
const { theme } = useContext(ThemeContext);
30+
const useIsMasterDetail = () => {
3931
const isMasterDetail = useMasterDetail();
40-
const root = useAppSelector(state => state.app.root);
32+
return useSelector((state: IApplicationState) => state.app.root === RootEnum.ROOT_INSIDE) && isMasterDetail;
33+
};
34+
35+
const useIsInside = () => {
36+
const isMasterDetail = useMasterDetail();
37+
return useSelector((state: IApplicationState) => state.app.root === RootEnum.ROOT_INSIDE) && !isMasterDetail;
38+
};
39+
40+
const useIsSetUsername = () => useSelector((state: IApplicationState) => state.app.root === RootEnum.ROOT_SET_USERNAME);
41+
42+
const useIsShareExtension = () => useSelector((state: IApplicationState) => state.app.root === RootEnum.ROOT_SHARE_EXTENSION);
43+
44+
const SetUsernameStack = createNativeStackNavigator({
45+
screenOptions: defaultHeader,
46+
screens: { SetUsernameView }
47+
});
48+
49+
const RootNavigator = createNativeStackNavigator({
50+
screenOptions: { headerShown: false, animation: 'none' },
51+
groups: {
52+
Loading: { if: useIsLoading, screens: { AuthLoading: AuthLoadingView } },
53+
Outside: { if: useIsOutside, screens: { OutsideStack } },
54+
MasterDetail: { if: useIsMasterDetail, screens: { MasterDetailStack } },
55+
Inside: { if: useIsInside, screens: { InsideStack } },
56+
SetUsername: { if: useIsSetUsername, screens: { SetUsernameStack } },
57+
ShareExtension: { if: useIsShareExtension, screens: { ShareExtensionStack } }
58+
}
59+
}).with(({ Navigator }) => {
60+
'use memo';
61+
62+
const { theme } = useContext(ThemeContext);
63+
return <Navigator screenOptions={{ navigationBarColor: themes[theme].surfaceLight }} />;
64+
});
65+
66+
const AppNavigation = createStaticNavigation(RootNavigator);
67+
68+
const AppContainer = () => {
69+
const { theme } = useContext(ThemeContext);
70+
const root = useSelector((state: IApplicationState) => state.app.root);
4171

4272
useEffect(() => {
4373
if (root) {
@@ -52,13 +82,11 @@ const App = memo(() => {
5282
return null;
5383
}
5484

55-
const navTheme = navigationTheme(theme);
56-
5785
return (
5886
<>
5987
<MediaCallHeader />
60-
<NavigationContainer
61-
theme={navTheme}
88+
<AppNavigation
89+
theme={navigationTheme(theme)}
6290
ref={Navigation.navigationRef}
6391
onReady={() => {
6492
emitter.emit('navigationReady');
@@ -70,24 +98,10 @@ const App = memo(() => {
7098
setCurrentScreen(currentRouteName);
7199
}
72100
Navigation.routeNameRef.current = currentRouteName;
73-
}}>
74-
<Stack.Navigator
75-
screenOptions={{ headerShown: false, animation: 'none', navigationBarColor: themes[theme].surfaceLight }}>
76-
{root === RootEnum.ROOT_LOADING || root === RootEnum.ROOT_LOADING_SHARE_EXTENSION ? (
77-
<Stack.Screen name='AuthLoading' component={AuthLoadingView} />
78-
) : null}
79-
{root === RootEnum.ROOT_OUTSIDE ? <Stack.Screen name='OutsideStack' component={OutsideStack} /> : null}
80-
{root === RootEnum.ROOT_INSIDE && isMasterDetail ? (
81-
<Stack.Screen name='MasterDetailStack' component={MasterDetailStack} />
82-
) : null}
83-
{root === RootEnum.ROOT_INSIDE && !isMasterDetail ? <Stack.Screen name='InsideStack' component={InsideStack} /> : null}
84-
{root === RootEnum.ROOT_SET_USERNAME ? <Stack.Screen name='SetUsernameStack' component={SetUsernameStack} /> : null}
85-
{root === RootEnum.ROOT_SHARE_EXTENSION ? (
86-
<Stack.Screen name='ShareExtensionStack' component={ShareExtensionStack} />
87-
) : null}
88-
</Stack.Navigator>
89-
</NavigationContainer>
101+
}}
102+
/>
90103
</>
91104
);
92-
});
93-
export default App;
105+
};
106+
107+
export default AppContainer;

app/stacks/InsideStack.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,4 @@ const InsideStack = createNativeStackNavigator({
384384
return <Navigator screenOptions={themedHeader(theme)} />;
385385
});
386386

387-
const InsideStackScreen = InsideStack.getComponent();
388-
389-
export default InsideStackScreen;
387+
export default InsideStack;

app/stacks/MasterDetailStack/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,4 @@ const InsideStack = createNativeStackNavigator({
300300
return <Navigator screenOptions={themedHeader(theme)} />;
301301
});
302302

303-
const MasterDetailStack = InsideStack.getComponent();
304-
305-
export default MasterDetailStack;
303+
export default InsideStack;

app/stacks/OutsideStack.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,4 @@ const OutsideModal = createNativeStackNavigator({
5050

5151
export type OutsideModalParamList = StaticParamList<typeof OutsideModal>;
5252

53-
const OutsideStackModal = OutsideModal.getComponent();
54-
55-
export default OutsideStackModal;
53+
export default OutsideModal;

app/stacks/ShareExtensionStack.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,4 @@ const ShareExtension = createNativeStackNavigator({
3333

3434
export type ShareInsideStackParamList = StaticParamList<typeof ShareExtension>;
3535

36-
const ShareExtensionStack = ShareExtension.getComponent();
37-
38-
export default ShareExtensionStack;
36+
export default ShareExtension;

0 commit comments

Comments
 (0)