Compare commits

..

No commits in common. "53ec2bb578b3e0b7e2f14b482bdeb1db847d19d0" and "7c38ec0bdb19159b414658452baeb28a8f70ec26" have entirely different histories.

41 changed files with 219 additions and 327 deletions

25
App.tsx
View file

@ -50,7 +50,6 @@ import MainApp from './src/screens/MainApp';
import LoginProvider from './src/components/providers/LoginProvider'; import LoginProvider from './src/components/providers/LoginProvider';
import { retrieveLoginToken } from './src/utils/loginToken'; import { retrieveLoginToken } from './src/utils/loginToken';
import { setupNotifications } from './src/utils/Notifications'; import { setupNotifications } from './src/utils/Notifications';
import { TabRoutes } from './src/navigation/TabNavigator';
// Native optimizations https://reactnavigation.org/docs/react-native-screens // Native optimizations https://reactnavigation.org/docs/react-native-screens
// Crashes app when navigating away from webview on android 9+ // Crashes app when navigating away from webview on android 9+
@ -60,8 +59,9 @@ initLocales();
setupNotifications(); setupNotifications();
LogBox.ignoreLogs([ LogBox.ignoreLogs([
// collapsible headers cause this warning, just ignore as it is not an issue
'Non-serializable values were found in the navigation state',
'Cannot update a component from inside the function body of a different component', 'Cannot update a component from inside the function body of a different component',
'`new NativeEventEmitter()` was called with a non-null argument',
]); ]);
type StateType = { type StateType = {
@ -76,9 +76,11 @@ type StateType = {
}; };
export default class App extends React.Component<{}, StateType> { export default class App extends React.Component<{}, StateType> {
navigatorRef: { current: null | NavigationContainerRef<any> }; navigatorRef: { current: null | NavigationContainerRef };
defaultData?: ParsedUrlDataType; defaultHomeRoute: string | undefined;
defaultHomeData: { [key: string]: string } | undefined;
urlHandler: URLHandler; urlHandler: URLHandler;
@ -95,7 +97,8 @@ export default class App extends React.Component<{}, StateType> {
loginToken: undefined, loginToken: undefined,
}; };
this.navigatorRef = React.createRef(); this.navigatorRef = React.createRef();
this.defaultData = undefined; this.defaultHomeRoute = undefined;
this.defaultHomeData = undefined;
this.urlHandler = new URLHandler(this.onInitialURLParsed, this.onDetectURL); this.urlHandler = new URLHandler(this.onInitialURLParsed, this.onDetectURL);
this.urlHandler.listen(); this.urlHandler.listen();
setSafeBounceHeight(Platform.OS === 'ios' ? 100 : 20); setSafeBounceHeight(Platform.OS === 'ios' ? 100 : 20);
@ -109,7 +112,8 @@ export default class App extends React.Component<{}, StateType> {
* @param parsedData The data parsed from the url * @param parsedData The data parsed from the url
*/ */
onInitialURLParsed = (parsedData: ParsedUrlDataType) => { onInitialURLParsed = (parsedData: ParsedUrlDataType) => {
this.defaultData = parsedData; this.defaultHomeRoute = parsedData.route;
this.defaultHomeData = parsedData.data;
}; };
/** /**
@ -122,9 +126,9 @@ export default class App extends React.Component<{}, StateType> {
// Navigate to nested navigator and pass data to the index screen // Navigate to nested navigator and pass data to the index screen
const nav = this.navigatorRef.current; const nav = this.navigatorRef.current;
if (nav != null) { if (nav != null) {
nav.navigate(TabRoutes.Home, { nav.navigate('home', {
nextScreen: parsedData.route, screen: 'index',
data: parsedData.data, params: { nextScreen: parsedData.route, data: parsedData.data },
}); });
} }
}; };
@ -209,7 +213,8 @@ export default class App extends React.Component<{}, StateType> {
<LoginProvider initialToken={this.state.loginToken}> <LoginProvider initialToken={this.state.loginToken}>
<MainApp <MainApp
ref={this.navigatorRef} ref={this.navigatorRef}
defaultData={this.defaultData} defaultHomeData={this.defaultHomeData}
defaultHomeRoute={this.defaultHomeRoute}
/> />
</LoginProvider> </LoginProvider>
</MascotPreferencesProvider> </MascotPreferencesProvider>

View file

@ -126,7 +126,6 @@
13B07F8E1A680F5B00A75B9A /* Resources */, 13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle Expo Assets */, 00DD1BFF1BD5951E006B06BC /* Bundle Expo Assets */,
58CDB7AB66969EE82AA3E3B0 /* [CP] Copy Pods Resources */, 58CDB7AB66969EE82AA3E3B0 /* [CP] Copy Pods Resources */,
2C1F7D7FCACF5494D140CFB7 /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -200,24 +199,6 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "../node_modules/react-native/scripts/react-native-xcode.sh\n"; shellScript = "../node_modules/react-native/scripts/react-native-xcode.sh\n";
}; };
2C1F7D7FCACF5494D140CFB7 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Campus/Pods-Campus-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Campus/Pods-Campus-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
58CDB7AB66969EE82AA3E3B0 /* [CP] Copy Pods Resources */ = { 58CDB7AB66969EE82AA3E3B0 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -407,7 +388,6 @@
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 i386";
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
@ -423,7 +403,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application; PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application;
@ -464,7 +444,6 @@
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 i386";
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -473,7 +452,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application; PRODUCT_BUNDLE_IDENTIFIER = fr.amicaleinsat.application;
PRODUCT_NAME = application; PRODUCT_NAME = application;

View file

@ -9,7 +9,7 @@ target 'Campus' do
use_react_native!( use_react_native!(
:path => config[:reactNativePath], :path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods # to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => true :hermes_enabled => false
) )

View file

@ -4,7 +4,6 @@ import i18n from 'i18n-js';
import { FlatList, StyleSheet } from 'react-native'; import { FlatList, StyleSheet } from 'react-native';
import { ProfileClubType } from '../../../screens/Amicale/ProfileScreen'; import { ProfileClubType } from '../../../screens/Amicale/ProfileScreen';
import { useNavigation } from '@react-navigation/core'; import { useNavigation } from '@react-navigation/core';
import { MainRoutes } from '../../../navigation/MainNavigator';
type Props = { type Props = {
clubs?: Array<ProfileClubType>; clubs?: Array<ProfileClubType>;
@ -27,10 +26,7 @@ export default function ProfileClubCard(props: Props) {
const getClubListItem = ({ item }: { item: ProfileClubType }) => { const getClubListItem = ({ item }: { item: ProfileClubType }) => {
const onPress = () => const onPress = () =>
navigation.navigate(MainRoutes.ClubInformation, { navigation.navigate('club-information', { clubId: item.id });
type: 'id',
clubId: item.id,
});
let description = i18n.t('screens.profile.isMember'); let description = i18n.t('screens.profile.isMember');
let icon = (leftProps: { let icon = (leftProps: {
color: string; color: string;

View file

@ -12,7 +12,6 @@ import {
import Urls from '../../../constants/Urls'; import Urls from '../../../constants/Urls';
import { ProfileDataType } from '../../../screens/Amicale/ProfileScreen'; import { ProfileDataType } from '../../../screens/Amicale/ProfileScreen';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
import { MainRoutes } from '../../../navigation/MainNavigator';
type Props = { type Props = {
profile?: ProfileDataType; profile?: ProfileDataType;
@ -94,7 +93,7 @@ export default function ProfilePersonalCard(props: Props) {
icon="account-edit" icon="account-edit"
mode="contained" mode="contained"
onPress={() => { onPress={() => {
navigation.navigate(MainRoutes.Website, { navigation.navigate('website', {
host: Urls.websites.amicale, host: Urls.websites.amicale,
path: profile?.link, path: profile?.link,
title: i18n.t('screens.websites.amicale'), title: i18n.t('screens.websites.amicale'),

View file

@ -6,7 +6,6 @@ import i18n from 'i18n-js';
import { StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native';
import CardList from '../../Lists/CardList/CardList'; import CardList from '../../Lists/CardList/CardList';
import { getAmicaleServices, SERVICES_KEY } from '../../../utils/Services'; import { getAmicaleServices, SERVICES_KEY } from '../../../utils/Services';
import { MainRoutes } from '../../../navigation/MainNavigator';
type Props = { type Props = {
firstname?: string; firstname?: string;
@ -52,11 +51,9 @@ function ProfileWelcomeCard(props: Props) {
<Divider /> <Divider />
<Paragraph>{i18n.t('screens.profile.welcomeDescription')}</Paragraph> <Paragraph>{i18n.t('screens.profile.welcomeDescription')}</Paragraph>
<CardList <CardList
dataset={getAmicaleServices( dataset={getAmicaleServices(navigation.navigate, true, [
(route) => navigation.navigate(route), SERVICES_KEY.PROFILE,
true, ])}
[SERVICES_KEY.PROFILE]
)}
isHorizontal={true} isHorizontal={true}
/> />
<Paragraph>{i18n.t('screens.profile.welcomeFeedback')}</Paragraph> <Paragraph>{i18n.t('screens.profile.welcomeFeedback')}</Paragraph>
@ -66,7 +63,7 @@ function ProfileWelcomeCard(props: Props) {
icon="bug" icon="bug"
mode="contained" mode="contained"
onPress={() => { onPress={() => {
navigation.navigate(MainRoutes.Feedback); navigation.navigate('feedback');
}} }}
style={styles.editButton} style={styles.editButton}
> >

View file

@ -24,7 +24,6 @@ import * as Animatable from 'react-native-animatable';
import { TAB_BAR_HEIGHT } from '../Tabbar/CustomTabBar'; import { TAB_BAR_HEIGHT } from '../Tabbar/CustomTabBar';
import { useNavigation } from '@react-navigation/core'; import { useNavigation } from '@react-navigation/core';
import { useCollapsible } from '../../context/CollapsibleContext'; import { useCollapsible } from '../../context/CollapsibleContext';
import { MainRoutes } from '../../navigation/MainNavigator';
type Props = { type Props = {
onPress: (action: string, data?: string) => void; onPress: (action: string, data?: string) => void;
@ -139,7 +138,7 @@ function PlanexBottomBar(props: Props) {
> >
<FAB <FAB
icon={'account-clock'} icon={'account-clock'}
onPress={() => navigation.navigate(MainRoutes.GroupSelect)} onPress={() => navigation.navigate('group-select')}
/> />
</Animatable.View> </Animatable.View>
</View> </View>

View file

@ -22,7 +22,6 @@ import { List } from 'react-native-paper';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { MainRoutes } from '../../navigation/MainNavigator';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
item: { item: {
@ -54,7 +53,7 @@ function ActionsDashBoardItem() {
icon="chevron-right" icon="chevron-right"
/> />
)} )}
onPress={(): void => navigation.navigate(MainRoutes.Feedback)} onPress={(): void => navigation.navigate('feedback')}
style={styles.item} style={styles.item}
/> />
</View> </View>

View file

@ -30,7 +30,6 @@ import type { NewsSourceType } from '../../constants/NewsSourcesConstants';
import ImageGalleryButton from '../Media/ImageGalleryButton'; import ImageGalleryButton from '../Media/ImageGalleryButton';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import GENERAL_STYLES from '../../constants/Styles'; import GENERAL_STYLES from '../../constants/Styles';
import { MainRoutes } from '../../navigation/MainNavigator';
type PropsType = { type PropsType = {
item: FeedItemType; item: FeedItemType;
@ -68,7 +67,7 @@ const styles = StyleSheet.create({
function FeedItem(props: PropsType) { function FeedItem(props: PropsType) {
const navigation = useNavigation(); const navigation = useNavigation();
const onPress = () => { const onPress = () => {
navigation.navigate(MainRoutes.FeedInformation, { navigation.navigate('feed-information', {
data: item, data: item,
date: getFormattedDate(props.item.time), date: getFormattedDate(props.item.time),
}); });

View file

@ -29,7 +29,6 @@ import {
import { StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native';
import GENERAL_STYLES from '../../../constants/Styles'; import GENERAL_STYLES from '../../../constants/Styles';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { MainRoutes } from '../../../navigation/MainNavigator';
type PropsType = { type PropsType = {
userDeviceRentDates: [string, string] | null; userDeviceRentDates: [string, string] | null;
@ -57,14 +56,14 @@ function EquipmentListItem(props: PropsType) {
let onPress; let onPress;
if (isRented) { if (isRented) {
onPress = () => { onPress = () => {
navigation.navigate(MainRoutes.EquipmentConfirm, { navigation.navigate('equipment-confirm', {
item, item,
dates: userDeviceRentDates, dates: userDeviceRentDates,
}); });
}; };
} else { } else {
onPress = () => { onPress = () => {
navigation.navigate(MainRoutes.EquipmentRent, { item }); navigation.navigate('equipment-rent', { item });
}; };
} }

View file

@ -22,7 +22,6 @@ import { TouchableRipple } from 'react-native-paper';
import { Image } from 'react-native-animatable'; import { Image } from 'react-native-animatable';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { StyleSheet, ViewStyle } from 'react-native'; import { StyleSheet, ViewStyle } from 'react-native';
import { MainRoutes } from '../../navigation/MainNavigator';
type PropsType = { type PropsType = {
images: Array<{ url: string }>; images: Array<{ url: string }>;
@ -40,7 +39,7 @@ function ImageGalleryButton(props: PropsType) {
const navigation = useNavigation(); const navigation = useNavigation();
const onPress = () => { const onPress = () => {
navigation.navigate(MainRoutes.Gallery, { images: props.images }); navigation.navigate('gallery', { images: props.images });
}; };
return ( return (

View file

@ -30,8 +30,7 @@ const PROXIMO_ENDPOINT = STUDENT_SERVER + '~proximo/v2/api/';
const PROXIMO_IMAGES_ENDPOINT = const PROXIMO_IMAGES_ENDPOINT =
STUDENT_SERVER + '~proximo/api_proximo/storage/app/public/'; STUDENT_SERVER + '~proximo/api_proximo/storage/app/public/';
const APP_IMAGES_ENDPOINT = STUDENT_SERVER + '~amicale_app/images/'; const APP_IMAGES_ENDPOINT = STUDENT_SERVER + '~amicale_app/images/';
const PROXIWASH_ENDPOINT = const PROXIWASH_ENDPOINT = 'https://www.proxiwash.com/weblaverie/ma-laverie-2?s=';
'https://www.proxiwash.com/weblaverie/ma-laverie-2?s=';
export default { export default {
amicale: { amicale: {

View file

@ -147,10 +147,10 @@ export function useCurrentDashboard() {
}; };
const allDatasets = [ const allDatasets = [
...getAmicaleServices((route) => navigation.navigate(route), isLoggedIn), ...getAmicaleServices(navigation.navigate, isLoggedIn),
...getStudentServices((route) => navigation.navigate(route)), ...getStudentServices(navigation.navigate),
...getINSAServices((route) => navigation.navigate(route)), ...getINSAServices(navigation.navigate),
...getSpecialServices((route) => navigation.navigate(route)), ...getSpecialServices(navigation.navigate),
]; ];
return { return {
currentDashboard: allDatasets.filter((item) => currentDashboard: allDatasets.filter((item) =>

View file

@ -24,7 +24,7 @@ import SettingsScreen from '../screens/Other/Settings/SettingsScreen';
import AboutScreen from '../screens/About/AboutScreen'; import AboutScreen from '../screens/About/AboutScreen';
import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen'; import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen';
import DebugScreen from '../screens/About/DebugScreen'; import DebugScreen from '../screens/About/DebugScreen';
import TabNavigator, { TabRoutes } from './TabNavigator'; import TabNavigator from './TabNavigator';
import GameMainScreen from '../screens/Game/screens/GameMainScreen'; import GameMainScreen from '../screens/Game/screens/GameMainScreen';
import VoteScreen from '../screens/Amicale/VoteScreen'; import VoteScreen from '../screens/Amicale/VoteScreen';
import LoginScreen from '../screens/Amicale/LoginScreen'; import LoginScreen from '../screens/Amicale/LoginScreen';
@ -33,10 +33,7 @@ import ProximoMainScreen from '../screens/Services/Proximo/ProximoMainScreen';
import ProximoListScreen from '../screens/Services/Proximo/ProximoListScreen'; import ProximoListScreen from '../screens/Services/Proximo/ProximoListScreen';
import ProximoAboutScreen from '../screens/Services/Proximo/ProximoAboutScreen'; import ProximoAboutScreen from '../screens/Services/Proximo/ProximoAboutScreen';
import ProfileScreen from '../screens/Amicale/ProfileScreen'; import ProfileScreen from '../screens/Amicale/ProfileScreen';
import ClubListScreen, { import ClubListScreen from '../screens/Amicale/Clubs/ClubListScreen';
ClubCategoryType,
ClubType,
} from '../screens/Amicale/Clubs/ClubListScreen';
import ClubAboutScreen from '../screens/Amicale/Clubs/ClubAboutScreen'; import ClubAboutScreen from '../screens/Amicale/Clubs/ClubAboutScreen';
import ClubDisplayScreen from '../screens/Amicale/Clubs/ClubDisplayScreen'; import ClubDisplayScreen from '../screens/Amicale/Clubs/ClubDisplayScreen';
import BugReportScreen from '../screens/Other/FeedbackScreen'; import BugReportScreen from '../screens/Other/FeedbackScreen';
@ -63,10 +60,6 @@ import FeedItemScreen from '../screens/Home/FeedItemScreen';
import GroupSelectionScreen from '../screens/Planex/GroupSelectionScreen'; import GroupSelectionScreen from '../screens/Planex/GroupSelectionScreen';
import ServicesSectionScreen from '../screens/Services/ServicesSectionScreen'; import ServicesSectionScreen from '../screens/Services/ServicesSectionScreen';
import AmicaleContactScreen from '../screens/Amicale/AmicaleContactScreen'; import AmicaleContactScreen from '../screens/Amicale/AmicaleContactScreen';
import { FeedItemType } from '../screens/Home/HomeScreen';
import { PlanningEventType } from '../utils/Planning';
import { ServiceCategoryType } from '../utils/Services';
import { ParsedUrlDataType } from '../utils/URLHandler';
export enum MainRoutes { export enum MainRoutes {
Main = 'main', Main = 'main',
@ -84,7 +77,6 @@ export enum MainRoutes {
Proximo = 'proximo', Proximo = 'proximo',
ProximoList = 'proximo-list', ProximoList = 'proximo-list',
ProximoAbout = 'proximo-about', ProximoAbout = 'proximo-about',
ProxiwashAbout = 'proxiwash-about',
Profile = 'profile', Profile = 'profile',
ClubList = 'club-list', ClubList = 'club-list',
ClubInformation = 'club-information', ClubInformation = 'club-information',
@ -95,72 +87,28 @@ export enum MainRoutes {
Vote = 'vote', Vote = 'vote',
Feedback = 'feedback', Feedback = 'feedback',
Website = 'website', Website = 'website',
PlanningInformation = 'planning-information',
Scanner = 'scanner',
FeedInformation = 'feed-information',
GroupSelect = 'group-select',
ServicesSection = 'services-section',
AmicaleContact = 'amicale-contact',
} }
type DefaultParams = { [key in MainRoutes]: object | undefined } & { type DefaultParams = { [key in MainRoutes]: object | undefined };
[key in TabRoutes]: object | undefined;
};
export type MainStackParamsList = DefaultParams & { export type FullParamsList = DefaultParams & {
[MainRoutes.Login]: { nextScreen: string }; 'login': { nextScreen: string };
[MainRoutes.EquipmentConfirm]: { 'equipment-confirm': {
item?: DeviceType; item?: DeviceType;
dates: [string, string]; dates: [string, string];
}; };
[MainRoutes.EquipmentRent]: { item?: DeviceType }; 'equipment-rent': { item?: DeviceType };
[MainRoutes.Gallery]: { images: Array<{ url: string }> }; 'gallery': { images: Array<{ url: string }> };
[MainRoutes.ProximoList]: { [MainRoutes.ProximoList]: {
shouldFocusSearchBar: boolean; shouldFocusSearchBar: boolean;
category: number; category: number;
}; };
[MainRoutes.ClubInformation]: ClubInformationScreenParams;
[MainRoutes.Website]: {
host: string;
path?: string;
title: string;
};
[MainRoutes.FeedInformation]: {
data: FeedItemType;
date: string;
};
[MainRoutes.PlanningInformation]: PlanningInformationScreenParams;
[MainRoutes.ServicesSection]: {
data: ServiceCategoryType;
};
}; };
export type ClubInformationScreenParams = // Don't know why but TS is complaining without this
| { // See: https://stackoverflow.com/questions/63652687/interface-does-not-satisfy-the-constraint-recordstring-object-undefined
type: 'full'; export type MainStackParamsList = FullParamsList &
data: ClubType; Record<string, object | undefined>;
categories: Array<ClubCategoryType>;
}
| {
type: 'id';
clubId: number;
};
export type PlanningInformationScreenParams =
| {
type: 'full';
data: PlanningEventType;
}
| {
type: 'id';
eventId: number;
};
declare global {
namespace ReactNavigation {
interface RootParamList extends MainStackParamsList {}
}
}
const MainStack = createStackNavigator<MainStackParamsList>(); const MainStack = createStackNavigator<MainStackParamsList>();
@ -364,41 +312,41 @@ function getRegularScreens(createTabNavigator: () => React.ReactElement) {
}} }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.ProxiwashAbout} name={'proxiwash-about'}
component={ProxiwashAboutScreen} component={ProxiwashAboutScreen}
options={{ title: i18n.t('screens.proxiwash.title') }} options={{ title: i18n.t('screens.proxiwash.title') }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.PlanningInformation} name={'planning-information'}
component={PlanningDisplayScreen} component={PlanningDisplayScreen}
options={{ title: i18n.t('screens.planning.eventDetails') }} options={{ title: i18n.t('screens.planning.eventDetails') }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.Scanner} name={'scanner'}
component={ScannerScreen} component={ScannerScreen}
options={{ title: i18n.t('screens.scanner.title') }} options={{ title: i18n.t('screens.scanner.title') }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.FeedInformation} name={'feed-information'}
component={FeedItemScreen} component={FeedItemScreen}
options={{ options={{
title: i18n.t('screens.home.feed'), title: i18n.t('screens.home.feed'),
}} }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.GroupSelect} name={'group-select'}
component={GroupSelectionScreen} component={GroupSelectionScreen}
options={{ options={{
title: '', title: '',
}} }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.ServicesSection} name={'services-section'}
component={ServicesSectionScreen} component={ServicesSectionScreen}
options={{ title: 'SECTION' }} options={{ title: 'SECTION' }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.AmicaleContact} name={'amicale-contact'}
component={AmicaleContactScreen} component={AmicaleContactScreen}
options={{ title: i18n.t('screens.amicaleAbout.title') }} options={{ title: i18n.t('screens.amicaleAbout.title') }}
/> />
@ -415,9 +363,7 @@ function MainStackComponent(props: {
return ( return (
<MainStack.Navigator <MainStack.Navigator
initialRouteName={showIntro ? MainRoutes.Intro : MainRoutes.Main} initialRouteName={showIntro ? MainRoutes.Intro : MainRoutes.Main}
screenOptions={{ headerMode={'float'}
headerMode: 'float',
}}
> >
{showIntro ? getIntroScreens() : getRegularScreens(createTabNavigator)} {showIntro ? getIntroScreens() : getRegularScreens(createTabNavigator)}
{isloggedIn ? getAmicaleScreens() : null} {isloggedIn ? getAmicaleScreens() : null}
@ -426,7 +372,8 @@ function MainStackComponent(props: {
} }
type PropsType = { type PropsType = {
defaultData?: ParsedUrlDataType; defaultHomeRoute?: string;
defaultHomeData?: { [key: string]: string };
}; };
function MainNavigator(props: PropsType) { function MainNavigator(props: PropsType) {
@ -448,5 +395,7 @@ function MainNavigator(props: PropsType) {
export default React.memo( export default React.memo(
MainNavigator, MainNavigator,
(pp: PropsType, np: PropsType) => pp.defaultData === np.defaultData (pp: PropsType, np: PropsType) =>
pp.defaultHomeRoute === np.defaultHomeRoute &&
pp.defaultHomeData === np.defaultHomeData
); );

View file

@ -36,7 +36,6 @@ import {
getPreferenceString, getPreferenceString,
GeneralPreferenceKeys, GeneralPreferenceKeys,
} from '../utils/asyncStorage'; } from '../utils/asyncStorage';
import { ParsedUrlDataType } from '../utils/URLHandler';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
header: { header: {
@ -52,24 +51,25 @@ const styles = StyleSheet.create({
}, },
}); });
export enum TabRoutes {
Services = 'services',
Proxiwash = 'proxiwash',
Home = 'home',
Planning = 'events',
Planex = 'planex',
}
type DefaultParams = { [key in TabRoutes]: object | undefined }; type DefaultParams = { [key in TabRoutes]: object | undefined };
export type TabStackParamsList = DefaultParams & { export type FullParamsList = DefaultParams & {
[TabRoutes.Home]: ParsedUrlDataType; [TabRoutes.Home]: {
nextScreen: string;
data: Record<string, object | undefined>;
};
}; };
// Don't know why but TS is complaining without this
// See: https://stackoverflow.com/questions/63652687/interface-does-not-satisfy-the-constraint-recordstring-object-undefined
export type TabStackParamsList = FullParamsList &
Record<string, object | undefined>;
const Tab = createBottomTabNavigator<TabStackParamsList>(); const Tab = createBottomTabNavigator<TabStackParamsList>();
type PropsType = { type PropsType = {
defaultData?: ParsedUrlDataType; defaultHomeRoute?: string;
defaultHomeData?: { [key: string]: string };
}; };
const ICONS: { const ICONS: {
@ -111,6 +111,15 @@ function TabNavigator(props: PropsType) {
} else { } else {
defaultRoute = defaultRoute.toLowerCase(); defaultRoute = defaultRoute.toLowerCase();
} }
let params;
if (props.defaultHomeRoute) {
params = {
data: props.defaultHomeData,
nextScreen: props.defaultHomeRoute,
shouldOpen: true,
};
}
const { colors } = useTheme(); const { colors } = useTheme();
const LABELS: { const LABELS: {
@ -124,23 +133,23 @@ function TabNavigator(props: PropsType) {
}; };
return ( return (
<Tab.Navigator <Tab.Navigator
initialRouteName={defaultRoute as TabRoutes} initialRouteName={defaultRoute}
tabBar={(tabProps) => ( tabBar={(tabProps) => (
<CustomTabBar {...tabProps} labels={LABELS} icons={ICONS} /> <CustomTabBar {...tabProps} labels={LABELS} icons={ICONS} />
)} )}
> >
<Tab.Screen <Tab.Screen
name={TabRoutes.Services} name={'services'}
component={WebsitesHomeScreen} component={WebsitesHomeScreen}
options={{ title: i18n.t('screens.services.title') }} options={{ title: i18n.t('screens.services.title') }}
/> />
<Tab.Screen <Tab.Screen
name={TabRoutes.Proxiwash} name={'proxiwash'}
component={ProxiwashScreen} component={ProxiwashScreen}
options={{ title: i18n.t('screens.proxiwash.title') }} options={{ title: i18n.t('screens.proxiwash.title') }}
/> />
<Tab.Screen <Tab.Screen
name={TabRoutes.Home} name={'home'}
component={HomeScreen} component={HomeScreen}
options={{ options={{
title: i18n.t('screens.home.title'), title: i18n.t('screens.home.title'),
@ -167,15 +176,15 @@ function TabNavigator(props: PropsType) {
</View> </View>
), ),
}} }}
initialParams={props.defaultData} initialParams={params}
/> />
<Tab.Screen <Tab.Screen
name={TabRoutes.Planning} name={'events'}
component={PlanningScreen} component={PlanningScreen}
options={{ title: i18n.t('screens.planning.title') }} options={{ title: i18n.t('screens.planning.title') }}
/> />
<Tab.Screen <Tab.Screen
name={TabRoutes.Planex} name={'planex'}
component={PlanexScreen} component={PlanexScreen}
options={{ options={{
title: i18n.t('screens.planex.title'), title: i18n.t('screens.planex.title'),
@ -187,5 +196,15 @@ function TabNavigator(props: PropsType) {
export default React.memo( export default React.memo(
TabNavigator, TabNavigator,
(pp: PropsType, np: PropsType) => pp.defaultData === np.defaultData (pp: PropsType, np: PropsType) =>
pp.defaultHomeRoute === np.defaultHomeRoute &&
pp.defaultHomeData === np.defaultHomeData
); );
export enum TabRoutes {
Services = 'services',
Proxiwash = 'proxiwash',
Home = 'home',
Planning = 'events',
Planex = 'planex',
}

View file

@ -35,7 +35,6 @@ import OptionsDialog from '../../components/Dialogs/OptionsDialog';
import type { OptionsDialogButtonType } from '../../components/Dialogs/OptionsDialog'; import type { OptionsDialogButtonType } from '../../components/Dialogs/OptionsDialog';
import GENERAL_STYLES from '../../constants/Styles'; import GENERAL_STYLES from '../../constants/Styles';
import Urls from '../../constants/Urls'; import Urls from '../../constants/Urls';
import { MainRoutes } from '../../navigation/MainNavigator';
const APP_LOGO = require('../../../assets/android.icon.round.png'); const APP_LOGO = require('../../../assets/android.icon.round.png');
@ -180,7 +179,7 @@ class AboutScreen extends React.Component<PropsType, StateType> {
{ {
onPressCallback: () => { onPressCallback: () => {
const { navigation } = this.props; const { navigation } = this.props;
navigation.navigate(MainRoutes.Feedback); navigation.navigate('feedback');
}, },
icon: 'bug', icon: 'bug',
text: i18n.t('screens.feedback.homeButtonTitle'), text: i18n.t('screens.feedback.homeButtonTitle'),
@ -237,7 +236,7 @@ class AboutScreen extends React.Component<PropsType, StateType> {
{ {
onPressCallback: () => { onPressCallback: () => {
const { navigation } = this.props; const { navigation } = this.props;
navigation.navigate(MainRoutes.Dependencies); navigation.navigate('dependencies');
}, },
icon: 'developer-board', icon: 'developer-board',
text: i18n.t('screens.about.libs'), text: i18n.t('screens.about.libs'),
@ -276,7 +275,7 @@ class AboutScreen extends React.Component<PropsType, StateType> {
{ {
onPressCallback: () => { onPressCallback: () => {
const { navigation } = this.props; const { navigation } = this.props;
navigation.navigate(MainRoutes.Feedback); navigation.navigate('feedback');
}, },
icon: 'hand-pointing-right', icon: 'hand-pointing-right',
text: i18n.t('screens.about.user.you'), text: i18n.t('screens.about.user.you'),

View file

@ -38,13 +38,16 @@ import { useFocusEffect } from '@react-navigation/core';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { useAuthenticatedRequest } from '../../../context/loginContext'; import { useAuthenticatedRequest } from '../../../context/loginContext';
import { StackScreenProps } from '@react-navigation/stack';
import {
MainRoutes,
MainStackParamsList,
} from '../../../navigation/MainNavigator';
type Props = StackScreenProps<MainStackParamsList, MainRoutes.ClubInformation>; type Props = {
route: {
params?: {
data?: ClubType;
categories?: Array<ClubCategoryType>;
clubId?: number;
};
};
};
type ResponseType = ClubType; type ResponseType = ClubType;
@ -91,19 +94,18 @@ function ClubDisplayScreen(props: Props) {
const theme = useTheme(); const theme = useTheme();
const [displayData, setDisplayData] = useState<ClubType | undefined>(); const [displayData, setDisplayData] = useState<ClubType | undefined>();
const [categories, setCategories] = useState< const [categories, setCategories] =
Array<ClubCategoryType> | undefined useState<Array<ClubCategoryType> | undefined>();
>();
const [clubId, setClubId] = useState<number | undefined>(); const [clubId, setClubId] = useState<number | undefined>();
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
if (props.route.params.type === 'full') { if (props.route.params?.data && props.route.params?.categories) {
setDisplayData(props.route.params.data); setDisplayData(props.route.params.data);
setCategories(props.route.params.categories); setCategories(props.route.params.categories);
setClubId(props.route.params.data.id); setClubId(props.route.params.data.id);
} else { } else {
const id = props.route.params.clubId; const id = props.route.params?.clubId;
setClubId(id ? id : 0); setClubId(id ? id : 0);
} }
}, [props.route.params]) }, [props.route.params])

View file

@ -33,7 +33,6 @@ import MaterialHeaderButtons, {
import WebSectionList from '../../../components/Screens/WebSectionList'; import WebSectionList from '../../../components/Screens/WebSectionList';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { useAuthenticatedRequest } from '../../../context/loginContext'; import { useAuthenticatedRequest } from '../../../context/loginContext';
import { MainRoutes } from '../../../navigation/MainNavigator';
export type ClubCategoryType = { export type ClubCategoryType = {
id: number; id: number;
@ -81,7 +80,7 @@ function ClubListScreen() {
<Item <Item
title="main" title="main"
iconName="information" iconName="information"
onPress={() => navigation.navigate(MainRoutes.ClubAbout)} onPress={() => navigation.navigate('club-about')}
/> />
</MaterialHeaderButtons> </MaterialHeaderButtons>
); );
@ -109,8 +108,7 @@ function ClubListScreen() {
* @param item The article pressed * @param item The article pressed
*/ */
const onListItemPress = (item: ClubType) => { const onListItemPress = (item: ClubType) => {
navigation.navigate(MainRoutes.ClubInformation, { navigation.navigate('club-information', {
type: 'full',
data: item, data: item,
categories: categories.current, categories: categories.current,
}); });

View file

@ -31,15 +31,12 @@ import i18n from 'i18n-js';
import { getRelativeDateString } from '../../../utils/EquipmentBooking'; import { getRelativeDateString } from '../../../utils/EquipmentBooking';
import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView'; import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
import { StackScreenProps } from '@react-navigation/stack'; import { StackScreenProps } from '@react-navigation/stack';
import { import { MainStackParamsList } from '../../../navigation/MainNavigator';
MainRoutes,
MainStackParamsList,
} from '../../../navigation/MainNavigator';
import GENERAL_STYLES from '../../../constants/Styles'; import GENERAL_STYLES from '../../../constants/Styles';
type EquipmentConfirmScreenNavigationProp = StackScreenProps< type EquipmentConfirmScreenNavigationProp = StackScreenProps<
MainStackParamsList, MainStackParamsList,
MainRoutes.EquipmentConfirm 'equipment-confirm'
>; >;
type Props = EquipmentConfirmScreenNavigationProp; type Props = EquipmentConfirmScreenNavigationProp;

View file

@ -60,15 +60,15 @@ const styles = StyleSheet.create({
function EquipmentListScreen() { function EquipmentListScreen() {
const userRents = useRef<undefined | Array<RentedDeviceType>>(); const userRents = useRef<undefined | Array<RentedDeviceType>>();
const [mascotDialogVisible, setMascotDialogVisible] = useState< const [mascotDialogVisible, setMascotDialogVisible] =
undefined | boolean useState<undefined | boolean>(undefined);
>(undefined);
const requestAll = const requestAll =
useAuthenticatedRequest<{ devices: Array<DeviceType> }>('location/all'); useAuthenticatedRequest<{ devices: Array<DeviceType> }>('location/all');
const requestOwn = useAuthenticatedRequest<{ const requestOwn =
locations: Array<RentedDeviceType>; useAuthenticatedRequest<{
}>('location/my'); locations: Array<RentedDeviceType>;
}>('location/my');
const getRenderItem = ({ item }: { item: DeviceType }) => { const getRenderItem = ({ item }: { item: DeviceType }) => {
return ( return (

View file

@ -42,10 +42,7 @@ import {
isEquipmentAvailable, isEquipmentAvailable,
} from '../../../utils/EquipmentBooking'; } from '../../../utils/EquipmentBooking';
import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView'; import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
import { import { MainStackParamsList } from '../../../navigation/MainNavigator';
MainRoutes,
MainStackParamsList,
} from '../../../navigation/MainNavigator';
import GENERAL_STYLES from '../../../constants/Styles'; import GENERAL_STYLES from '../../../constants/Styles';
import { ApiRejectType } from '../../../utils/WebData'; import { ApiRejectType } from '../../../utils/WebData';
import { REQUEST_STATUS } from '../../../utils/Requests'; import { REQUEST_STATUS } from '../../../utils/Requests';
@ -53,7 +50,7 @@ import { useFocusEffect } from '@react-navigation/core';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { useAuthenticatedRequest } from '../../../context/loginContext'; import { useAuthenticatedRequest } from '../../../context/loginContext';
type Props = StackScreenProps<MainStackParamsList, MainRoutes.EquipmentRent>; type Props = StackScreenProps<MainStackParamsList, 'equipment-rent'>;
export type MarkedDatesObjectType = { export type MarkedDatesObjectType = {
[key: string]: PeriodMarking; [key: string]: PeriodMarking;

View file

@ -26,10 +26,7 @@ import ErrorDialog from '../../components/Dialogs/ErrorDialog';
import { MASCOT_STYLE } from '../../components/Mascot/Mascot'; import { MASCOT_STYLE } from '../../components/Mascot/Mascot';
import MascotPopup from '../../components/Mascot/MascotPopup'; import MascotPopup from '../../components/Mascot/MascotPopup';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView'; import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
import { import { MainStackParamsList } from '../../navigation/MainNavigator';
MainRoutes,
MainStackParamsList,
} from '../../navigation/MainNavigator';
import GENERAL_STYLES from '../../constants/Styles'; import GENERAL_STYLES from '../../constants/Styles';
import Urls from '../../constants/Urls'; import Urls from '../../constants/Urls';
import { ApiRejectType, connectToAmicale } from '../../utils/WebData'; import { ApiRejectType, connectToAmicale } from '../../utils/WebData';
@ -40,16 +37,15 @@ import { TabRoutes } from '../../navigation/TabNavigator';
import { useShouldShowMascot } from '../../context/preferencesContext'; import { useShouldShowMascot } from '../../context/preferencesContext';
import { useLogin } from '../../context/loginContext'; import { useLogin } from '../../context/loginContext';
type Props = StackScreenProps<MainStackParamsList, MainRoutes.Login>; type Props = StackScreenProps<MainStackParamsList, 'login'>;
function LoginScreen(props: Props) { function LoginScreen(props: Props) {
const navigation = useNavigation<StackNavigationProp<any>>(); const navigation = useNavigation<StackNavigationProp<any>>();
const { setLogin } = useLogin(); const { setLogin } = useLogin();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [nextScreen, setNextScreen] = useState<string | undefined>(undefined); const [nextScreen, setNextScreen] = useState<string | undefined>(undefined);
const [mascotDialogVisible, setMascotDialogVisible] = useState< const [mascotDialogVisible, setMascotDialogVisible] =
undefined | boolean useState<undefined | boolean>(undefined);
>(undefined);
const [currentError, setCurrentError] = useState<ApiRejectType>({ const [currentError, setCurrentError] = useState<ApiRejectType>({
status: REQUEST_STATUS.SUCCESS, status: REQUEST_STATUS.SUCCESS,
}); });
@ -62,7 +58,7 @@ function LoginScreen(props: Props) {
); );
const onResetPasswordClick = () => { const onResetPasswordClick = () => {
navigation.navigate(MainRoutes.Website, { navigation.navigate('website', {
host: Urls.websites.amicale, host: Urls.websites.amicale,
path: Urls.amicale.resetPassword, path: Urls.amicale.resetPassword,
title: i18n.t('screens.websites.amicale'), title: i18n.t('screens.websites.amicale'),

View file

@ -133,9 +133,8 @@ const styles = StyleSheet.create({
*/ */
export default function VoteScreen() { export default function VoteScreen() {
const [hasVoted, setHasVoted] = useState(false); const [hasVoted, setHasVoted] = useState(false);
const [mascotDialogVisible, setMascotDialogVisible] = useState< const [mascotDialogVisible, setMascotDialogVisible] =
undefined | boolean useState<undefined | boolean>(undefined);
>(undefined);
const datesRequest = const datesRequest =
useAuthenticatedRequest<VoteDatesStringType>('elections/dates'); useAuthenticatedRequest<VoteDatesStringType>('elections/dates');

View file

@ -79,12 +79,13 @@ export default function GameMainScreen() {
gameLevel: 0, gameLevel: 0,
}); });
const [dialogContent, setDialogContent] = useState<{ const [dialogContent, setDialogContent] =
dialogTitle: string; useState<{
dialogMessage: string; dialogTitle: string;
dialogButtons: Array<OptionsDialogButtonType>; dialogMessage: string;
onDialogDismiss: () => void; dialogButtons: Array<OptionsDialogButtonType>;
}>(); onDialogDismiss: () => void;
}>();
const { preferences, updatePreferences } = usePreferences(); const { preferences, updatePreferences } = usePreferences();

View file

@ -21,7 +21,7 @@ import * as React from 'react';
import { Linking, Image, StyleSheet } from 'react-native'; import { Linking, Image, StyleSheet } from 'react-native';
import { Card, Text } from 'react-native-paper'; import { Card, Text } from 'react-native-paper';
import Autolink from 'react-native-autolink'; import Autolink from 'react-native-autolink';
import { StackScreenProps } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import MaterialHeaderButtons, { import MaterialHeaderButtons, {
Item, Item,
} from '../../components/Overrides/CustomHeaderButton'; } from '../../components/Overrides/CustomHeaderButton';
@ -33,15 +33,11 @@ import NewsSourcesConstants, {
AvailablePages, AvailablePages,
} from '../../constants/NewsSourcesConstants'; } from '../../constants/NewsSourcesConstants';
import type { NewsSourceType } from '../../constants/NewsSourcesConstants'; import type { NewsSourceType } from '../../constants/NewsSourcesConstants';
import {
MainRoutes,
MainStackParamsList,
} from '../../navigation/MainNavigator';
type PropsType = StackScreenProps< type PropsType = {
MainStackParamsList, navigation: StackNavigationProp<any>;
MainRoutes.FeedInformation route: { params: { data: FeedItemType; date: string } };
>; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {

View file

@ -154,7 +154,7 @@ function HomeScreen(props: Props) {
useLayoutEffect(() => { useLayoutEffect(() => {
const getHeaderButton = () => { const getHeaderButton = () => {
let onPressLog = () => let onPressLog = () =>
navigation.navigate(MainRoutes.Login, { nextScreen: 'profile' }); navigation.navigate('login', { nextScreen: 'profile' });
let logIcon = 'login'; let logIcon = 'login';
let logColor = theme.colors.primary; let logColor = theme.colors.primary;
if (isLoggedIn) { if (isLoggedIn) {
@ -190,8 +190,8 @@ function HomeScreen(props: Props) {
const handleNavigationParams = () => { const handleNavigationParams = () => {
const { route } = props; const { route } = props;
if (route.params != null) { if (route.params != null) {
if (route.params.route != null) { if (route.params.nextScreen != null) {
navigation.navigate(route.params.route, route.params.data); navigation.navigate(route.params.nextScreen, route.params.data);
// reset params to prevent infinite loop // reset params to prevent infinite loop
navigation.dispatch(CommonActions.setParams({ nextScreen: null })); navigation.dispatch(CommonActions.setParams({ nextScreen: null }));
} }
@ -328,7 +328,7 @@ function HomeScreen(props: Props) {
const hideDisconnectDialog = () => setDialogVisible(false); const hideDisconnectDialog = () => setDialogVisible(false);
const openScanner = () => navigation.navigate(MainRoutes.Scanner); const openScanner = () => navigation.navigate('scanner');
/** /**
* Creates the dataset to be used in the FlatList * Creates the dataset to be used in the FlatList

View file

@ -13,13 +13,13 @@ import { Platform, SafeAreaView, View } from 'react-native';
import { useDarkTheme } from '../context/preferencesContext'; import { useDarkTheme } from '../context/preferencesContext';
import { CustomDarkTheme, CustomWhiteTheme } from '../utils/Themes'; import { CustomDarkTheme, CustomWhiteTheme } from '../utils/Themes';
import { setupStatusBar } from '../utils/Utils'; import { setupStatusBar } from '../utils/Utils';
import { ParsedUrlDataType } from '../utils/URLHandler';
type Props = { type Props = {
defaultData?: ParsedUrlDataType; defaultHomeRoute?: string;
defaultHomeData?: { [key: string]: string };
}; };
function MainApp(props: Props, ref?: Ref<NavigationContainerRef<any>>) { function MainApp(props: Props, ref?: Ref<NavigationContainerRef>) {
const darkTheme = useDarkTheme(); const darkTheme = useDarkTheme();
const theme = darkTheme ? CustomDarkTheme : CustomWhiteTheme; const theme = darkTheme ? CustomDarkTheme : CustomWhiteTheme;
@ -44,7 +44,10 @@ function MainApp(props: Props, ref?: Ref<NavigationContainerRef<any>>) {
> >
<SafeAreaView style={GENERAL_STYLES.flex}> <SafeAreaView style={GENERAL_STYLES.flex}>
<NavigationContainer theme={theme} ref={ref}> <NavigationContainer theme={theme} ref={ref}>
<MainNavigator defaultData={props.defaultData} /> <MainNavigator
defaultHomeRoute={props.defaultHomeRoute}
defaultHomeData={props.defaultHomeData}
/>
</NavigationContainer> </NavigationContainer>
</SafeAreaView> </SafeAreaView>
</View> </View>

View file

@ -23,14 +23,11 @@ import ImageViewer from 'react-native-image-zoom-viewer';
import { StackNavigationProp, StackScreenProps } from '@react-navigation/stack'; import { StackNavigationProp, StackScreenProps } from '@react-navigation/stack';
import * as Animatable from 'react-native-animatable'; import * as Animatable from 'react-native-animatable';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import { import { MainStackParamsList } from '../../navigation/MainNavigator';
MainRoutes,
MainStackParamsList,
} from '../../navigation/MainNavigator';
type ImageGalleryScreenNavigationProp = StackScreenProps< type ImageGalleryScreenNavigationProp = StackScreenProps<
MainStackParamsList, MainStackParamsList,
MainRoutes.Gallery 'gallery'
>; >;
type Props = ImageGalleryScreenNavigationProp & { type Props = ImageGalleryScreenNavigationProp & {

View file

@ -149,7 +149,6 @@ function DashboardEditScreen() {
return ( return (
<CollapsibleFlatList <CollapsibleFlatList
//@ts-ignore
data={getCategories(navigation.navigate, isLoggedIn)} data={getCategories(navigation.navigate, isLoggedIn)}
renderItem={getRenderItem} renderItem={getRenderItem}
ListHeaderComponent={getListHeader()} ListHeaderComponent={getListHeader()}

View file

@ -44,7 +44,6 @@ import {
GeneralPreferenceKeys, GeneralPreferenceKeys,
ProxiwashPreferenceKeys, ProxiwashPreferenceKeys,
} from '../../../utils/asyncStorage'; } from '../../../utils/asyncStorage';
import { MainRoutes } from '../../../navigation/MainNavigator';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
slider: { slider: {
@ -205,7 +204,7 @@ function SettingsScreen() {
}; };
const getNavigateItem = ( const getNavigateItem = (
route: MainRoutes, route: string,
icon: string, icon: string,
title: string, title: string,
subtitle: string, subtitle: string,
@ -284,7 +283,7 @@ function SettingsScreen() {
/> />
{getStartScreenPicker()} {getStartScreenPicker()}
{getNavigateItem( {getNavigateItem(
MainRoutes.DashboardEdit, 'dashboard-edit',
'view-dashboard', 'view-dashboard',
i18n.t('screens.settings.dashboard'), i18n.t('screens.settings.dashboard'),
i18n.t('screens.settings.dashboardSub') i18n.t('screens.settings.dashboardSub')
@ -329,21 +328,21 @@ function SettingsScreen() {
<List.Section> <List.Section>
{isDebugUnlocked {isDebugUnlocked
? getNavigateItem( ? getNavigateItem(
MainRoutes.Debug, 'debug',
'bug-check', 'bug-check',
i18n.t('screens.debug.title'), i18n.t('screens.debug.title'),
'' ''
) )
: null} : null}
{getNavigateItem( {getNavigateItem(
MainRoutes.About, 'about',
'information', 'information',
i18n.t('screens.about.title'), i18n.t('screens.about.title'),
i18n.t('screens.about.buttonDesc'), i18n.t('screens.about.buttonDesc'),
unlockDebugMode unlockDebugMode
)} )}
{getNavigateItem( {getNavigateItem(
MainRoutes.Feedback, 'feedback',
'comment-quote', 'comment-quote',
i18n.t('screens.feedback.homeButtonTitle'), i18n.t('screens.feedback.homeButtonTitle'),
i18n.t('screens.feedback.homeButtonSubtitle') i18n.t('screens.feedback.homeButtonSubtitle')

View file

@ -42,7 +42,6 @@ import {
} from '../../utils/asyncStorage'; } from '../../utils/asyncStorage';
import { usePlanexPreferences } from '../../context/preferencesContext'; import { usePlanexPreferences } from '../../context/preferencesContext';
import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen'; import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen';
import { MainRoutes } from '../../navigation/MainNavigator';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -60,14 +59,15 @@ function PlanexScreen() {
const theme = useTheme(); const theme = useTheme();
const { preferences } = usePlanexPreferences(); const { preferences } = usePlanexPreferences();
const [dialogContent, setDialogContent] = useState< const [dialogContent, setDialogContent] =
| undefined useState<
| { | undefined
title: string | React.ReactElement; | {
message: string | React.ReactElement; title: string | React.ReactElement;
color: string; message: string | React.ReactElement;
} color: string;
>(); }
>();
const [injectJS, setInjectJS] = useState(''); const [injectJS, setInjectJS] = useState('');
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@ -106,7 +106,7 @@ function PlanexScreen() {
* Callback used when the user clicks on the navigate to settings button. * Callback used when the user clicks on the navigate to settings button.
* This will hide the banner and open the SettingsScreen * This will hide the banner and open the SettingsScreen
*/ */
const onGoToSettings = () => navigation.navigate(MainRoutes.Settings); const onGoToSettings = () => navigation.navigate('settings');
/** /**
* Sends a FullCalendar action to the web page inside the webview. * Sends a FullCalendar action to the web page inside the webview.

View file

@ -21,7 +21,7 @@ import * as React from 'react';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import { Card } from 'react-native-paper'; import { Card } from 'react-native-paper';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
import { StackScreenProps } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import { getDateOnlyString, getTimeOnlyString } from '../../utils/Planning'; import { getDateOnlyString, getTimeOnlyString } from '../../utils/Planning';
import DateManager from '../../managers/DateManager'; import DateManager from '../../managers/DateManager';
import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen'; import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen';
@ -33,15 +33,11 @@ import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrol
import type { PlanningEventType } from '../../utils/Planning'; import type { PlanningEventType } from '../../utils/Planning';
import ImageGalleryButton from '../../components/Media/ImageGalleryButton'; import ImageGalleryButton from '../../components/Media/ImageGalleryButton';
import { API_REQUEST_CODES, REQUEST_STATUS } from '../../utils/Requests'; import { API_REQUEST_CODES, REQUEST_STATUS } from '../../utils/Requests';
import {
MainRoutes,
MainStackParamsList,
} from '../../navigation/MainNavigator';
type PropsType = StackScreenProps< type PropsType = {
MainStackParamsList, navigation: StackNavigationProp<any>;
MainRoutes.PlanningInformation route: { params: { data: PlanningEventType; id: number; eventId: number } };
>; };
type StateType = { type StateType = {
loading: boolean; loading: boolean;
@ -82,7 +78,7 @@ class PlanningDisplayScreen extends React.Component<PropsType, StateType> {
constructor(props: PropsType) { constructor(props: PropsType) {
super(props); super(props);
if (props.route.params.type === 'full') { if (props.route.params.data != null) {
this.displayData = props.route.params.data; this.displayData = props.route.params.data;
this.eventId = this.displayData.id; this.eventId = this.displayData.id;
this.shouldFetchData = false; this.shouldFetchData = false;

View file

@ -36,7 +36,6 @@ import { MASCOT_STYLE } from '../../components/Mascot/Mascot';
import MascotPopup from '../../components/Mascot/MascotPopup'; import MascotPopup from '../../components/Mascot/MascotPopup';
import GENERAL_STYLES from '../../constants/Styles'; import GENERAL_STYLES from '../../constants/Styles';
import Urls from '../../constants/Urls'; import Urls from '../../constants/Urls';
import { MainRoutes } from '../../navigation/MainNavigator';
LocaleConfig.locales.fr = { LocaleConfig.locales.fr = {
monthNames: [ monthNames: [
@ -218,7 +217,7 @@ class PlanningScreen extends React.Component<PropsType, StateType> {
getRenderItem = (item: PlanningEventType) => { getRenderItem = (item: PlanningEventType) => {
const { navigation } = this.props; const { navigation } = this.props;
const onPress = () => { const onPress = () => {
navigation.navigate(MainRoutes.PlanningInformation, { navigation.navigate('planning-information', {
data: item, data: item,
}); });
}; };

View file

@ -61,7 +61,6 @@ import {
} from '../../utils/asyncStorage'; } from '../../utils/asyncStorage';
import { useProxiwashPreferences } from '../../context/preferencesContext'; import { useProxiwashPreferences } from '../../context/preferencesContext';
import { useSubsequentEffect } from '../../utils/customHooks'; import { useSubsequentEffect } from '../../utils/customHooks';
import { MainRoutes } from '../../navigation/MainNavigator';
const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
const LIST_ITEM_HEIGHT = 64; const LIST_ITEM_HEIGHT = 64;
@ -171,7 +170,7 @@ function ProxiwashScreen() {
<Item <Item
title={'information'} title={'information'}
iconName={'information'} iconName={'information'}
onPress={() => navigation.navigate(MainRoutes.ProxiwashAbout)} onPress={() => navigation.navigate('proxiwash-about')}
/> />
</MaterialHeaderButtons> </MaterialHeaderButtons>
), ),
@ -495,7 +494,7 @@ function ProxiwashScreen() {
action: { action: {
message: i18n.t('screens.proxiwash.mascotDialog.ok'), message: i18n.t('screens.proxiwash.mascotDialog.ok'),
icon: 'cog', icon: 'cog',
onPress: () => navigation.navigate(MainRoutes.Settings), onPress: () => navigation.navigate('settings'),
}, },
cancel: { cancel: {
message: i18n.t('screens.proxiwash.mascotDialog.cancel'), message: i18n.t('screens.proxiwash.mascotDialog.cancel'),

View file

@ -123,9 +123,8 @@ function ProximoListScreen(props: Props) {
const [currentSearchString, setCurrentSearchString] = useState(''); const [currentSearchString, setCurrentSearchString] = useState('');
const [currentSortMode, setCurrentSortMode] = useState(2); const [currentSortMode, setCurrentSortMode] = useState(2);
const [modalCurrentDisplayItem, setModalCurrentDisplayItem] = useState< const [modalCurrentDisplayItem, setModalCurrentDisplayItem] =
React.ReactChild | undefined useState<React.ReactChild | undefined>();
>();
const sortModes = [sortPrice, sortPriceReverse, sortName, sortNameReverse]; const sortModes = [sortPrice, sortPriceReverse, sortName, sortNameReverse];

View file

@ -32,7 +32,6 @@ import { useNavigation } from '@react-navigation/core';
import { useLayoutEffect } from 'react'; import { useLayoutEffect } from 'react';
import { useCachedProximoCategories } from '../../../context/cacheContext'; import { useCachedProximoCategories } from '../../../context/cacheContext';
import GENERAL_STYLES from '../../../constants/Styles'; import GENERAL_STYLES from '../../../constants/Styles';
import { MainRoutes } from '../../../navigation/MainNavigator';
const LIST_ITEM_HEIGHT = 84; const LIST_ITEM_HEIGHT = 84;
@ -123,10 +122,10 @@ function ProximoMainScreen() {
shouldFocusSearchBar: true, shouldFocusSearchBar: true,
category: -1, category: -1,
}; };
navigation.navigate(MainRoutes.ProximoList, searchScreenData); navigation.navigate('proximo-list', searchScreenData);
}; };
const onPressAboutBtn = () => navigation.navigate(MainRoutes.ProximoAbout); const onPressAboutBtn = () => navigation.navigate('proximo-about');
const getHeaderButtons = () => { const getHeaderButtons = () => {
return ( return (
@ -171,8 +170,7 @@ function ProximoMainScreen() {
? i18n.t('screens.proximo.articles') ? i18n.t('screens.proximo.articles')
: i18n.t('screens.proximo.article') : i18n.t('screens.proximo.article')
}`; }`;
const onPress = () => const onPress = () => navigation.navigate('proximo-list', dataToSend);
navigation.navigate(MainRoutes.ProximoList, dataToSend);
if (article_number > 0) { if (article_number > 0) {
return ( return (
<List.Item <List.Item

View file

@ -42,7 +42,6 @@ import {
} from '../../utils/Services'; } from '../../utils/Services';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { useLoginState } from '../../context/loginContext'; import { useLoginState } from '../../context/loginContext';
import { MainRoutes } from '../../navigation/MainNavigator';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -63,7 +62,6 @@ function ServicesScreen() {
const theme = useTheme(); const theme = useTheme();
const isLoggedIn = useLoginState(); const isLoggedIn = useLoginState();
//@ts-ignore
const finalDataset = getCategories(navigation.navigate, isLoggedIn, [ const finalDataset = getCategories(navigation.navigate, isLoggedIn, [
SERVICES_CATEGORIES_KEY.SPECIAL, SERVICES_CATEGORIES_KEY.SPECIAL,
]); ]);
@ -74,7 +72,7 @@ function ServicesScreen() {
<Item <Item
title="information" title="information"
iconName="information" iconName="information"
onPress={() => navigation.navigate(MainRoutes.AmicaleContact)} onPress={() => navigation.navigate('amicale-contact')}
/> />
</MaterialHeaderButtons> </MaterialHeaderButtons>
); );
@ -116,9 +114,7 @@ function ServicesScreen() {
return ( return (
<TouchableRipple <TouchableRipple
style={styles.container} style={styles.container}
onPress={() => onPress={() => navigation.navigate('services-section', { data: item })}
navigation.navigate(MainRoutes.ServicesSection, { data: item })
}
> >
<View> <View>
<Card.Title <Card.Title

View file

@ -18,19 +18,17 @@
*/ */
import * as React from 'react'; import * as React from 'react';
import { Collapsible } from 'react-navigation-collapsible';
import { CommonActions } from '@react-navigation/native'; import { CommonActions } from '@react-navigation/native';
import { StackScreenProps } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import CardList from '../../components/Lists/CardList/CardList'; import CardList from '../../components/Lists/CardList/CardList';
import { ServiceCategoryType } from '../../utils/Services'; import { ServiceCategoryType } from '../../utils/Services';
import {
MainRoutes,
MainStackParamsList,
} from '../../navigation/MainNavigator';
type PropsType = StackScreenProps< type PropsType = {
MainStackParamsList, navigation: StackNavigationProp<any>;
MainRoutes.ServicesSection route: { params: { data: ServiceCategoryType | null } };
>; collapsibleStack: Collapsible;
};
class ServicesSectionScreen extends React.Component<PropsType> { class ServicesSectionScreen extends React.Component<PropsType> {
finalDataset: null | ServiceCategoryType; finalDataset: null | ServiceCategoryType;

View file

@ -18,16 +18,15 @@
*/ */
import * as React from 'react'; import * as React from 'react';
import { StackScreenProps } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import WebViewScreen from '../../components/Screens/WebViewScreen'; import WebViewScreen from '../../components/Screens/WebViewScreen';
import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen'; import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen';
import Urls from '../../constants/Urls'; import Urls from '../../constants/Urls';
import {
MainRoutes,
MainStackParamsList,
} from '../../navigation/MainNavigator';
type Props = StackScreenProps<MainStackParamsList, MainRoutes.Website>; type Props = {
navigation: StackNavigationProp<any>;
route: { params: { host: string; path: string | null; title: string } };
};
type State = { type State = {
url: string; url: string;

View file

@ -87,8 +87,8 @@ export type ServiceCategoryType = {
}; };
function getAmicaleOnPress( function getAmicaleOnPress(
route: MainRoutes, route: string,
onPress: (route: MainRoutes, params?: { [key: string]: any }) => void, onPress: (route: string, params?: { [key: string]: any }) => void,
isLoggedIn: boolean isLoggedIn: boolean
) { ) {
if (isLoggedIn) { if (isLoggedIn) {
@ -99,7 +99,7 @@ function getAmicaleOnPress(
} }
export function getAmicaleServices( export function getAmicaleServices(
onPress: (route: MainRoutes, params?: { [key: string]: any }) => void, onPress: (route: string, params?: { [key: string]: any }) => void,
isLoggedIn: boolean, isLoggedIn: boolean,
excludedItems?: Array<string> excludedItems?: Array<string>
): Array<ServiceItemType> { ): Array<ServiceItemType> {
@ -148,7 +148,7 @@ export function getAmicaleServices(
} }
export function getStudentServices( export function getStudentServices(
onPress: (route: MainRoutes, params?: { [key: string]: any }) => void, onPress: (route: string, params?: { [key: string]: any }) => void,
excludedItems?: Array<string> excludedItems?: Array<string>
): Array<ServiceItemType> { ): Array<ServiceItemType> {
const studentsDataset = [ const studentsDataset = [
@ -201,7 +201,7 @@ export function getStudentServices(
} }
export function getINSAServices( export function getINSAServices(
onPress: (route: MainRoutes, params?: { [key: string]: any }) => void, onPress: (route: string, params?: { [key: string]: any }) => void,
excludedItems?: Array<string> excludedItems?: Array<string>
): Array<ServiceItemType> { ): Array<ServiceItemType> {
const insaDataset = [ const insaDataset = [
@ -274,10 +274,7 @@ export function getINSAServices(
} }
export function getSpecialServices( export function getSpecialServices(
onPress: ( onPress: (route: string, params?: { [key: string]: any }) => void,
route: MainRoutes | TabRoutes,
params?: { [key: string]: any }
) => void,
excludedItems?: Array<string> excludedItems?: Array<string>
): Array<ServiceItemType> { ): Array<ServiceItemType> {
const specialDataset = [ const specialDataset = [
@ -304,10 +301,7 @@ export function getSpecialServices(
} }
export function getCategories( export function getCategories(
onPress: ( onPress: (route: string, params?: { [key: string]: any }) => void,
route: MainRoutes | TabRoutes,
params?: { [key: string]: any }
) => void,
isLoggedIn: boolean, isLoggedIn: boolean,
excludedItems?: Array<string> excludedItems?: Array<string>
): Array<ServiceCategoryType> { ): Array<ServiceCategoryType> {

View file

@ -18,15 +18,10 @@
*/ */
import { Linking } from 'react-native'; import { Linking } from 'react-native';
import {
ClubInformationScreenParams,
MainRoutes,
PlanningInformationScreenParams,
} from '../navigation/MainNavigator';
export type ParsedUrlDataType = { export type ParsedUrlDataType = {
route: MainRoutes.ClubInformation | MainRoutes.PlanningInformation; route: string;
data: ClubInformationScreenParams | PlanningInformationScreenParams; data: { [key: string]: string };
}; };
export type ParsedUrlCallbackType = (parsedData: ParsedUrlDataType) => void; export type ParsedUrlCallbackType = (parsedData: ParsedUrlDataType) => void;
@ -46,6 +41,10 @@ export default class URLHandler {
static EVENT_INFO_URL_PATH = 'event'; static EVENT_INFO_URL_PATH = 'event';
static CLUB_INFO_ROUTE = 'club-information';
static EVENT_INFO_ROUTE = 'planning-information';
onInitialURLParsed: ParsedUrlCallbackType; onInitialURLParsed: ParsedUrlCallbackType;
onDetectURL: ParsedUrlCallbackType; onDetectURL: ParsedUrlCallbackType;
@ -153,11 +152,8 @@ export default class URLHandler {
const id = parseInt(params.id, 10); const id = parseInt(params.id, 10);
if (!Number.isNaN(id)) { if (!Number.isNaN(id)) {
return { return {
route: MainRoutes.ClubInformation, route: URLHandler.CLUB_INFO_ROUTE,
data: { data: { clubId: id.toString() },
type: 'id',
clubId: id,
},
}; };
} }
} }
@ -177,11 +173,8 @@ export default class URLHandler {
const id = parseInt(params.id, 10); const id = parseInt(params.id, 10);
if (!Number.isNaN(id)) { if (!Number.isNaN(id)) {
return { return {
route: MainRoutes.PlanningInformation, route: URLHandler.EVENT_INFO_ROUTE,
data: { data: { eventId: id.toString() },
type: 'id',
eventId: id,
},
}; };
} }
} }