From deaaaac2cde523435c35393bba00d8a445be6b4b Mon Sep 17 00:00:00 2001 From: Arthur Jamet Date: Sun, 16 Apr 2023 16:01:12 +0100 Subject: [PATCH] Front: Navigation: Route Props include route info --- front/Navigation.tsx | 20 +++++++++++++------- front/views/AuthenticationView.tsx | 15 ++++++--------- front/views/PlayView.tsx | 2 +- front/views/ScoreView.tsx | 6 ++++-- front/views/SongLobbyView.tsx | 2 +- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/front/Navigation.tsx b/front/Navigation.tsx index b4e32db..21e1244 100644 --- a/front/Navigation.tsx +++ b/front/Navigation.tsx @@ -1,5 +1,5 @@ import { NativeStackScreenProps, createNativeStackNavigator } from '@react-navigation/native-stack'; -import { NavigationProp, useNavigation as navigationHook } from "@react-navigation/native"; +import { NavigationProp, ParamListBase, 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'; @@ -19,6 +19,7 @@ import LoadingComponent from './components/Loading'; import ProfileView from './views/ProfileView'; import useColorScheme from './hooks/colorScheme'; + const protectedRoutes = () => ({ Home: { component: HomeView, options: { title: translate('welcome') } }, Settings: { component: SetttingsNavigator, options: { title: 'Settings' } }, @@ -34,13 +35,15 @@ const publicRoutes = () => ({ Login: { component: AuthenticationView, options: { title: translate('signInBtn') } }, }) as const; -type Route = { - component: (...args: Args) => JSX.Element, +type Route = { + component: (arg: RouteProps) => JSX.Element | (() => JSX.Element), options: any } +type OmitOrUndefined = T extends undefined ? T : Omit + type RouteParams> = { - [RouteName in keyof Routes]: Parameters[0]; + [RouteName in keyof Routes]: OmitOrUndefined[0], keyof NativeStackScreenProps<{}>>; } type PrivateRoutesParams = RouteParams>; @@ -49,12 +52,12 @@ type AppRouteParams = PrivateRoutesParams & PublicRoutesParams; const Stack = createNativeStackNavigator(); -const RouteToScreen = (component: Route['component']) => (props: NativeStackScreenProps) => +const RouteToScreen = (component: Route['component']) => (props: NativeStackScreenProps) => <> - {component(props.route.params)} + {component({ ...props.route.params, route: props.route } as Parameters['component']>[0])} -const routesToScreens = (routes: Record) => Object.entries(routes) +const routesToScreens = (routes: Partial>) => Object.entries(routes) .map(([name, route]) => ( { ); } +export type RouteProps = T & Pick, 'route'>; + + export const useNavigation = () => navigationHook>(); \ No newline at end of file diff --git a/front/views/AuthenticationView.tsx b/front/views/AuthenticationView.tsx index cea938d..ec6970c 100644 --- a/front/views/AuthenticationView.tsx +++ b/front/views/AuthenticationView.tsx @@ -7,7 +7,7 @@ import { Center, Button, Text } from 'native-base'; import SigninForm from "../components/forms/signinform"; import SignupForm from "../components/forms/signupform"; import TextButton from "../components/TextButton"; -import { useNavigation } from "../Navigation"; +import { RouteProps } from "../Navigation"; const hanldeSignin = async (username: string, password: string, apiSetter: (accessToken: string) => void): Promise => { try { @@ -33,15 +33,12 @@ const handleSignup = async (username: string, password: string, email: string, a } }; -const AuthenticationView = () => { - const navigation = useNavigation(); +type AuthenticationViewProps = { + isSignup: boolean; +} + +const AuthenticationView = ({ isSignup }: RouteProps) => { const dispatch = useDispatch(); - console.log(navigation.getState()); - const params = navigation.getState().routes.find((route) => { - // this is not ideal way to check if we are on login page - return route.name === "Login"; - }).params ?? {}; - const isSignup = params?.isSignup ?? false; const [mode, setMode] = React.useState<"signin" | "signup">(isSignup ? "signup" : "signin"); return ( diff --git a/front/views/PlayView.tsx b/front/views/PlayView.tsx index ce06fe0..3486f53 100644 --- a/front/views/PlayView.tsx +++ b/front/views/PlayView.tsx @@ -33,7 +33,7 @@ if (process.env.NODE_ENV != 'development' && Platform.OS === 'web') { } } -const PlayView = ({ songId }: PlayViewProps) => { +const PlayView = ({ songId }: RouteProps) => { const navigation = useNavigation(); const queryClient = useQueryClient(); const song = useQuery(['song', songId], () => API.getSong(songId)); diff --git a/front/views/ScoreView.tsx b/front/views/ScoreView.tsx index 1764697..66bcf07 100644 --- a/front/views/ScoreView.tsx +++ b/front/views/ScoreView.tsx @@ -1,14 +1,16 @@ import { Card, Column, Image, Row, Text, useTheme, ScrollView, Center, VStack } from "native-base" import Translate from "../components/Translate"; import SongCardGrid from "../components/SongCardGrid"; -import { useNavigation } from "../Navigation"; +import { RouteProps, useNavigation } from "../Navigation"; import { CardBorderRadius } from "../components/Card"; import TextButton from "../components/TextButton"; import API from '../API'; import { useQuery } from "react-query"; import LoadingComponent from "../components/Loading"; -const ScoreView = ({ songId }: { songId: number }) => { +type ScoreViewProps = { songId: number } + +const ScoreView = ({ songId }: RouteProps) => { const theme = useTheme(); const navigation = useNavigation(); // const songQuery = useQuery(['song', props.songId], () => API.getSong(props.songId)); diff --git a/front/views/SongLobbyView.tsx b/front/views/SongLobbyView.tsx index a3713d0..00dac8e 100644 --- a/front/views/SongLobbyView.tsx +++ b/front/views/SongLobbyView.tsx @@ -14,7 +14,7 @@ interface SongLobbyProps { songId: number; } -const SongLobbyView = (props: SongLobbyProps) => { +const SongLobbyView = (props: RouteProps) => { const navigation = useNavigation(); const songQuery = useQuery(['song', props.songId], () => API.getSong(props.songId)); const chaptersQuery = useQuery(['song', props.songId, 'chapters'], () => API.getSongChapters(props.songId));