Front: Navigation: Use actual routes to build a typed navigator
This commit is contained in:
+37
-16
@@ -1,4 +1,5 @@
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import { NavigationProp, useNavigation as navigationHook } from "@react-navigation/native";
|
||||
import React from 'react';
|
||||
import { DarkTheme, DefaultTheme, NavigationContainer } from '@react-navigation/native';
|
||||
import { RootState, useSelector } from './state/Store';
|
||||
@@ -17,21 +18,39 @@ import LoadingComponent from './components/Loading';
|
||||
import ProfileView from './views/ProfileView';
|
||||
import useColorScheme from './hooks/colorScheme';
|
||||
|
||||
const Stack = createNativeStackNavigator();
|
||||
const protectedRoutes = () => ({
|
||||
Home: { component: HomeView, options: { title: translate('welcome') } },
|
||||
Settings: { component: SetttingsNavigator, options: { title: 'Settings' } },
|
||||
Song: { component: SongLobbyView, options: { title: translate('play') } },
|
||||
Play: { component: PlayView, options: { title: translate('play') } },
|
||||
Score: { component: ScoreView, options: { title: translate('score') } },
|
||||
Search: { component: SearchView, options: { title: translate('search') } },
|
||||
User: { component: ProfileView, options: { title: translate('user') } },
|
||||
}) as const;
|
||||
|
||||
export const protectedRoutes = <>
|
||||
<Stack.Screen name="Home" component={HomeView} options={{ title: translate('welcome') }} />
|
||||
<Stack.Screen name="Settings" component={SetttingsNavigator} options={{ title: 'Settings' }} />
|
||||
<Stack.Screen name="Song" component={SongLobbyView} options={{ title: translate('play') }} />
|
||||
<Stack.Screen name="Play" component={PlayView} options={{ title: translate('play') }} />
|
||||
<Stack.Screen name="Score" component={ScoreView} options={{ title: translate('score') }} />
|
||||
<Stack.Screen name="Search" component={SearchView} options={{ title: translate('search') }} />
|
||||
<Stack.Screen name="User" component={ProfileView} options={{ title: translate('user') }} />
|
||||
</>;
|
||||
const publicRoutes = () => ({
|
||||
Login: { component: AuthenticationView, options: { title: translate('signInBtn') } },
|
||||
}) as const;
|
||||
|
||||
export const publicRoutes = <React.Fragment>
|
||||
<Stack.Screen name="Login" component={AuthenticationView} options={{ title: translate('signInBtn')}} />
|
||||
</React.Fragment>;
|
||||
type Route<Args extends any[] = any[]> = {
|
||||
component: (...args: Args) => JSX.Element,
|
||||
options: any
|
||||
}
|
||||
|
||||
type RouteParams<Routes extends Record<string, Route>> = {
|
||||
[RouteName in keyof Routes]: Parameters<Routes[RouteName]['component']>[0];
|
||||
}
|
||||
|
||||
type PrivateRoutesParams = RouteParams<ReturnType<typeof protectedRoutes>>;
|
||||
type PublicRoutesParams = RouteParams<ReturnType<typeof publicRoutes>>;
|
||||
type AppRouteParams = PrivateRoutesParams & PublicRoutesParams;
|
||||
|
||||
const Stack = createNativeStackNavigator<AppRouteParams & { Loading: never }>();
|
||||
|
||||
const routesToScreens = (routes: Record<string, Route>) => Object.entries(routes)
|
||||
.map(([name, route]) => (
|
||||
<Stack.Screen name={name as any} {...route}/>
|
||||
))
|
||||
|
||||
export const Router = () => {
|
||||
const accessToken = useSelector((state: RootState) => state.user.accessToken);
|
||||
@@ -53,11 +72,13 @@ export const Router = () => {
|
||||
<LoadingComponent/>
|
||||
</Center>
|
||||
}/>
|
||||
: userProfile.isSuccess && accessToken
|
||||
? protectedRoutes
|
||||
: publicRoutes
|
||||
: routesToScreens(userProfile.isSuccess && accessToken
|
||||
? protectedRoutes()
|
||||
: publicRoutes())
|
||||
}
|
||||
</Stack.Navigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export const useNavigation = () => navigationHook<NavigationProp<AppRouteParams>>();
|
||||
Reference in New Issue
Block a user