Compare commits

..

No commits in common. "4d0df7a5b7d7f8b33893b5a7a9f06d01bc86253d" and "300558ac56438a60312ed9e73abf0634f7ce1d75" have entirely different histories.

11 changed files with 413 additions and 402 deletions

View file

@ -22,7 +22,7 @@ import {TouchableRipple, useTheme} from 'react-native-paper';
import {Dimensions, Image, View} from 'react-native'; import {Dimensions, Image, View} from 'react-native';
type PropsType = { type PropsType = {
image?: string | number; image: string;
isActive: boolean; isActive: boolean;
onPress: () => void; onPress: () => void;
}; };
@ -51,17 +51,13 @@ function DashboardEditPreviewItem(props: PropsType) {
width: itemSize, width: itemSize,
height: itemSize, height: itemSize,
}}> }}>
{props.image ? (
<Image <Image
source={ source={{uri: props.image}}
typeof props.image === 'string' ? {uri: props.image} : props.image
}
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
}} }}
/> />
) : null}
</View> </View>
</TouchableRipple> </TouchableRipple>
); );

View file

@ -21,22 +21,36 @@ import * as React from 'react';
import {Animated} from 'react-native'; import {Animated} from 'react-native';
import {withTheme} from 'react-native-paper'; import {withTheme} from 'react-native-paper';
import {Collapsible} from 'react-navigation-collapsible'; import {Collapsible} from 'react-navigation-collapsible';
import {StackNavigationProp} from '@react-navigation/stack';
import TabIcon from './TabIcon'; import TabIcon from './TabIcon';
import TabHomeIcon from './TabHomeIcon'; import TabHomeIcon from './TabHomeIcon';
import {BottomTabBarProps} from '@react-navigation/bottom-tabs';
import {NavigationState} from '@react-navigation/native';
import {
PartialState,
Route,
} from '@react-navigation/routers/lib/typescript/src/types';
type RouteType = Route<string> & { type RouteType = {
state?: NavigationState | PartialState<NavigationState>; name: string;
key: string;
params: {collapsible: Collapsible};
state: {
index: number;
routes: Array<RouteType>;
};
}; };
interface PropsType extends BottomTabBarProps { type PropsType = {
state: {
index: number;
routes: Array<RouteType>;
};
descriptors: {
[key: string]: {
options: {
tabBarLabel: string;
title: string;
};
};
};
navigation: StackNavigationProp<any>;
theme: ReactNativePaper.Theme; theme: ReactNativePaper.Theme;
} };
type StateType = { type StateType = {
translateY: any; translateY: any;
@ -150,7 +164,7 @@ class CustomTabBar extends React.Component<PropsType, StateType> {
onLongPress={onLongPress} onLongPress={onLongPress}
icon={this.getTabBarIcon(route, isFocused)} icon={this.getTabBarIcon(route, isFocused)}
color={color} color={color}
label={label as string} label={label}
focused={isFocused} focused={isFocused}
extraData={state.index > index} extraData={state.index > index}
key={route.key} key={route.key}
@ -179,12 +193,9 @@ class CustomTabBar extends React.Component<PropsType, StateType> {
if (isFocused) { if (isFocused) {
const stackState = route.state; const stackState = route.state;
const stackRoute = const stackRoute =
stackState && stackState.index stackState != null ? stackState.routes[stackState.index] : null;
? stackState.routes[stackState.index] const params: {collapsible: Collapsible} | null =
: null; stackRoute != null ? stackRoute.params : null;
const params: {collapsible: Collapsible} | null | undefined = stackRoute
? (stackRoute.params as {collapsible: Collapsible})
: null;
const collapsible = params != null ? params.collapsible : null; const collapsible = params != null ? params.collapsible : null;
if (collapsible != null) { if (collapsible != null) {
this.setState({ this.setState({

View file

@ -17,6 +17,8 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {createStackNavigator, TransitionPresets} from '@react-navigation/stack'; import {createStackNavigator, TransitionPresets} from '@react-navigation/stack';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
@ -38,63 +40,18 @@ import ClubListScreen 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 { import {
CreateScreenCollapsibleStack, createScreenCollapsibleStack,
getWebsiteStack, getWebsiteStack,
} from '../utils/CollapsibleUtils'; } from '../utils/CollapsibleUtils';
import BugReportScreen from '../screens/Other/FeedbackScreen'; import BugReportScreen from '../screens/Other/FeedbackScreen';
import WebsiteScreen from '../screens/Services/WebsiteScreen'; import WebsiteScreen from '../screens/Services/WebsiteScreen';
import EquipmentScreen, { import EquipmentScreen from '../screens/Amicale/Equipment/EquipmentListScreen';
DeviceType,
} from '../screens/Amicale/Equipment/EquipmentListScreen';
import EquipmentLendScreen from '../screens/Amicale/Equipment/EquipmentRentScreen'; import EquipmentLendScreen from '../screens/Amicale/Equipment/EquipmentRentScreen';
import EquipmentConfirmScreen from '../screens/Amicale/Equipment/EquipmentConfirmScreen'; import EquipmentConfirmScreen from '../screens/Amicale/Equipment/EquipmentConfirmScreen';
import DashboardEditScreen from '../screens/Other/Settings/DashboardEditScreen'; import DashboardEditScreen from '../screens/Other/Settings/DashboardEditScreen';
import GameStartScreen from '../screens/Game/screens/GameStartScreen'; import GameStartScreen from '../screens/Game/screens/GameStartScreen';
import ImageGalleryScreen from '../screens/Media/ImageGalleryScreen'; import ImageGalleryScreen from '../screens/Media/ImageGalleryScreen';
export enum MainRoutes {
Main = 'main',
Gallery = 'gallery',
Settings = 'settings',
DashboardEdit = 'dashboard-edit',
About = 'about',
Dependencies = 'dependencies',
Debug = 'debug',
GameStart = 'game-start',
GameMain = 'game-main',
Login = 'login',
SelfMenu = 'self-menu',
Proximo = 'proximo',
ProximoList = 'proximo-list',
ProximoAbout = 'proximo-about',
Profile = 'profile',
ClubList = 'club-list',
ClubInformation = 'club-information',
ClubAbout = 'club-about',
EquipmentList = 'equipment-list',
EquipmentRent = 'equipment-rent',
EquipmentConfirm = 'equipment-confirm',
Vote = 'vote',
Feedback = 'feedback',
}
type DefaultParams = {[key in MainRoutes]: object | undefined};
export interface FullParamsList extends DefaultParams {
login: {nextScreen: string};
'equipment-confirm': {
item?: DeviceType;
dates: [string, string];
};
'equipment-rent': {item?: DeviceType};
gallery: {images: Array<{url: string}>};
}
// 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 MainStackParamsList = FullParamsList &
Record<string, object | undefined>;
const modalTransition = const modalTransition =
Platform.OS === 'ios' Platform.OS === 'ios'
? TransitionPresets.ModalPresentationIOS ? TransitionPresets.ModalPresentationIOS
@ -106,17 +63,19 @@ const defaultScreenOptions = {
...TransitionPresets.SlideFromRightIOS, ...TransitionPresets.SlideFromRightIOS,
}; };
const MainStack = createStackNavigator<MainStackParamsList>(); const MainStack = createStackNavigator();
function MainStackComponent(props: {createTabNavigator: () => JSX.Element}) { function MainStackComponent(props: {
createTabNavigator: () => React.Node,
}): React.Node {
const {createTabNavigator} = props; const {createTabNavigator} = props;
return ( return (
<MainStack.Navigator <MainStack.Navigator
initialRouteName={MainRoutes.Main} initialRouteName="main"
headerMode="screen" headerMode="screen"
screenOptions={defaultScreenOptions}> screenOptions={defaultScreenOptions}>
<MainStack.Screen <MainStack.Screen
name={MainRoutes.Main} name="main"
component={createTabNavigator} component={createTabNavigator}
options={{ options={{
headerShown: false, headerShown: false,
@ -124,62 +83,62 @@ function MainStackComponent(props: {createTabNavigator: () => JSX.Element}) {
}} }}
/> />
<MainStack.Screen <MainStack.Screen
name={MainRoutes.Gallery} name="gallery"
component={ImageGalleryScreen} component={ImageGalleryScreen}
options={{ options={{
headerShown: false, headerShown: false,
...modalTransition, ...modalTransition,
}} }}
/> />
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Settings, 'settings',
MainStack, MainStack,
SettingsScreen, SettingsScreen,
i18n.t('screens.settings.title'), i18n.t('screens.settings.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.DashboardEdit, 'dashboard-edit',
MainStack, MainStack,
DashboardEditScreen, DashboardEditScreen,
i18n.t('screens.settings.dashboardEdit.title'), i18n.t('screens.settings.dashboardEdit.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.About, 'about',
MainStack, MainStack,
AboutScreen, AboutScreen,
i18n.t('screens.about.title'), i18n.t('screens.about.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Dependencies, 'dependencies',
MainStack, MainStack,
AboutDependenciesScreen, AboutDependenciesScreen,
i18n.t('screens.about.libs'), i18n.t('screens.about.libs'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Debug, 'debug',
MainStack, MainStack,
DebugScreen, DebugScreen,
i18n.t('screens.about.debug'), i18n.t('screens.about.debug'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.GameStart, 'game-start',
MainStack, MainStack,
GameStartScreen, GameStartScreen,
i18n.t('screens.game.title'), i18n.t('screens.game.title'),
true, true,
undefined, null,
'transparent', 'transparent',
)} )}
<MainStack.Screen <MainStack.Screen
name={MainRoutes.GameMain} name="game-main"
component={GameMainScreen} component={GameMainScreen}
options={{ options={{
title: i18n.t('screens.game.title'), title: i18n.t('screens.game.title'),
}} }}
/> />
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Login, 'login',
MainStack, MainStack,
LoginScreen, LoginScreen,
i18n.t('screens.login.title'), i18n.t('screens.login.title'),
@ -189,26 +148,26 @@ function MainStackComponent(props: {createTabNavigator: () => JSX.Element}) {
)} )}
{getWebsiteStack('website', MainStack, WebsiteScreen, '')} {getWebsiteStack('website', MainStack, WebsiteScreen, '')}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.SelfMenu, 'self-menu',
MainStack, MainStack,
SelfMenuScreen, SelfMenuScreen,
i18n.t('screens.menu.title'), i18n.t('screens.menu.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Proximo, 'proximo',
MainStack, MainStack,
ProximoMainScreen, ProximoMainScreen,
i18n.t('screens.proximo.title'), i18n.t('screens.proximo.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.ProximoList, 'proximo-list',
MainStack, MainStack,
ProximoListScreen, ProximoListScreen,
i18n.t('screens.proximo.articleList'), i18n.t('screens.proximo.articleList'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.ProximoAbout, 'proximo-about',
MainStack, MainStack,
ProximoAboutScreen, ProximoAboutScreen,
i18n.t('screens.proximo.title'), i18n.t('screens.proximo.title'),
@ -216,60 +175,60 @@ function MainStackComponent(props: {createTabNavigator: () => JSX.Element}) {
{...modalTransition}, {...modalTransition},
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Profile, 'profile',
MainStack, MainStack,
ProfileScreen, ProfileScreen,
i18n.t('screens.profile.title'), i18n.t('screens.profile.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.ClubList, 'club-list',
MainStack, MainStack,
ClubListScreen, ClubListScreen,
i18n.t('screens.clubs.title'), i18n.t('screens.clubs.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.ClubInformation, 'club-information',
MainStack, MainStack,
ClubDisplayScreen, ClubDisplayScreen,
i18n.t('screens.clubs.details'), i18n.t('screens.clubs.details'),
true, true,
{...modalTransition}, {...modalTransition},
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.ClubAbout, 'club-about',
MainStack, MainStack,
ClubAboutScreen, ClubAboutScreen,
i18n.t('screens.clubs.title'), i18n.t('screens.clubs.title'),
true, true,
{...modalTransition}, {...modalTransition},
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.EquipmentList, 'equipment-list',
MainStack, MainStack,
EquipmentScreen, EquipmentScreen,
i18n.t('screens.equipment.title'), i18n.t('screens.equipment.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.EquipmentRent, 'equipment-rent',
MainStack, MainStack,
EquipmentLendScreen, EquipmentLendScreen,
i18n.t('screens.equipment.book'), i18n.t('screens.equipment.book'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.EquipmentConfirm, 'equipment-confirm',
MainStack, MainStack,
EquipmentConfirmScreen, EquipmentConfirmScreen,
i18n.t('screens.equipment.confirm'), i18n.t('screens.equipment.confirm'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Vote, 'vote',
MainStack, MainStack,
VoteScreen, VoteScreen,
i18n.t('screens.vote.title'), i18n.t('screens.vote.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
MainRoutes.Feedback, 'feedback',
MainStack, MainStack,
BugReportScreen, BugReportScreen,
i18n.t('screens.feedback.title'), i18n.t('screens.feedback.title'),
@ -279,10 +238,25 @@ function MainStackComponent(props: {createTabNavigator: () => JSX.Element}) {
} }
type PropsType = { type PropsType = {
defaultHomeRoute: string | null; defaultHomeRoute: string | null,
defaultHomeData: {[key: string]: string}; // eslint-disable-next-line flowtype/no-weak-types
defaultHomeData: {[key: string]: string},
}; };
export default function MainNavigator(props: PropsType) { export default class MainNavigator extends React.Component<PropsType> {
return <MainStackComponent createTabNavigator={() => TabNavigator(props)} />; createTabNavigator: () => React.Node;
constructor(props: PropsType) {
super(props);
this.createTabNavigator = (): React.Node => (
<TabNavigator
defaultHomeRoute={props.defaultHomeRoute}
defaultHomeData={props.defaultHomeData}
/>
);
}
render(): React.Node {
return <MainStackComponent createTabNavigator={this.createTabNavigator} />;
}
} }

View file

@ -17,6 +17,8 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {createStackNavigator, TransitionPresets} from '@react-navigation/stack'; import {createStackNavigator, TransitionPresets} from '@react-navigation/stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'; import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
@ -42,7 +44,7 @@ import WebsitesHomeScreen from '../screens/Services/ServicesScreen';
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 { import {
CreateScreenCollapsibleStack, createScreenCollapsibleStack,
getWebsiteStack, getWebsiteStack,
} from '../utils/CollapsibleUtils'; } from '../utils/CollapsibleUtils';
import Mascot, {MASCOT_STYLE} from '../components/Mascot/Mascot'; import Mascot, {MASCOT_STYLE} from '../components/Mascot/Mascot';
@ -60,25 +62,25 @@ const defaultScreenOptions = {
const ServicesStack = createStackNavigator(); const ServicesStack = createStackNavigator();
function ServicesStackComponent() { function ServicesStackComponent(): React.Node {
return ( return (
<ServicesStack.Navigator <ServicesStack.Navigator
initialRouteName="index" initialRouteName="index"
headerMode="screen" headerMode="screen"
screenOptions={defaultScreenOptions}> screenOptions={defaultScreenOptions}>
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'index', 'index',
ServicesStack, ServicesStack,
WebsitesHomeScreen, WebsitesHomeScreen,
i18n.t('screens.services.title'), i18n.t('screens.services.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'services-section', 'services-section',
ServicesStack, ServicesStack,
ServicesSectionScreen, ServicesSectionScreen,
'SECTION', 'SECTION',
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'amicale-contact', 'amicale-contact',
ServicesStack, ServicesStack,
AmicaleContactScreen, AmicaleContactScreen,
@ -90,19 +92,19 @@ function ServicesStackComponent() {
const ProxiwashStack = createStackNavigator(); const ProxiwashStack = createStackNavigator();
function ProxiwashStackComponent() { function ProxiwashStackComponent(): React.Node {
return ( return (
<ProxiwashStack.Navigator <ProxiwashStack.Navigator
initialRouteName="index" initialRouteName="index"
headerMode="screen" headerMode="screen"
screenOptions={defaultScreenOptions}> screenOptions={defaultScreenOptions}>
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'index', 'index',
ProxiwashStack, ProxiwashStack,
ProxiwashScreen, ProxiwashScreen,
i18n.t('screens.proxiwash.title'), i18n.t('screens.proxiwash.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'proxiwash-about', 'proxiwash-about',
ProxiwashStack, ProxiwashStack,
ProxiwashAboutScreen, ProxiwashAboutScreen,
@ -114,7 +116,7 @@ function ProxiwashStackComponent() {
const PlanningStack = createStackNavigator(); const PlanningStack = createStackNavigator();
function PlanningStackComponent() { function PlanningStackComponent(): React.Node {
return ( return (
<PlanningStack.Navigator <PlanningStack.Navigator
initialRouteName="index" initialRouteName="index"
@ -125,7 +127,7 @@ function PlanningStackComponent() {
component={PlanningScreen} component={PlanningScreen}
options={{title: i18n.t('screens.planning.title')}} options={{title: i18n.t('screens.planning.title')}}
/> />
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'planning-information', 'planning-information',
PlanningStack, PlanningStack,
PlanningDisplayScreen, PlanningDisplayScreen,
@ -140,11 +142,10 @@ const HomeStack = createStackNavigator();
function HomeStackComponent( function HomeStackComponent(
initialRoute: string | null, initialRoute: string | null,
defaultData: {[key: string]: string}, defaultData: {[key: string]: string},
) { ): React.Node {
let params; let params;
if (initialRoute != null) { if (initialRoute != null)
params = {data: defaultData, nextScreen: initialRoute, shouldOpen: true}; params = {data: defaultData, nextScreen: initialRoute, shouldOpen: true};
}
const {colors} = useTheme(); const {colors} = useTheme();
return ( return (
<HomeStack.Navigator <HomeStack.Navigator
@ -160,7 +161,7 @@ function HomeStackComponent(
headerStyle: { headerStyle: {
backgroundColor: colors.surface, backgroundColor: colors.surface,
}, },
headerTitle: () => ( headerTitle: (): React.Node => (
<View style={{flexDirection: 'row'}}> <View style={{flexDirection: 'row'}}>
<Mascot <Mascot
style={{ style={{
@ -202,19 +203,19 @@ function HomeStackComponent(
options={{title: i18n.t('screens.scanner.title')}} options={{title: i18n.t('screens.scanner.title')}}
/> />
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'club-information', 'club-information',
HomeStack, HomeStack,
ClubDisplayScreen, ClubDisplayScreen,
i18n.t('screens.clubs.details'), i18n.t('screens.clubs.details'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'feed-information', 'feed-information',
HomeStack, HomeStack,
FeedItemScreen, FeedItemScreen,
i18n.t('screens.home.feed'), i18n.t('screens.home.feed'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'planning-information', 'planning-information',
HomeStack, HomeStack,
PlanningDisplayScreen, PlanningDisplayScreen,
@ -226,7 +227,7 @@ function HomeStackComponent(
const PlanexStack = createStackNavigator(); const PlanexStack = createStackNavigator();
function PlanexStackComponent() { function PlanexStackComponent(): React.Node {
return ( return (
<PlanexStack.Navigator <PlanexStack.Navigator
initialRouteName="index" initialRouteName="index"
@ -238,7 +239,7 @@ function PlanexStackComponent() {
PlanexScreen, PlanexScreen,
i18n.t('screens.planex.title'), i18n.t('screens.planex.title'),
)} )}
{CreateScreenCollapsibleStack( {createScreenCollapsibleStack(
'group-select', 'group-select',
PlanexStack, PlanexStack,
GroupSelectionScreen, GroupSelectionScreen,
@ -251,26 +252,35 @@ function PlanexStackComponent() {
const Tab = createBottomTabNavigator(); const Tab = createBottomTabNavigator();
type PropsType = { type PropsType = {
defaultHomeRoute: string | null; defaultHomeRoute: string | null,
defaultHomeData: {[key: string]: string}; defaultHomeData: {[key: string]: string},
}; };
export default function TabNavigator(props: PropsType) { export default class TabNavigator extends React.Component<PropsType> {
let defaultRoute = 'home'; createHomeStackComponent: () => React.Node;
if (!props.defaultHomeRoute) {
defaultRoute = AsyncStorageManager.getString( defaultRoute: string;
constructor(props: PropsType) {
super(props);
if (props.defaultHomeRoute != null) this.defaultRoute = 'home';
else
this.defaultRoute = AsyncStorageManager.getString(
AsyncStorageManager.PREFERENCES.defaultStartScreen.key, AsyncStorageManager.PREFERENCES.defaultStartScreen.key,
).toLowerCase(); ).toLowerCase();
} this.createHomeStackComponent = (): React.Node =>
const createHomeStackComponent = () =>
HomeStackComponent(props.defaultHomeRoute, props.defaultHomeData); HomeStackComponent(props.defaultHomeRoute, props.defaultHomeData);
}
render(): React.Node {
return ( return (
<Tab.Navigator <Tab.Navigator
initialRouteName={defaultRoute} initialRouteName={this.defaultRoute}
tabBar={(tabProps) => <CustomTabBar {...tabProps} />}> // eslint-disable-next-line react/jsx-props-no-spreading
tabBar={(props: {...}): React.Node => <CustomTabBar {...props} />}>
<Tab.Screen <Tab.Screen
name="services" name="services"
option
component={ServicesStackComponent} component={ServicesStackComponent}
options={{title: i18n.t('screens.services.title')}} options={{title: i18n.t('screens.services.title')}}
/> />
@ -281,7 +291,7 @@ export default function TabNavigator(props: PropsType) {
/> />
<Tab.Screen <Tab.Screen
name="home" name="home"
component={createHomeStackComponent} component={this.createHomeStackComponent}
options={{title: i18n.t('screens.home.title')}} options={{title: i18n.t('screens.home.title')}}
/> />
<Tab.Screen <Tab.Screen
@ -289,6 +299,7 @@ export default function TabNavigator(props: PropsType) {
component={PlanningStackComponent} component={PlanningStackComponent}
options={{title: i18n.t('screens.planning.title')}} options={{title: i18n.t('screens.planning.title')}}
/> />
<Tab.Screen <Tab.Screen
name="planex" name="planex"
component={PlanexStackComponent} component={PlanexStackComponent}
@ -296,4 +307,5 @@ export default function TabNavigator(props: PropsType) {
/> />
</Tab.Navigator> </Tab.Navigator>
); );
}
} }

View file

@ -50,11 +50,11 @@ const LIST_ITEM_HEIGHT = 64;
/** /**
* Class defining a screen showing the list of libraries used by the app, taken from package.json * Class defining a screen showing the list of libraries used by the app, taken from package.json
*/ */
export default class AboutDependenciesScreen extends React.Component<{}> { export default class AboutDependenciesScreen extends React.Component<null> {
data: Array<ListItemType>; data: Array<ListItemType>;
constructor() { constructor() {
super({}); super(null);
this.data = generateListFromObject(packageJson.dependencies); this.data = generateListFromObject(packageJson.dependencies);
} }

View file

@ -34,12 +34,12 @@ type DatasetItemType = {
/** /**
* Class defining a planning event information page. * Class defining a planning event information page.
*/ */
class AmicaleContactScreen extends React.Component<{}> { class AmicaleContactScreen extends React.Component<null> {
// Dataset containing information about contacts // Dataset containing information about contacts
CONTACT_DATASET: Array<DatasetItemType>; CONTACT_DATASET: Array<DatasetItemType>;
constructor() { constructor() {
super({}); super(null);
this.CONTACT_DATASET = [ this.CONTACT_DATASET = [
{ {
name: i18n.t('screens.amicaleAbout.roles.interSchools'), name: i18n.t('screens.amicaleAbout.roles.interSchools'),

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Avatar, Button, Card, Paragraph, withTheme} from 'react-native-paper';
import i18n from 'i18n-js';
import {Linking, View} from 'react-native';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
import type {CardTitleIconPropsType} from '../../constants/PaperStyles';
const links = {
bugsGit: 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/',
trello: 'https://trello.com/b/RMej49Uq/application-campus-insa',
facebook: 'https://www.facebook.com/campus.insat',
feedbackMail: `mailto:app@amicale-insat.fr?subject=[FEEDBACK] Application CAMPUS
&body=Coucou Arnaud j'ai du feedback\n\n\n\nBien cordialement.`,
feedbackDiscord: 'https://discord.gg/W8MeTec',
};
class FeedbackScreen extends React.Component<null> {
/**
* Gets link buttons
*
* @returns {*}
*/
static getButtons(isFeedback: boolean): React.Node {
return (
<Card.Actions
style={{
flex: 1,
flexWrap: 'wrap',
}}>
{isFeedback ? (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="email"
mode="contained"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackMail);
}}>
MAIL
</Button>
<Button
icon="facebook"
mode="contained"
color="#2e88fe"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.facebook);
}}>
Facebook
</Button>
<Button
icon="discord"
mode="contained"
color="#7289da"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackDiscord);
}}>
Discord
</Button>
</View>
) : (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="git"
mode="contained"
color="#609927"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.bugsGit);
}}>
GITETUD
</Button>
<Button
icon="calendar"
mode="contained"
color="#026AA7"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.trello);
}}>
TRELLO
</Button>
</View>
)}
</Card.Actions>
);
}
render(): React.Node {
return (
<CollapsibleScrollView style={{padding: 5}}>
<Card>
<Card.Title
title={i18n.t('screens.feedback.feedback')}
subtitle={i18n.t('screens.feedback.feedbackSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="comment" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.feedbackDescription')}
</Paragraph>
</Card.Content>
{FeedbackScreen.getButtons(true)}
<Card.Title
title={i18n.t('screens.feedback.contribute')}
subtitle={i18n.t('screens.feedback.contributeSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="handshake" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.contributeDescription')}
</Paragraph>
</Card.Content>
{FeedbackScreen.getButtons(false)}
</Card>
</CollapsibleScrollView>
);
}
}
export default withTheme(FeedbackScreen);

View file

@ -1,169 +0,0 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
import * as React from 'react';
import {Avatar, Button, Card, Paragraph, withTheme} from 'react-native-paper';
import i18n from 'i18n-js';
import {Linking, View} from 'react-native';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
const links = {
bugsGit: 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/',
trello: 'https://trello.com/b/RMej49Uq/application-campus-insa',
facebook: 'https://www.facebook.com/campus.insat',
feedbackMail: `mailto:app@amicale-insat.fr?subject=[FEEDBACK] Application CAMPUS
&body=Coucou Arnaud j'ai du feedback\n\n\n\nBien cordialement.`,
feedbackDiscord: 'https://discord.gg/W8MeTec',
};
function getButtons(isFeedback: boolean) {
return (
<Card.Actions
style={{
flex: 1,
flexWrap: 'wrap',
}}>
{isFeedback ? (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="email"
mode="contained"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackMail);
}}>
MAIL
</Button>
<Button
icon="facebook"
mode="contained"
color="#2e88fe"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.facebook);
}}>
Facebook
</Button>
<Button
icon="discord"
mode="contained"
color="#7289da"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackDiscord);
}}>
Discord
</Button>
</View>
) : (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="git"
mode="contained"
color="#609927"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.bugsGit);
}}>
GITETUD
</Button>
<Button
icon="calendar"
mode="contained"
color="#026AA7"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.trello);
}}>
TRELLO
</Button>
</View>
)}
</Card.Actions>
);
}
function FeedbackScreen() {
return (
<CollapsibleScrollView style={{padding: 5}}>
<Card>
<Card.Title
title={i18n.t('screens.feedback.feedback')}
subtitle={i18n.t('screens.feedback.feedbackSubtitle')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="comment" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.feedbackDescription')}
</Paragraph>
</Card.Content>
{getButtons(true)}
<Card.Title
title={i18n.t('screens.feedback.contribute')}
subtitle={i18n.t('screens.feedback.contributeSubtitle')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="handshake" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.contributeDescription')}
</Paragraph>
</Card.Content>
{getButtons(false)}
</Card>
</CollapsibleScrollView>
);
}
export default withTheme(FeedbackScreen);

View file

@ -17,9 +17,11 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {StackNavigationProp} from '@react-navigation/stack'; import {StackNavigationProp} from '@react-navigation/stack';
import {Button, Card, Paragraph} from 'react-native-paper'; import {Button, Card, Paragraph, withTheme} from 'react-native-paper';
import {FlatList} from 'react-native'; import {FlatList} from 'react-native';
import {View} from 'react-native-animatable'; import {View} from 'react-native-animatable';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
@ -28,19 +30,20 @@ import type {
ServiceItemType, ServiceItemType,
} from '../../../managers/ServicesManager'; } from '../../../managers/ServicesManager';
import DashboardManager from '../../../managers/DashboardManager'; import DashboardManager from '../../../managers/DashboardManager';
import DashboardItem from '../../../components/Home/EventDashboardItem';
import DashboardEditAccordion from '../../../components/Lists/DashboardEdit/DashboardEditAccordion'; import DashboardEditAccordion from '../../../components/Lists/DashboardEdit/DashboardEditAccordion';
import DashboardEditPreviewItem from '../../../components/Lists/DashboardEdit/DashboardEditPreviewItem'; import DashboardEditPreviewItem from '../../../components/Lists/DashboardEdit/DashboardEditPreviewItem';
import AsyncStorageManager from '../../../managers/AsyncStorageManager'; import AsyncStorageManager from '../../../managers/AsyncStorageManager';
import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList'; import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList';
type PropsType = { type PropsType = {
navigation: StackNavigationProp<any>; navigation: StackNavigationProp,
}; };
type StateType = { type StateType = {
currentDashboard: Array<ServiceItemType | null>; currentDashboard: Array<ServiceItemType | null>,
currentDashboardIdList: Array<string>; currentDashboardIdList: Array<string>,
activeItem: number; activeItem: number,
}; };
/** /**
@ -72,13 +75,13 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
item, item,
index, index,
}: { }: {
item: ServiceItemType | null; item: DashboardItem,
index: number; index: number,
}) => { }): React.Node => {
const {activeItem} = this.state; const {activeItem} = this.state;
return ( return (
<DashboardEditPreviewItem <DashboardEditPreviewItem
image={item?.image} image={item.image}
onPress={() => { onPress={() => {
this.setState({activeItem: index}); this.setState({activeItem: index});
}} }}
@ -87,7 +90,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
}; };
getDashboard(content: Array<ServiceItemType | null>) { getDashboard(content: Array<DashboardItem>): React.Node {
return ( return (
<FlatList <FlatList
data={content} data={content}
@ -103,7 +106,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
} }
getRenderItem = ({item}: {item: ServiceCategoryType}) => { getRenderItem = ({item}: {item: ServiceCategoryType}): React.Node => {
const {currentDashboardIdList} = this.state; const {currentDashboardIdList} = this.state;
return ( return (
<DashboardEditAccordion <DashboardEditAccordion
@ -114,7 +117,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
}; };
getListHeader() { getListHeader(): React.Node {
const {currentDashboard} = this.state; const {currentDashboard} = this.state;
return ( return (
<Card style={{margin: 5}}> <Card style={{margin: 5}}>
@ -167,7 +170,7 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
); );
}; };
render() { render(): React.Node {
return ( return (
<CollapsibleFlatList <CollapsibleFlatList
data={this.content} data={this.content}
@ -179,4 +182,4 @@ class DashboardEditScreen extends React.Component<PropsType, StateType> {
} }
} }
export default DashboardEditScreen; export default withTheme(DashboardEditScreen);

View file

@ -17,6 +17,8 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
// @flow
import * as React from 'react'; import * as React from 'react';
import {View} from 'react-native'; import {View} from 'react-native';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
@ -30,22 +32,24 @@ import {
} from 'react-native-paper'; } from 'react-native-paper';
import {Appearance} from 'react-native-appearance'; import {Appearance} from 'react-native-appearance';
import {StackNavigationProp} from '@react-navigation/stack'; import {StackNavigationProp} from '@react-navigation/stack';
import type {CustomThemeType} from '../../../managers/ThemeManager';
import ThemeManager from '../../../managers/ThemeManager'; import ThemeManager from '../../../managers/ThemeManager';
import AsyncStorageManager from '../../../managers/AsyncStorageManager'; import AsyncStorageManager from '../../../managers/AsyncStorageManager';
import CustomSlider from '../../../components/Overrides/CustomSlider'; import CustomSlider from '../../../components/Overrides/CustomSlider';
import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView'; import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
import type {ListIconPropsType} from '../../../constants/PaperStyles';
type PropsType = { type PropsType = {
navigation: StackNavigationProp<any>; navigation: StackNavigationProp,
theme: ReactNativePaper.Theme; theme: CustomThemeType,
}; };
type StateType = { type StateType = {
nightMode: boolean; nightMode: boolean,
nightModeFollowSystem: boolean; nightModeFollowSystem: boolean,
startScreenPickerSelected: string; startScreenPickerSelected: string,
selectedWash: string; selectedWash: string,
isDebugUnlocked: boolean; isDebugUnlocked: boolean,
}; };
/** /**
@ -57,15 +61,14 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
/** /**
* Loads user preferences into state * Loads user preferences into state
*/ */
constructor(props: PropsType) { constructor() {
super(props); super();
const notifReminder = AsyncStorageManager.getString( const notifReminder = AsyncStorageManager.getString(
AsyncStorageManager.PREFERENCES.proxiwashNotifications.key, AsyncStorageManager.PREFERENCES.proxiwashNotifications.key,
); );
this.savedNotificationReminder = parseInt(notifReminder, 10); this.savedNotificationReminder = parseInt(notifReminder, 10);
if (Number.isNaN(this.savedNotificationReminder)) { if (Number.isNaN(this.savedNotificationReminder))
this.savedNotificationReminder = 0; this.savedNotificationReminder = 0;
}
this.state = { this.state = {
nightMode: ThemeManager.getNightMode(), nightMode: ThemeManager.getNightMode(),
@ -117,7 +120,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
* *
* @returns {React.Node} * @returns {React.Node}
*/ */
getProxiwashNotifPicker() { getProxiwashNotifPicker(): React.Node {
const {theme} = this.props; const {theme} = this.props;
return ( return (
<CustomSlider <CustomSlider
@ -138,7 +141,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
* *
* @returns {React.Node} * @returns {React.Node}
*/ */
getProxiwashChangePicker() { getProxiwashChangePicker(): React.Node {
const {selectedWash} = this.state; const {selectedWash} = this.state;
return ( return (
<RadioButton.Group <RadioButton.Group
@ -161,7 +164,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
* *
* @returns {React.Node} * @returns {React.Node}
*/ */
getStartScreenPicker() { getStartScreenPicker(): React.Node {
const {startScreenPickerSelected} = this.state; const {startScreenPickerSelected} = this.state;
return ( return (
<ToggleButton.Row <ToggleButton.Row
@ -217,15 +220,17 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
title: string, title: string,
subtitle: string, subtitle: string,
state: boolean, state: boolean,
) { ): React.Node {
return ( return (
<List.Item <List.Item
title={title} title={title}
description={subtitle} description={subtitle}
left={(props) => ( left={(props: ListIconPropsType): React.Node => (
<List.Icon color={props.color} style={props.style} icon={icon} /> <List.Icon color={props.color} style={props.style} icon={icon} />
)} )}
right={() => <Switch value={state} onValueChange={onPressCallback} />} right={(): React.Node => (
<Switch value={state} onValueChange={onPressCallback} />
)}
/> />
); );
} }
@ -236,7 +241,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
title: string, title: string,
subtitle: string, subtitle: string,
onLongPress?: () => void, onLongPress?: () => void,
) { ): React.Node {
const {navigation} = this.props; const {navigation} = this.props;
return ( return (
<List.Item <List.Item
@ -245,10 +250,10 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
onPress={() => { onPress={() => {
navigation.navigate(route); navigation.navigate(route);
}} }}
left={(props) => ( left={(props: ListIconPropsType): React.Node => (
<List.Icon color={props.color} style={props.style} icon={icon} /> <List.Icon color={props.color} style={props.style} icon={icon} />
)} )}
right={(props) => ( right={(props: ListIconPropsType): React.Node => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}
@ -286,7 +291,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
); );
}; };
render() { render(): React.Node {
const {nightModeFollowSystem, nightMode, isDebugUnlocked} = this.state; const {nightModeFollowSystem, nightMode, isDebugUnlocked} = this.state;
return ( return (
<CollapsibleScrollView> <CollapsibleScrollView>
@ -317,7 +322,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
<List.Item <List.Item
title={i18n.t('screens.settings.startScreen')} title={i18n.t('screens.settings.startScreen')}
description={i18n.t('screens.settings.startScreenSub')} description={i18n.t('screens.settings.startScreenSub')}
left={(props) => ( left={(props: ListIconPropsType): React.Node => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}
@ -340,7 +345,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
<List.Item <List.Item
title={i18n.t('screens.settings.proxiwashNotifReminder')} title={i18n.t('screens.settings.proxiwashNotifReminder')}
description={i18n.t('screens.settings.proxiwashNotifReminderSub')} description={i18n.t('screens.settings.proxiwashNotifReminderSub')}
left={(props) => ( left={(props: ListIconPropsType): React.Node => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}
@ -354,7 +359,7 @@ class SettingsScreen extends React.Component<PropsType, StateType> {
<List.Item <List.Item
title={i18n.t('screens.settings.proxiwashChangeWash')} title={i18n.t('screens.settings.proxiwashChangeWash')}
description={i18n.t('screens.settings.proxiwashChangeWashSub')} description={i18n.t('screens.settings.proxiwashChangeWashSub')}
left={(props) => ( left={(props: ListIconPropsType): React.Node => (
<List.Icon <List.Icon
color={props.color} color={props.color}
style={props.style} style={props.style}

View file

@ -21,7 +21,7 @@ import * as React from 'react';
import {useTheme} from 'react-native-paper'; import {useTheme} from 'react-native-paper';
import {createCollapsibleStack} from 'react-navigation-collapsible'; import {createCollapsibleStack} from 'react-navigation-collapsible';
import StackNavigator, {StackNavigationOptions} from '@react-navigation/stack'; import StackNavigator, {StackNavigationOptions} from '@react-navigation/stack';
import {StackNavigationState, TypedNavigator} from '@react-navigation/native'; import {StackNavigationState} from '@react-navigation/native';
import {StackNavigationEventMap} from '@react-navigation/stack/lib/typescript/src/types'; import {StackNavigationEventMap} from '@react-navigation/stack/lib/typescript/src/types';
type StackNavigatorType = import('@react-navigation/native').TypedNavigator< type StackNavigatorType = import('@react-navigation/native').TypedNavigator<
@ -50,7 +50,7 @@ type StackNavigatorType = import('@react-navigation/native').TypedNavigator<
*/ */
export function CreateScreenCollapsibleStack( export function CreateScreenCollapsibleStack(
name: string, name: string,
Stack: TypedNavigator<any, any, any, any, any>, Stack: StackNavigatorType,
component: React.ComponentType<any>, component: React.ComponentType<any>,
title: string, title: string,
useNativeDriver: boolean = true, useNativeDriver: boolean = true,
@ -91,7 +91,7 @@ export function CreateScreenCollapsibleStack(
*/ */
export function getWebsiteStack( export function getWebsiteStack(
name: string, name: string,
Stack: TypedNavigator<any, any, any, any, any>, Stack: StackNavigatorType,
component: React.ComponentType<any>, component: React.ComponentType<any>,
title: string, title: string,
) { ) {