Front: Navigation: Route Props include route info
This commit is contained in:
committed by
Clément Le Bihan
parent
6871aaf759
commit
deaaaac2cd
@@ -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<Args extends any[] = any[]> = {
|
||||
component: (...args: Args) => JSX.Element,
|
||||
type Route<Props = any> = {
|
||||
component: (arg: RouteProps<Props>) => JSX.Element | (() => JSX.Element),
|
||||
options: any
|
||||
}
|
||||
|
||||
type OmitOrUndefined<T, K extends string> = T extends undefined ? T : Omit<T, K>
|
||||
|
||||
type RouteParams<Routes extends Record<string, Route>> = {
|
||||
[RouteName in keyof Routes]: Parameters<Routes[RouteName]['component']>[0];
|
||||
[RouteName in keyof Routes]: OmitOrUndefined<Parameters<Routes[RouteName]['component']>[0], keyof NativeStackScreenProps<{}>>;
|
||||
}
|
||||
|
||||
type PrivateRoutesParams = RouteParams<ReturnType<typeof protectedRoutes>>;
|
||||
@@ -49,12 +52,12 @@ type AppRouteParams = PrivateRoutesParams & PublicRoutesParams;
|
||||
|
||||
const Stack = createNativeStackNavigator<AppRouteParams & { Loading: never }>();
|
||||
|
||||
const RouteToScreen = (component: Route['component']) => (props: NativeStackScreenProps<AppRouteParams>) =>
|
||||
const RouteToScreen = <T extends {}, >(component: Route<T>['component']) => (props: NativeStackScreenProps<T & ParamListBase>) =>
|
||||
<>
|
||||
{component(props.route.params)}
|
||||
{component({ ...props.route.params, route: props.route } as Parameters<Route<T>['component']>[0])}
|
||||
</>
|
||||
|
||||
const routesToScreens = (routes: Record<keyof AppRouteParams, Route>) => Object.entries(routes)
|
||||
const routesToScreens = (routes: Partial<Record<keyof AppRouteParams, Route>>) => Object.entries(routes)
|
||||
.map(([name, route]) => (
|
||||
<Stack.Screen
|
||||
name={name as keyof AppRouteParams}
|
||||
@@ -92,4 +95,7 @@ export const Router = () => {
|
||||
);
|
||||
}
|
||||
|
||||
export type RouteProps<T> = T & Pick<NativeStackScreenProps<T & ParamListBase>, 'route'>;
|
||||
|
||||
|
||||
export const useNavigation = () => navigationHook<NavigationProp<AppRouteParams>>();
|
||||
@@ -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<string> => {
|
||||
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<AuthenticationViewProps>) => {
|
||||
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 (
|
||||
|
||||
@@ -33,7 +33,7 @@ if (process.env.NODE_ENV != 'development' && Platform.OS === 'web') {
|
||||
}
|
||||
}
|
||||
|
||||
const PlayView = ({ songId }: PlayViewProps) => {
|
||||
const PlayView = ({ songId }: RouteProps<PlayViewProps>) => {
|
||||
const navigation = useNavigation();
|
||||
const queryClient = useQueryClient();
|
||||
const song = useQuery(['song', songId], () => API.getSong(songId));
|
||||
|
||||
@@ -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<ScoreViewProps>) => {
|
||||
const theme = useTheme();
|
||||
const navigation = useNavigation();
|
||||
// const songQuery = useQuery(['song', props.songId], () => API.getSong(props.songId));
|
||||
|
||||
@@ -14,7 +14,7 @@ interface SongLobbyProps {
|
||||
songId: number;
|
||||
}
|
||||
|
||||
const SongLobbyView = (props: SongLobbyProps) => {
|
||||
const SongLobbyView = (props: RouteProps<SongLobbyProps>) => {
|
||||
const navigation = useNavigation();
|
||||
const songQuery = useQuery(['song', props.songId], () => API.getSong(props.songId));
|
||||
const chaptersQuery = useQuery(['song', props.songId, 'chapters'], () => API.getSongChapters(props.songId));
|
||||
|
||||
Reference in New Issue
Block a user