Compare commits
No commits in common. "be33726e39e05353e1e203ade9c19d781be95263" and "560c3367593d87b9459c3d5e35773b004a63d9d3" have entirely different histories.
be33726e39
...
560c336759
32 changed files with 531 additions and 522 deletions
|
|
@ -95,10 +95,8 @@
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"title": "Campus",
|
"title": "Campus",
|
||||||
"feedTitle": "Campus News",
|
"feedTitle": "Amicale's News",
|
||||||
"feed": "Details",
|
"feed": "Details",
|
||||||
"feedLoading": "Loading News",
|
|
||||||
"feedError": "Failed to load news",
|
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"seeMore": "Click to see more",
|
"seeMore": "Click to see more",
|
||||||
"todayEventsTitle": "Today's events",
|
"todayEventsTitle": "Today's events",
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,8 @@
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"title": "Campus",
|
"title": "Campus",
|
||||||
"feedTitle": "News du Campus",
|
"feedTitle": "News de l'Amicale",
|
||||||
"feed": "Détails",
|
"feed": "Détails",
|
||||||
"feedLoading": "Chargement des news",
|
|
||||||
"feedError": "Erreur de chargement des news",
|
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"seeMore": "Clique pour plus d'infos",
|
"seeMore": "Clique pour plus d'infos",
|
||||||
"todayEventsTitle": "Événements aujourd'hui",
|
"todayEventsTitle": "Événements aujourd'hui",
|
||||||
|
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {withCollapsible} from "../../utils/withCollapsible";
|
|
||||||
import {Collapsible} from "react-navigation-collapsible";
|
|
||||||
import CustomTabBar from "../Tabbar/CustomTabBar";
|
|
||||||
|
|
||||||
export type CollapsibleComponentProps = {
|
|
||||||
children?: React.Node,
|
|
||||||
hasTab?: boolean,
|
|
||||||
onScroll?: (event: SyntheticEvent<EventTarget>) => void,
|
|
||||||
};
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
...CollapsibleComponentProps,
|
|
||||||
collapsibleStack: Collapsible,
|
|
||||||
component: any,
|
|
||||||
}
|
|
||||||
|
|
||||||
class CollapsibleComponent extends React.Component<Props> {
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
hasTab: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
onScroll = (event: SyntheticEvent<EventTarget>) => {
|
|
||||||
if (this.props.onScroll)
|
|
||||||
this.props.onScroll(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const Comp = this.props.component;
|
|
||||||
const {containerPaddingTop, scrollIndicatorInsetTop, onScrollWithListener} = this.props.collapsibleStack;
|
|
||||||
return (
|
|
||||||
<Comp
|
|
||||||
{...this.props}
|
|
||||||
onScroll={onScrollWithListener(this.onScroll)}
|
|
||||||
contentContainerStyle={{
|
|
||||||
paddingTop: containerPaddingTop,
|
|
||||||
paddingBottom: this.props.hasTab ? CustomTabBar.TAB_BAR_HEIGHT : 0,
|
|
||||||
minHeight: '100%'
|
|
||||||
}}
|
|
||||||
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
|
||||||
>
|
|
||||||
{this.props.children}
|
|
||||||
</Comp>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withCollapsible(CollapsibleComponent);
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {Animated} from "react-native";
|
|
||||||
import type {CollapsibleComponentProps} from "./CollapsibleComponent";
|
|
||||||
import CollapsibleComponent from "./CollapsibleComponent";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
...CollapsibleComponentProps
|
|
||||||
}
|
|
||||||
|
|
||||||
class CollapsibleFlatList extends React.Component<Props> {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<CollapsibleComponent
|
|
||||||
{...this.props}
|
|
||||||
component={Animated.FlatList}
|
|
||||||
>
|
|
||||||
{this.props.children}
|
|
||||||
</CollapsibleComponent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CollapsibleFlatList;
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {Animated} from "react-native";
|
|
||||||
import type {CollapsibleComponentProps} from "./CollapsibleComponent";
|
|
||||||
import CollapsibleComponent from "./CollapsibleComponent";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
...CollapsibleComponentProps
|
|
||||||
}
|
|
||||||
|
|
||||||
class CollapsibleScrollView extends React.Component<Props> {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<CollapsibleComponent
|
|
||||||
{...this.props}
|
|
||||||
component={Animated.ScrollView}
|
|
||||||
>
|
|
||||||
{this.props.children}
|
|
||||||
</CollapsibleComponent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CollapsibleScrollView;
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {Animated} from "react-native";
|
|
||||||
import type {CollapsibleComponentProps} from "./CollapsibleComponent";
|
|
||||||
import CollapsibleComponent from "./CollapsibleComponent";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
...CollapsibleComponentProps
|
|
||||||
}
|
|
||||||
|
|
||||||
class CollapsibleSectionList extends React.Component<Props> {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<CollapsibleComponent
|
|
||||||
{...this.props}
|
|
||||||
component={Animated.SectionList}
|
|
||||||
>
|
|
||||||
{this.props.children}
|
|
||||||
</CollapsibleComponent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default CollapsibleSectionList;
|
|
||||||
|
|
@ -4,31 +4,28 @@ import * as React from 'react';
|
||||||
import {ERROR_TYPE, readData} from "../../utils/WebData";
|
import {ERROR_TYPE, readData} from "../../utils/WebData";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {Snackbar} from 'react-native-paper';
|
import {Snackbar} from 'react-native-paper';
|
||||||
import {RefreshControl, View} from "react-native";
|
import {Animated, RefreshControl, View} from "react-native";
|
||||||
import ErrorView from "./ErrorView";
|
import ErrorView from "./ErrorView";
|
||||||
import BasicLoadingScreen from "./BasicLoadingScreen";
|
import BasicLoadingScreen from "./BasicLoadingScreen";
|
||||||
import {withCollapsible} from "../../utils/withCollapsible";
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
import * as Animatable from 'react-native-animatable';
|
import * as Animatable from 'react-native-animatable';
|
||||||
import CustomTabBar from "../Tabbar/CustomTabBar";
|
import CustomTabBar from "../Tabbar/CustomTabBar";
|
||||||
import {Collapsible} from "react-navigation-collapsible";
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
|
||||||
import CollapsibleSectionList from "../Collapsible/CollapsibleSectionList";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: { [key: string]: any },
|
||||||
fetchUrl: string,
|
fetchUrl: string,
|
||||||
autoRefreshTime: number,
|
autoRefreshTime: number,
|
||||||
refreshOnFocus: boolean,
|
refreshOnFocus: boolean,
|
||||||
renderItem: (data: { [key: string]: any }) => React.Node,
|
renderItem: (data: { [key: string]: any }) => React.Node,
|
||||||
createDataset: (data: { [key: string]: any } | null, isLoading?: boolean) => Array<Object>,
|
createDataset: (data: { [key: string]: any }) => Array<Object>,
|
||||||
onScroll: (event: SyntheticEvent<EventTarget>) => void,
|
onScroll: (event: SyntheticEvent<EventTarget>) => void,
|
||||||
collapsibleStack: Collapsible,
|
collapsibleStack: Collapsible,
|
||||||
|
|
||||||
showError: boolean,
|
showError: boolean,
|
||||||
itemHeight?: number,
|
itemHeight?: number,
|
||||||
updateData?: number,
|
updateData?: number,
|
||||||
renderListHeaderComponent?: (data: { [key: string]: any } | null) => React.Node,
|
renderSectionHeader?: (data: { [key: string]: any }) => React.Node,
|
||||||
renderSectionHeader?: (data: { section: { [key: string]: any } }, isLoading?: boolean) => React.Node,
|
|
||||||
stickyHeader?: boolean,
|
stickyHeader?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,6 +53,7 @@ class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
showError: true,
|
showError: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scrollRef: { current: null | Animated.SectionList };
|
||||||
refreshInterval: IntervalID;
|
refreshInterval: IntervalID;
|
||||||
lastRefresh: Date | null;
|
lastRefresh: Date | null;
|
||||||
|
|
||||||
|
|
@ -71,26 +69,31 @@ class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
* Allows to detect when the screen is focused
|
* Allows to detect when the screen is focused
|
||||||
*/
|
*/
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.navigation.addListener('focus', this.onScreenFocus);
|
const onScreenFocus = this.onScreenFocus.bind(this);
|
||||||
this.props.navigation.addListener('blur', this.onScreenBlur);
|
const onScreenBlur = this.onScreenBlur.bind(this);
|
||||||
this.lastRefresh = null;
|
this.props.navigation.addListener('focus', onScreenFocus);
|
||||||
|
this.props.navigation.addListener('blur', onScreenBlur);
|
||||||
|
this.scrollRef = React.createRef();
|
||||||
this.onRefresh();
|
this.onRefresh();
|
||||||
|
this.lastRefresh = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes data when focusing the screen and setup a refresh interval if asked to
|
* Refreshes data when focusing the screen and setup a refresh interval if asked to
|
||||||
*/
|
*/
|
||||||
onScreenFocus = () => {
|
onScreenFocus() {
|
||||||
if (this.props.refreshOnFocus && this.lastRefresh)
|
if (this.props.refreshOnFocus && this.lastRefresh)
|
||||||
this.onRefresh();
|
this.onRefresh();
|
||||||
if (this.props.autoRefreshTime > 0)
|
if (this.props.autoRefreshTime > 0)
|
||||||
this.refreshInterval = setInterval(this.onRefresh, this.props.autoRefreshTime)
|
this.refreshInterval = setInterval(this.onRefresh, this.props.autoRefreshTime)
|
||||||
|
// if (this.scrollRef.current) // Reset scroll to top
|
||||||
|
// this.scrollRef.current.getNode().scrollToLocation({animated:false, itemIndex:0, sectionIndex:0});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes any interval on un-focus
|
* Removes any interval on un-focus
|
||||||
*/
|
*/
|
||||||
onScreenBlur = () => {
|
onScreenBlur() {
|
||||||
clearInterval(this.refreshInterval);
|
clearInterval(this.refreshInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +173,7 @@ class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
duration={500}
|
duration={500}
|
||||||
useNativeDriver
|
useNativeDriver
|
||||||
>
|
>
|
||||||
{this.props.renderSectionHeader(data, this.state.refreshing)}
|
{this.props.renderSectionHeader(data)}
|
||||||
</Animatable.View>
|
</Animatable.View>
|
||||||
);
|
);
|
||||||
} else
|
} else
|
||||||
|
|
@ -202,12 +205,16 @@ class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
render() {
|
render() {
|
||||||
let dataset = [];
|
let dataset = [];
|
||||||
if (this.state.fetchedData != null || (this.state.fetchedData == null && !this.props.showError)) {
|
if (this.state.fetchedData != null || (this.state.fetchedData == null && !this.props.showError)) {
|
||||||
dataset = this.props.createDataset(this.state.fetchedData, this.state.refreshing);
|
if (this.state.fetchedData == null)
|
||||||
|
dataset = this.props.createDataset({});
|
||||||
|
else
|
||||||
|
dataset = this.props.createDataset(this.state.fetchedData);
|
||||||
}
|
}
|
||||||
const {containerPaddingTop} = this.props.collapsibleStack;
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScrollWithListener} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<CollapsibleSectionList
|
<Animated.SectionList
|
||||||
|
ref={this.scrollRef}
|
||||||
sections={dataset}
|
sections={dataset}
|
||||||
extraData={this.props.updateData}
|
extraData={this.props.updateData}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
|
|
@ -221,9 +228,6 @@ class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
stickySectionHeadersEnabled={this.props.stickyHeader}
|
stickySectionHeadersEnabled={this.props.stickyHeader}
|
||||||
style={{minHeight: '100%'}}
|
style={{minHeight: '100%'}}
|
||||||
ListHeaderComponent={this.props.renderListHeaderComponent != null
|
|
||||||
? this.props.renderListHeaderComponent(this.state.fetchedData)
|
|
||||||
: null}
|
|
||||||
ListEmptyComponent={this.state.refreshing
|
ListEmptyComponent={this.state.refreshing
|
||||||
? <BasicLoadingScreen/>
|
? <BasicLoadingScreen/>
|
||||||
: <ErrorView
|
: <ErrorView
|
||||||
|
|
@ -232,8 +236,14 @@ class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
onRefresh={this.onRefresh}/>
|
onRefresh={this.onRefresh}/>
|
||||||
}
|
}
|
||||||
getItemLayout={this.props.itemHeight != null ? this.itemLayout : undefined}
|
getItemLayout={this.props.itemHeight != null ? this.itemLayout : undefined}
|
||||||
onScroll={this.onScroll}
|
// Animations
|
||||||
hasTab={true}
|
onScroll={onScrollWithListener(this.onScroll)}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT,
|
||||||
|
minHeight: '100%'
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
/>
|
/>
|
||||||
<Snackbar
|
<Snackbar
|
||||||
visible={this.state.snackbarVisible}
|
visible={this.state.snackbarVisible}
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,16 @@ import EquipmentLendScreen from "../screens/Amicale/Equipment/EquipmentRentScree
|
||||||
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 GameEndScreen from "../screens/Game/screens/GameEndScreen";
|
||||||
|
|
||||||
const modalTransition = Platform.OS === 'ios' ? TransitionPresets.ModalPresentationIOS : TransitionPresets.ModalSlideFromBottomIOS;
|
const modalTransition = Platform.OS === 'ios' ? TransitionPresets.ModalPresentationIOS : TransitionPresets.ModalSlideFromBottomIOS;
|
||||||
|
|
||||||
|
const screenTransition = TransitionPresets.SlideFromRightIOS;
|
||||||
|
|
||||||
const defaultScreenOptions = {
|
const defaultScreenOptions = {
|
||||||
gestureEnabled: true,
|
gestureEnabled: true,
|
||||||
cardOverlayEnabled: true,
|
cardOverlayEnabled: true,
|
||||||
...TransitionPresets.SlideFromRightIOS,
|
...screenTransition,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -55,37 +58,48 @@ function MainStackComponent(props: { createTabNavigator: () => React.Node }) {
|
||||||
title: i18n.t('screens.home.title'),
|
title: i18n.t('screens.home.title'),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{createScreenCollapsibleStack(
|
<MainStack.Screen
|
||||||
"settings",
|
name="settings"
|
||||||
MainStack,
|
component={SettingsScreen}
|
||||||
SettingsScreen,
|
options={{
|
||||||
i18n.t('screens.settings.title'))}
|
title: i18n.t('screens.settings.title'),
|
||||||
{createScreenCollapsibleStack(
|
}}
|
||||||
"dashboard-edit",
|
/>
|
||||||
MainStack,
|
<MainStack.Screen
|
||||||
DashboardEditScreen,
|
name="dashboard-edit"
|
||||||
i18n.t('screens.settings.dashboardEdit.title'))}
|
component={DashboardEditScreen}
|
||||||
{createScreenCollapsibleStack(
|
options={{
|
||||||
"about",
|
title: i18n.t('screens.settings.dashboardEdit.title'),
|
||||||
MainStack,
|
}}
|
||||||
AboutScreen,
|
/>
|
||||||
i18n.t('screens.about.title'))}
|
<MainStack.Screen
|
||||||
{createScreenCollapsibleStack(
|
name="about"
|
||||||
"dependencies",
|
component={AboutScreen}
|
||||||
MainStack,
|
options={{
|
||||||
AboutDependenciesScreen,
|
title: i18n.t('screens.about.title'),
|
||||||
i18n.t('screens.about.libs'))}
|
}}
|
||||||
{createScreenCollapsibleStack(
|
/>
|
||||||
"debug",
|
<MainStack.Screen
|
||||||
MainStack,
|
name="dependencies"
|
||||||
DebugScreen,
|
component={AboutDependenciesScreen}
|
||||||
i18n.t('screens.about.debug'))}
|
options={{
|
||||||
|
title: i18n.t('screens.about.libs')
|
||||||
{createScreenCollapsibleStack(
|
}}
|
||||||
"game-start",
|
/>
|
||||||
MainStack,
|
<MainStack.Screen
|
||||||
GameStartScreen,
|
name="debug"
|
||||||
i18n.t('screens.game.title'))}
|
component={DebugScreen}
|
||||||
|
options={{
|
||||||
|
title: i18n.t('screens.about.debug')
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<MainStack.Screen
|
||||||
|
name="game-start"
|
||||||
|
component={GameStartScreen}
|
||||||
|
options={{
|
||||||
|
title: i18n.t("screens.game.title"),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<MainStack.Screen
|
<MainStack.Screen
|
||||||
name="game-main"
|
name="game-main"
|
||||||
component={GameMainScreen}
|
component={GameMainScreen}
|
||||||
|
|
@ -93,91 +107,73 @@ function MainStackComponent(props: { createTabNavigator: () => React.Node }) {
|
||||||
title: i18n.t("screens.game.title"),
|
title: i18n.t("screens.game.title"),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{createScreenCollapsibleStack(
|
<MainStack.Screen
|
||||||
"login",
|
name="game-end"
|
||||||
MainStack,
|
component={GameEndScreen}
|
||||||
LoginScreen,
|
options={{
|
||||||
i18n.t('screens.login.title'),
|
title: i18n.t("screens.game.title"),
|
||||||
true,
|
}}
|
||||||
{headerTintColor: "#fff"},
|
/>
|
||||||
'transparent')}
|
{createScreenCollapsibleStack("login", MainStack, LoginScreen, i18n.t('screens.login.title'),
|
||||||
|
true, {headerTintColor: "#fff"}, 'transparent')}
|
||||||
{getWebsiteStack("website", MainStack, WebsiteScreen, "")}
|
{getWebsiteStack("website", MainStack, WebsiteScreen, "")}
|
||||||
|
|
||||||
|
|
||||||
{createScreenCollapsibleStack(
|
{createScreenCollapsibleStack("self-menu", MainStack, SelfMenuScreen, i18n.t('screens.menu.title'))}
|
||||||
"self-menu",
|
{createScreenCollapsibleStack("proximo", MainStack, ProximoMainScreen, i18n.t('screens.proximo.title'))}
|
||||||
MainStack,
|
|
||||||
SelfMenuScreen,
|
|
||||||
i18n.t('screens.menu.title'))}
|
|
||||||
{createScreenCollapsibleStack(
|
|
||||||
"proximo",
|
|
||||||
MainStack,
|
|
||||||
ProximoMainScreen,
|
|
||||||
i18n.t('screens.proximo.title'))}
|
|
||||||
{createScreenCollapsibleStack(
|
{createScreenCollapsibleStack(
|
||||||
"proximo-list",
|
"proximo-list",
|
||||||
MainStack,
|
MainStack,
|
||||||
ProximoListScreen,
|
ProximoListScreen,
|
||||||
i18n.t('screens.proximo.articleList'),
|
i18n.t('screens.proximo.articleList'),
|
||||||
)}
|
|
||||||
{createScreenCollapsibleStack(
|
|
||||||
"proximo-about",
|
|
||||||
MainStack,
|
|
||||||
ProximoAboutScreen,
|
|
||||||
i18n.t('screens.proximo.title'),
|
|
||||||
true,
|
true,
|
||||||
{...modalTransition},
|
{...screenTransition},
|
||||||
)}
|
)}
|
||||||
|
<MainStack.Screen
|
||||||
|
name="proximo-about"
|
||||||
|
component={ProximoAboutScreen}
|
||||||
|
options={{
|
||||||
|
title: i18n.t('screens.proximo.title'),
|
||||||
|
...modalTransition,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{createScreenCollapsibleStack(
|
{createScreenCollapsibleStack("profile", MainStack, ProfileScreen, i18n.t('screens.profile.title'))}
|
||||||
"profile",
|
{createScreenCollapsibleStack("club-list", MainStack, ClubListScreen, i18n.t('screens.clubs.title'))}
|
||||||
MainStack,
|
{createScreenCollapsibleStack("equipment-list", MainStack, EquipmentScreen, i18n.t('screens.equipment.title'))}
|
||||||
ProfileScreen,
|
{createScreenCollapsibleStack("equipment-rent", MainStack, EquipmentLendScreen, i18n.t('screens.equipment.book'))}
|
||||||
i18n.t('screens.profile.title'))}
|
{createScreenCollapsibleStack("equipment-confirm", MainStack, EquipmentConfirmScreen, i18n.t('screens.equipment.confirm'))}
|
||||||
{createScreenCollapsibleStack(
|
<MainStack.Screen
|
||||||
"club-list",
|
name="club-information"
|
||||||
MainStack,
|
component={ClubDisplayScreen}
|
||||||
ClubListScreen,
|
options={{
|
||||||
i18n.t('screens.clubs.title'))}
|
title: i18n.t('screens.clubs.details'),
|
||||||
{createScreenCollapsibleStack(
|
...modalTransition,
|
||||||
"club-information",
|
}}
|
||||||
MainStack,
|
/>
|
||||||
ClubDisplayScreen,
|
<MainStack.Screen
|
||||||
i18n.t('screens.clubs.details'),
|
name="club-about"
|
||||||
true,
|
component={ClubAboutScreen}
|
||||||
{...modalTransition})}
|
options={{
|
||||||
{createScreenCollapsibleStack(
|
title: i18n.t('screens.clubs.title'),
|
||||||
"club-about",
|
...modalTransition,
|
||||||
MainStack,
|
}}
|
||||||
ClubAboutScreen,
|
/>
|
||||||
i18n.t('screens.clubs.title'),
|
<MainStack.Screen
|
||||||
true,
|
name="vote"
|
||||||
{...modalTransition})}
|
component={VoteScreen}
|
||||||
{createScreenCollapsibleStack(
|
options={{
|
||||||
"equipment-list",
|
title: i18n.t('screens.vote.title'),
|
||||||
MainStack,
|
}}
|
||||||
EquipmentScreen,
|
/>
|
||||||
i18n.t('screens.equipment.title'))}
|
|
||||||
{createScreenCollapsibleStack(
|
<MainStack.Screen
|
||||||
"equipment-rent",
|
name="feedback"
|
||||||
MainStack,
|
component={BugReportScreen}
|
||||||
EquipmentLendScreen,
|
options={{
|
||||||
i18n.t('screens.equipment.book'))}
|
title: i18n.t('screens.feedback.title'),
|
||||||
{createScreenCollapsibleStack(
|
}}
|
||||||
"equipment-confirm",
|
/>
|
||||||
MainStack,
|
|
||||||
EquipmentConfirmScreen,
|
|
||||||
i18n.t('screens.equipment.confirm'))}
|
|
||||||
{createScreenCollapsibleStack(
|
|
||||||
"vote",
|
|
||||||
MainStack,
|
|
||||||
VoteScreen,
|
|
||||||
i18n.t('screens.vote.title'))}
|
|
||||||
{createScreenCollapsibleStack(
|
|
||||||
"feedback",
|
|
||||||
MainStack,
|
|
||||||
BugReportScreen,
|
|
||||||
i18n.t('screens.feedback.title'))}
|
|
||||||
</MainStack.Navigator>
|
</MainStack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import {FlatList} from "react-native";
|
||||||
import packageJson from '../../../package';
|
import packageJson from '../../../package';
|
||||||
import {List} from 'react-native-paper';
|
import {List} from 'react-native-paper';
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
import {View} from "react-native-animatable";
|
|
||||||
|
|
||||||
type listItem = {
|
type listItem = {
|
||||||
name: string,
|
name: string,
|
||||||
|
|
@ -60,16 +59,14 @@ export default class AboutDependenciesScreen extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View>
|
<FlatList
|
||||||
<CollapsibleFlatList
|
data={this.data}
|
||||||
data={this.data}
|
keyExtractor={this.keyExtractor}
|
||||||
keyExtractor={this.keyExtractor}
|
renderItem={this.renderItem}
|
||||||
renderItem={this.renderItem}
|
// Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
|
||||||
// Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
|
removeClippedSubviews={true}
|
||||||
removeClippedSubviews={true}
|
getItemLayout={this.itemLayout}
|
||||||
getItemLayout={this.itemLayout}
|
/>
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import i18n from "i18n-js";
|
||||||
import {Avatar, Card, List, Title, withTheme} from 'react-native-paper';
|
import {Avatar, Card, List, Title, withTheme} from 'react-native-paper';
|
||||||
import packageJson from "../../../package.json";
|
import packageJson from "../../../package.json";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
type ListItem = {
|
type ListItem = {
|
||||||
onPressCallback: () => void,
|
onPressCallback: () => void,
|
||||||
|
|
@ -339,7 +338,7 @@ class AboutScreen extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<CollapsibleFlatList
|
<FlatList
|
||||||
style={{padding: 5}}
|
style={{padding: 5}}
|
||||||
data={this.dataOrder}
|
data={this.dataOrder}
|
||||||
renderItem={this.getMainCard}
|
renderItem={this.getMainCard}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {View} from "react-native";
|
import {FlatList, View} from "react-native";
|
||||||
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
||||||
import CustomModal from "../../components/Overrides/CustomModal";
|
import CustomModal from "../../components/Overrides/CustomModal";
|
||||||
import {Button, List, Subheading, TextInput, Title, withTheme} from 'react-native-paper';
|
import {Button, List, Subheading, TextInput, Title, withTheme} from 'react-native-paper';
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import {Modalize} from "react-native-modalize";
|
import {Modalize} from "react-native-modalize";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
type PreferenceItem = {
|
type PreferenceItem = {
|
||||||
key: string,
|
key: string,
|
||||||
|
|
@ -169,7 +168,7 @@ class DebugScreen extends React.Component<Props, State> {
|
||||||
{this.getModalContent()}
|
{this.getModalContent()}
|
||||||
</CustomModal>
|
</CustomModal>
|
||||||
{/*$FlowFixMe*/}
|
{/*$FlowFixMe*/}
|
||||||
<CollapsibleFlatList
|
<FlatList
|
||||||
data={this.state.currentPreferences}
|
data={this.state.currentPreferences}
|
||||||
extraData={this.state.currentPreferences}
|
extraData={this.state.currentPreferences}
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {FlatList, Image, Linking, View} from 'react-native';
|
import {Animated, FlatList, Image, Linking, View} from 'react-native';
|
||||||
import {Card, List, Text, withTheme} from 'react-native-paper';
|
import {Card, List, Text, withTheme} from 'react-native-paper';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||||
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
import type {MaterialCommunityIconsGlyphs} from "react-native-vector-icons/MaterialCommunityIcons";
|
import type {MaterialCommunityIconsGlyphs} from "react-native-vector-icons/MaterialCommunityIcons";
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
collapsibleStack: Collapsible
|
||||||
};
|
};
|
||||||
|
|
||||||
type DatasetItem = {
|
type DatasetItem = {
|
||||||
|
|
@ -127,14 +130,22 @@ class AmicaleContactScreen extends React.Component<Props> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<CollapsibleFlatList
|
<Animated.FlatList
|
||||||
data={[{key: "1"}]}
|
data={[{key: "1"}]}
|
||||||
renderItem={this.getScreen}
|
renderItem={this.getScreen}
|
||||||
hasTab={true}
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT,
|
||||||
|
minHeight: '100%'
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(AmicaleContactScreen);
|
export default withCollapsible(withTheme(AmicaleContactScreen));
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Image, View} from 'react-native';
|
import {Image, ScrollView, View} from 'react-native';
|
||||||
import {Card, List, Text, withTheme} from 'react-native-paper';
|
import {Card, List, Text, withTheme} from 'react-native-paper';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import Autolink from "react-native-autolink";
|
import Autolink from "react-native-autolink";
|
||||||
import CollapsibleScrollView from "../../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
|
|
@ -15,7 +14,7 @@ class ClubAboutScreen extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<CollapsibleScrollView style={{padding: 5}}>
|
<ScrollView style={{padding: 5}}>
|
||||||
<View style={{
|
<View style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 100,
|
height: 100,
|
||||||
|
|
@ -44,7 +43,7 @@ class ClubAboutScreen extends React.Component<Props> {
|
||||||
/>
|
/>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card>
|
</Card>
|
||||||
</CollapsibleScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Linking, View} from 'react-native';
|
import {Linking, ScrollView, View} from 'react-native';
|
||||||
import {Avatar, Button, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
|
import {Avatar, Button, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
|
||||||
import ImageModal from 'react-native-image-modal';
|
import ImageModal from 'react-native-image-modal';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
|
|
@ -12,7 +12,6 @@ import type {category, club} from "./ClubListScreen";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import {ERROR_TYPE} from "../../../utils/WebData";
|
import {ERROR_TYPE} from "../../../utils/WebData";
|
||||||
import CollapsibleScrollView from "../../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
|
@ -185,10 +184,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
return (
|
return (
|
||||||
<CollapsibleScrollView
|
<ScrollView style={{paddingLeft: 5, paddingRight: 5}}>
|
||||||
style={{paddingLeft: 5, paddingRight: 5}}
|
|
||||||
hasTab={true}
|
|
||||||
>
|
|
||||||
{this.getCategoriesRender(data.category)}
|
{this.getCategoriesRender(data.category)}
|
||||||
{data.logo !== null ?
|
{data.logo !== null ?
|
||||||
<View style={{
|
<View style={{
|
||||||
|
|
@ -218,7 +214,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
: <View/>}
|
: <View/>}
|
||||||
{this.getManagersRender(data.responsibles, data.email)}
|
{this.getManagersRender(data.responsibles, data.email)}
|
||||||
</CollapsibleScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
} else
|
} else
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Platform} from "react-native";
|
import {Animated, Platform} from "react-native";
|
||||||
import {Searchbar} from 'react-native-paper';
|
import {Searchbar} from 'react-native-paper';
|
||||||
import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
|
import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
|
|
@ -9,9 +9,10 @@ import ClubListItem from "../../../components/Lists/Clubs/ClubListItem";
|
||||||
import {isItemInCategoryFilter, stringMatchQuery} from "../../../utils/Search";
|
import {isItemInCategoryFilter, stringMatchQuery} from "../../../utils/Search";
|
||||||
import ClubListHeader from "../../../components/Lists/Clubs/ClubListHeader";
|
import ClubListHeader from "../../../components/Lists/Clubs/ClubListHeader";
|
||||||
import MaterialHeaderButtons, {Item} from "../../../components/Overrides/CustomHeaderButton";
|
import MaterialHeaderButtons, {Item} from "../../../components/Overrides/CustomHeaderButton";
|
||||||
|
import {withCollapsible} from "../../../utils/withCollapsible";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import CollapsibleFlatList from "../../../components/Collapsible/CollapsibleFlatList";
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
|
||||||
export type category = {
|
export type category = {
|
||||||
id: number,
|
id: number,
|
||||||
|
|
@ -31,6 +32,7 @@ export type club = {
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -109,8 +111,9 @@ class ClubListScreen extends React.Component<Props, State> {
|
||||||
clubList = data[0].clubs;
|
clubList = data[0].clubs;
|
||||||
}
|
}
|
||||||
this.categories = categoryList;
|
this.categories = categoryList;
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<CollapsibleFlatList
|
<Animated.FlatList
|
||||||
data={clubList}
|
data={clubList}
|
||||||
keyExtractor={this.keyExtractor}
|
keyExtractor={this.keyExtractor}
|
||||||
renderItem={this.getRenderItem}
|
renderItem={this.getRenderItem}
|
||||||
|
|
@ -118,6 +121,10 @@ class ClubListScreen extends React.Component<Props, State> {
|
||||||
// Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
|
// Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
getItemLayout={this.itemLayout}
|
getItemLayout={this.itemLayout}
|
||||||
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{paddingTop: containerPaddingTop}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
@ -234,4 +241,4 @@ class ClubListScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ClubListScreen;
|
export default withCollapsible(ClubListScreen);
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Button, Caption, Card, Headline, Paragraph, withTheme} from 'react-native-paper';
|
import {Button, Caption, Card, Headline, Paragraph, withTheme} from 'react-native-paper';
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {withCollapsible} from "../../../utils/withCollapsible";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import type {Device} from "./EquipmentListScreen";
|
import type {Device} from "./EquipmentListScreen";
|
||||||
import {View} from "react-native";
|
import {Animated, View} from "react-native";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {getRelativeDateString} from "../../../utils/EquipmentBooking";
|
import {getRelativeDateString} from "../../../utils/EquipmentBooking";
|
||||||
import CollapsibleScrollView from "../../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
|
@ -19,6 +20,7 @@ type Props = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -42,13 +44,21 @@ class EquipmentConfirmScreen extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
const item = this.item;
|
const item = this.item;
|
||||||
const dates = this.dates;
|
const dates = this.dates;
|
||||||
if (item != null && dates != null) {
|
if (item != null && dates != null) {
|
||||||
const start = new Date(dates[0]);
|
const start = new Date(dates[0]);
|
||||||
const end = new Date(dates[1]);
|
const end = new Date(dates[1]);
|
||||||
return (
|
return (
|
||||||
<CollapsibleScrollView>
|
<Animated.ScrollView
|
||||||
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
minHeight: '100%'
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}>
|
||||||
<Card style={{margin: 5}}>
|
<Card style={{margin: 5}}>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
|
|
@ -93,7 +103,7 @@ class EquipmentConfirmScreen extends React.Component<Props> {
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card>
|
</Card>
|
||||||
</CollapsibleScrollView>
|
</Animated.ScrollView>
|
||||||
);
|
);
|
||||||
} else
|
} else
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -102,4 +112,4 @@ class EquipmentConfirmScreen extends React.Component<Props> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(EquipmentConfirmScreen);
|
export default withCollapsible(withTheme(EquipmentConfirmScreen));
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {View} from "react-native";
|
import {Animated, View} from "react-native";
|
||||||
import {Button, withTheme} from 'react-native-paper';
|
import {Button, withTheme} from 'react-native-paper';
|
||||||
import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
|
import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {withCollapsible} from "../../../utils/withCollapsible";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
|
|
@ -12,11 +14,11 @@ import EquipmentListItem from "../../../components/Lists/Equipment/EquipmentList
|
||||||
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
||||||
import {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
import {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
||||||
import AsyncStorageManager from "../../../managers/AsyncStorageManager";
|
import AsyncStorageManager from "../../../managers/AsyncStorageManager";
|
||||||
import CollapsibleFlatList from "../../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -27,7 +29,7 @@ export type Device = {
|
||||||
id: number,
|
id: number,
|
||||||
name: string,
|
name: string,
|
||||||
caution: number,
|
caution: number,
|
||||||
booked_at: Array<{ begin: string, end: string }>,
|
booked_at: Array<{begin: string, end: string}>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RentedDevice = {
|
export type RentedDevice = {
|
||||||
|
|
@ -131,12 +133,20 @@ class EquipmentListScreen extends React.Component<Props, State> {
|
||||||
if (fetchedData != null)
|
if (fetchedData != null)
|
||||||
this.userRents = fetchedData["locations"];
|
this.userRents = fetchedData["locations"];
|
||||||
}
|
}
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<CollapsibleFlatList
|
<Animated.FlatList
|
||||||
keyExtractor={this.keyExtractor}
|
keyExtractor={this.keyExtractor}
|
||||||
renderItem={this.getRenderItem}
|
renderItem={this.getRenderItem}
|
||||||
ListHeaderComponent={this.getListHeader()}
|
ListHeaderComponent={this.getListHeader()}
|
||||||
data={this.data}
|
data={this.data}
|
||||||
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
minHeight: '100%'
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
@ -193,4 +203,4 @@ class EquipmentListScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(EquipmentListScreen);
|
export default withCollapsible(withTheme(EquipmentListScreen));
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Button, Caption, Card, Headline, Subheading, withTheme} from 'react-native-paper';
|
import {Button, Caption, Card, Headline, Subheading, withTheme} from 'react-native-paper';
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {withCollapsible} from "../../../utils/withCollapsible";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import type {Device} from "./EquipmentListScreen";
|
import type {Device} from "./EquipmentListScreen";
|
||||||
import {BackHandler, View} from "react-native";
|
import {Animated, BackHandler, View} from "react-native";
|
||||||
import * as Animatable from "react-native-animatable";
|
import * as Animatable from "react-native-animatable";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {CalendarList} from "react-native-calendars";
|
import {CalendarList} from "react-native-calendars";
|
||||||
|
|
@ -20,7 +22,6 @@ import {
|
||||||
isEquipmentAvailable
|
isEquipmentAvailable
|
||||||
} from "../../../utils/EquipmentBooking";
|
} from "../../../utils/EquipmentBooking";
|
||||||
import ConnectionManager from "../../../managers/ConnectionManager";
|
import ConnectionManager from "../../../managers/ConnectionManager";
|
||||||
import CollapsibleScrollView from "../../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
|
@ -30,6 +31,7 @@ type Props = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -267,6 +269,8 @@ class EquipmentRentScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
|
|
||||||
const item = this.item;
|
const item = this.item;
|
||||||
const start = this.getBookStartDate();
|
const start = this.getBookStartDate();
|
||||||
const end = this.getBookEndDate();
|
const end = this.getBookEndDate();
|
||||||
|
|
@ -276,7 +280,14 @@ class EquipmentRentScreen extends React.Component<Props, State> {
|
||||||
const firstAvailability = getFirstEquipmentAvailability(item);
|
const firstAvailability = getFirstEquipmentAvailability(item);
|
||||||
return (
|
return (
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
<CollapsibleScrollView>
|
<Animated.ScrollView
|
||||||
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
minHeight: '100%'
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}>
|
||||||
<Card style={{margin: 5}}>
|
<Card style={{margin: 5}}>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
|
|
@ -385,7 +396,7 @@ class EquipmentRentScreen extends React.Component<Props, State> {
|
||||||
}}
|
}}
|
||||||
style={{marginBottom: 50}}
|
style={{marginBottom: 50}}
|
||||||
/>
|
/>
|
||||||
</CollapsibleScrollView>
|
</Animated.ScrollView>
|
||||||
<LoadingConfirmDialog
|
<LoadingConfirmDialog
|
||||||
visible={this.state.dialogVisible}
|
visible={this.state.dialogVisible}
|
||||||
onDismiss={this.onDialogDismiss}
|
onDismiss={this.onDialogDismiss}
|
||||||
|
|
@ -438,4 +449,4 @@ class EquipmentRentScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(EquipmentRentScreen);
|
export default withCollapsible(withTheme(EquipmentRentScreen));
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Image, KeyboardAvoidingView, StyleSheet, View} from "react-native";
|
import {Animated, Dimensions, Image, KeyboardAvoidingView, StyleSheet, View} from "react-native";
|
||||||
import {Button, Card, HelperText, TextInput, withTheme} from 'react-native-paper';
|
import {Button, Card, HelperText, TextInput, withTheme} from 'react-native-paper';
|
||||||
import ConnectionManager from "../../managers/ConnectionManager";
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import ErrorDialog from "../../components/Dialogs/ErrorDialog";
|
import ErrorDialog from "../../components/Dialogs/ErrorDialog";
|
||||||
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
|
|
@ -13,11 +15,11 @@ import AvailableWebsites from "../../constants/AvailableWebsites";
|
||||||
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 LinearGradient from "react-native-linear-gradient";
|
import LinearGradient from "react-native-linear-gradient";
|
||||||
import CollapsibleScrollView from "../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
route: { params: { nextScreen: string } },
|
route: { params: { nextScreen: string } },
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
theme: CustomTheme
|
theme: CustomTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,6 +56,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
onEmailChange: (value: string) => null;
|
onEmailChange: (value: string) => null;
|
||||||
onPasswordChange: (value: string) => null;
|
onPasswordChange: (value: string) => null;
|
||||||
passwordInputRef: { current: null | TextInput };
|
passwordInputRef: { current: null | TextInput };
|
||||||
|
windowHeight: number;
|
||||||
|
|
||||||
nextScreen: string | null;
|
nextScreen: string | null;
|
||||||
|
|
||||||
|
|
@ -63,6 +66,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
this.onEmailChange = this.onInputChange.bind(this, true);
|
this.onEmailChange = this.onInputChange.bind(this, true);
|
||||||
this.onPasswordChange = this.onInputChange.bind(this, false);
|
this.onPasswordChange = this.onInputChange.bind(this, false);
|
||||||
this.props.navigation.addListener('focus', this.onScreenFocus);
|
this.props.navigation.addListener('focus', this.onScreenFocus);
|
||||||
|
this.windowHeight = Dimensions.get('window').height;
|
||||||
}
|
}
|
||||||
|
|
||||||
onScreenFocus = () => {
|
onScreenFocus = () => {
|
||||||
|
|
@ -319,13 +323,13 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
{this.getFormInput()}
|
{this.getFormInput()}
|
||||||
<Card.Actions style={{flexWrap: "wrap"}}>
|
<Card.Actions style={{flexWrap: "wrap"}}>
|
||||||
<Button
|
<Button
|
||||||
icon="lock-question"
|
icon="lock-question"
|
||||||
mode="contained"
|
mode="contained"
|
||||||
onPress={this.onResetPasswordClick}
|
onPress={this.onResetPasswordClick}
|
||||||
color={this.props.theme.colors.warning}
|
color={this.props.theme.colors.warning}
|
||||||
style={{marginRight: 'auto', marginBottom: 20}}>
|
style={{marginRight: 'auto', marginBottom: 20}}>
|
||||||
{i18n.t("screens.login.resetPassword")}
|
{i18n.t("screens.login.resetPassword")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
icon="send"
|
icon="send"
|
||||||
mode="contained"
|
mode="contained"
|
||||||
|
|
@ -355,6 +359,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
style={{
|
style={{
|
||||||
|
|
@ -370,10 +375,16 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
enabled
|
enabled
|
||||||
keyboardVerticalOffset={100}
|
keyboardVerticalOffset={100}
|
||||||
>
|
>
|
||||||
<CollapsibleScrollView>
|
<Animated.ScrollView
|
||||||
<View style={{height: "100%"}}>
|
onScroll={onScroll}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
|
style={{flex: 1}}
|
||||||
|
>
|
||||||
|
<View style={{height: this.windowHeight - containerPaddingTop}}>
|
||||||
{this.getMainCard()}
|
{this.getMainCard()}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
||||||
<MascotPopup
|
<MascotPopup
|
||||||
visible={this.state.mascotDialogVisible}
|
visible={this.state.mascotDialogVisible}
|
||||||
title={i18n.t("screens.login.mascotDialog.title")}
|
title={i18n.t("screens.login.mascotDialog.title")}
|
||||||
|
|
@ -394,7 +405,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
onDismiss={this.hideErrorDialog}
|
onDismiss={this.hideErrorDialog}
|
||||||
errorCode={this.state.dialogError}
|
errorCode={this.state.dialogError}
|
||||||
/>
|
/>
|
||||||
</CollapsibleScrollView>
|
</Animated.ScrollView>
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
</LinearGradient>
|
</LinearGradient>
|
||||||
);
|
);
|
||||||
|
|
@ -420,4 +431,4 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withTheme(LoginScreen);
|
export default withCollapsible(withTheme(LoginScreen));
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {FlatList, StyleSheet, View} from "react-native";
|
import {Animated, FlatList, StyleSheet, View} from "react-native";
|
||||||
import {Avatar, Button, Card, Divider, List, Paragraph, withTheme} from 'react-native-paper';
|
import {Avatar, Button, Card, Divider, List, Paragraph, withTheme} from 'react-native-paper';
|
||||||
import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
|
import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import LogoutDialog from "../../components/Amicale/LogoutDialog";
|
import LogoutDialog from "../../components/Amicale/LogoutDialog";
|
||||||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
||||||
|
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
import type {cardList} from "../../components/Lists/CardList/CardList";
|
import type {cardList} from "../../components/Lists/CardList/CardList";
|
||||||
import CardList from "../../components/Lists/CardList/CardList";
|
import CardList from "../../components/Lists/CardList/CardList";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
|
|
@ -14,11 +17,11 @@ import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import AvailableWebsites from "../../constants/AvailableWebsites";
|
import AvailableWebsites from "../../constants/AvailableWebsites";
|
||||||
import Mascot, {MASCOT_STYLE} from "../../components/Mascot/Mascot";
|
import Mascot, {MASCOT_STYLE} from "../../components/Mascot/Mascot";
|
||||||
import ServicesManager, {SERVICES_KEY} from "../../managers/ServicesManager";
|
import ServicesManager, {SERVICES_KEY} from "../../managers/ServicesManager";
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -94,11 +97,20 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
if (data[0] != null) {
|
if (data[0] != null) {
|
||||||
this.data = data[0];
|
this.data = data[0];
|
||||||
}
|
}
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
<CollapsibleFlatList
|
<Animated.FlatList
|
||||||
renderItem={this.getRenderItem}
|
renderItem={this.getRenderItem}
|
||||||
data={this.flatListData}
|
data={this.flatListData}
|
||||||
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT,
|
||||||
|
minHeight: '100%'
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
/>
|
/>
|
||||||
<LogoutDialog
|
<LogoutDialog
|
||||||
{...this.props}
|
{...this.props}
|
||||||
|
|
@ -429,4 +441,4 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withTheme(ProfileScreen);
|
export default withCollapsible(withTheme(ProfileScreen));
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {RefreshControl, View} from "react-native";
|
import {FlatList, RefreshControl, View} from "react-native";
|
||||||
import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
|
import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
|
||||||
import {getTimeOnlyString, stringToDate} from "../../utils/Planning";
|
import {getTimeOnlyString, stringToDate} from "../../utils/Planning";
|
||||||
import VoteTease from "../../components/Amicale/Vote/VoteTease";
|
import VoteTease from "../../components/Amicale/Vote/VoteTease";
|
||||||
|
|
@ -15,7 +15,6 @@ import MascotPopup from "../../components/Mascot/MascotPopup";
|
||||||
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
||||||
import {Button} from "react-native-paper";
|
import {Button} from "react-native-paper";
|
||||||
import VoteNotAvailable from "../../components/Amicale/Vote/VoteNotAvailable";
|
import VoteNotAvailable from "../../components/Amicale/Vote/VoteNotAvailable";
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
export type team = {
|
export type team = {
|
||||||
id: number,
|
id: number,
|
||||||
|
|
@ -247,17 +246,20 @@ export default class VoteScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
this.generateDateObject();
|
this.generateDateObject();
|
||||||
return (
|
return (
|
||||||
<CollapsibleFlatList
|
<View>
|
||||||
data={this.mainFlatListData}
|
{/*$FlowFixMe*/}
|
||||||
refreshControl={
|
<FlatList
|
||||||
<RefreshControl
|
data={this.mainFlatListData}
|
||||||
refreshing={false}
|
refreshControl={
|
||||||
onRefresh={this.reloadData}
|
<RefreshControl
|
||||||
/>
|
refreshing={false}
|
||||||
}
|
onRefresh={this.reloadData}
|
||||||
extraData={this.state.hasVoted.toString()}
|
/>
|
||||||
renderItem={this.mainRenderItem}
|
}
|
||||||
/>
|
extraData={this.state.hasVoted.toString()}
|
||||||
|
renderItem={this.mainRenderItem}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
26
src/screens/Game/screens/GameEndScreen.js
Normal file
26
src/screens/Game/screens/GameEndScreen.js
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
|
import {withTheme} from "react-native-paper";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
navigation: StackNavigationProp,
|
||||||
|
theme: CustomTheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class GameEndScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withTheme(GameEndScreen);
|
||||||
|
|
@ -4,7 +4,7 @@ import * as React from "react";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import {Button, Card, Divider, Headline, Paragraph, Text, withTheme} from "react-native-paper";
|
import {Button, Card, Divider, Headline, Paragraph, Text, withTheme} from "react-native-paper";
|
||||||
import {View} from "react-native";
|
import {ScrollView, View} from "react-native";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import Mascot, {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
import Mascot, {MASCOT_STYLE} from "../../../components/Mascot/Mascot";
|
||||||
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
import MascotPopup from "../../../components/Mascot/MascotPopup";
|
||||||
|
|
@ -17,7 +17,6 @@ import * as Animatable from "react-native-animatable";
|
||||||
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
|
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
|
||||||
import LinearGradient from "react-native-linear-gradient";
|
import LinearGradient from "react-native-linear-gradient";
|
||||||
import SpeechArrow from "../../../components/Mascot/SpeechArrow";
|
import SpeechArrow from "../../../components/Mascot/SpeechArrow";
|
||||||
import CollapsibleScrollView from "../../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type GameStats = {
|
type GameStats = {
|
||||||
score: number,
|
score: number,
|
||||||
|
|
@ -418,7 +417,7 @@ class GameStartScreen extends React.Component<Props, State> {
|
||||||
start={{x: 0, y: 0}}
|
start={{x: 0, y: 0}}
|
||||||
end={{x: 0, y: 1}}
|
end={{x: 0, y: 1}}
|
||||||
>
|
>
|
||||||
<CollapsibleScrollView>
|
<ScrollView>
|
||||||
{this.getMainContent()}
|
{this.getMainContent()}
|
||||||
<MascotPopup
|
<MascotPopup
|
||||||
visible={this.state.mascotDialogVisible}
|
visible={this.state.mascotDialogVisible}
|
||||||
|
|
@ -435,7 +434,7 @@ class GameStartScreen extends React.Component<Props, State> {
|
||||||
}}
|
}}
|
||||||
emotion={MASCOT_STYLE.COOL}
|
emotion={MASCOT_STYLE.COOL}
|
||||||
/>
|
/>
|
||||||
</CollapsibleScrollView>
|
</ScrollView>
|
||||||
</LinearGradient>
|
</LinearGradient>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {FlatList} from 'react-native';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import DashboardItem from "../../components/Home/EventDashboardItem";
|
import DashboardItem from "../../components/Home/EventDashboardItem";
|
||||||
import WebSectionList from "../../components/Screens/WebSectionList";
|
import WebSectionList from "../../components/Screens/WebSectionList";
|
||||||
import {ActivityIndicator, Headline, withTheme} from 'react-native-paper';
|
import {Headline, withTheme} from 'react-native-paper';
|
||||||
import FeedItem from "../../components/Home/FeedItem";
|
import FeedItem from "../../components/Home/FeedItem";
|
||||||
import SmallDashboardItem from "../../components/Home/SmallDashboardItem";
|
import SmallDashboardItem from "../../components/Home/SmallDashboardItem";
|
||||||
import PreviewEventDashboardItem from "../../components/Home/PreviewEventDashboardItem";
|
import PreviewEventDashboardItem from "../../components/Home/PreviewEventDashboardItem";
|
||||||
|
|
@ -16,7 +16,6 @@ import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHead
|
||||||
import AnimatedFAB from "../../components/Animations/AnimatedFAB";
|
import AnimatedFAB from "../../components/Animations/AnimatedFAB";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import * as Animatable from "react-native-animatable";
|
|
||||||
import {View} from "react-native-animatable";
|
import {View} from "react-native-animatable";
|
||||||
import ConnectionManager from "../../managers/ConnectionManager";
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
import LogoutDialog from "../../components/Amicale/LogoutDialog";
|
import LogoutDialog from "../../components/Amicale/LogoutDialog";
|
||||||
|
|
@ -24,8 +23,6 @@ import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
||||||
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 DashboardManager from "../../managers/DashboardManager";
|
import DashboardManager from "../../managers/DashboardManager";
|
||||||
import type {ServiceItem} from "../../managers/ServicesManager";
|
|
||||||
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
|
|
||||||
// import DATA from "../dashboard_data.json";
|
// import DATA from "../dashboard_data.json";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -64,6 +61,11 @@ export type fullDashboard = {
|
||||||
available_tutorials: number,
|
available_tutorials: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type dashboardItem = {
|
||||||
|
id: string,
|
||||||
|
content: Array<{ [key: string]: any }>
|
||||||
|
};
|
||||||
|
|
||||||
export type event = {
|
export type event = {
|
||||||
id: number,
|
id: number,
|
||||||
title: string,
|
title: string,
|
||||||
|
|
@ -76,6 +78,12 @@ export type event = {
|
||||||
url: string,
|
url: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type listSection = {
|
||||||
|
title: string,
|
||||||
|
data: Array<dashboardItem> | Array<feedItem>,
|
||||||
|
id: string
|
||||||
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
route: { params: any, ... },
|
route: { params: any, ... },
|
||||||
|
|
@ -195,41 +203,84 @@ class HomeScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
hideDisconnectDialog = () => this.setState({dialogVisible: false});
|
hideDisconnectDialog = () => this.setState({dialogVisible: false});
|
||||||
|
|
||||||
openScanner = () => this.props.navigation.navigate("scanner");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the dataset to be used in the FlatList
|
* Creates the dataset to be used in the FlatList
|
||||||
*
|
*
|
||||||
* @param fetchedData
|
* @param fetchedData
|
||||||
* @param isLoading
|
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
createDataset = (fetchedData: rawDashboard | null, isLoading: boolean) => {
|
createDataset = (fetchedData: rawDashboard) => {
|
||||||
// fetchedData = DATA;
|
// fetchedData = DATA;
|
||||||
if (fetchedData != null) {
|
let dashboardData;
|
||||||
if (fetchedData.news_feed != null)
|
if (fetchedData.news_feed != null)
|
||||||
this.currentNewFeed = fetchedData.news_feed.data;
|
this.currentNewFeed = fetchedData.news_feed.data;
|
||||||
if (fetchedData.dashboard != null)
|
if (fetchedData.dashboard != null)
|
||||||
this.currentDashboard = fetchedData.dashboard;
|
this.currentDashboard = fetchedData.dashboard;
|
||||||
}
|
|
||||||
if (this.currentNewFeed.length > 0)
|
if (fetchedData.dashboard != null)
|
||||||
return [
|
dashboardData = this.generateDashboardDataset(fetchedData.dashboard);
|
||||||
{
|
|
||||||
title: i18n.t("screens.home.feedTitle"),
|
|
||||||
data: this.currentNewFeed,
|
|
||||||
id: SECTIONS_ID[1]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
else
|
else
|
||||||
return [
|
dashboardData = this.generateDashboardDataset(null);
|
||||||
{
|
return [
|
||||||
title: isLoading ? i18n.t("screens.home.feedLoading") : i18n.t("screens.home.feedError"),
|
{
|
||||||
data: [],
|
title: '',
|
||||||
id: SECTIONS_ID[1]
|
data: dashboardData,
|
||||||
}
|
id: SECTIONS_ID[0]
|
||||||
];
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t("screens.home.feedTitle"),
|
||||||
|
data: this.currentNewFeed,
|
||||||
|
id: SECTIONS_ID[1]
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the dataset associated to the dashboard to be displayed in the FlatList as a section
|
||||||
|
*
|
||||||
|
* @param dashboardData
|
||||||
|
* @return {Array<dashboardItem>}
|
||||||
|
*/
|
||||||
|
generateDashboardDataset(dashboardData: fullDashboard | null): Array<dashboardItem> {
|
||||||
|
return [
|
||||||
|
{id: 'actions', content: []},
|
||||||
|
{
|
||||||
|
id: 'top',
|
||||||
|
content: this.dashboardManager.getCurrentDashboard(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'event',
|
||||||
|
content: dashboardData == null ? [] : dashboardData.today_events
|
||||||
|
},
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a dashboard item
|
||||||
|
*
|
||||||
|
* @param item The item to display
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
getDashboardItem(item: dashboardItem) {
|
||||||
|
let content = item.content;
|
||||||
|
if (item.id === 'event')
|
||||||
|
return this.getDashboardEvent(content);
|
||||||
|
else if (item.id === 'top')
|
||||||
|
return this.getDashboardRow(content);
|
||||||
|
else
|
||||||
|
return this.getDashboardActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a dashboard item with action buttons
|
||||||
|
*
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
getDashboardActions() {
|
||||||
|
return <ActionsDashBoardItem {...this.props} isLoggedIn={this.isLoggedIn}/>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the time limit depending on the current day:
|
* Gets the time limit depending on the current day:
|
||||||
* 17:30 for every day of the week except for thursday 11:30
|
* 17:30 for every day of the week except for thursday 11:30
|
||||||
|
|
@ -376,13 +427,22 @@ class HomeScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a dashboard item with action buttons
|
* Gets a dashboard shortcut item
|
||||||
*
|
*
|
||||||
|
* @param item
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
getDashboardActions() {
|
dashboardRowRenderItem = ({item}: { item: DashboardItem }) => {
|
||||||
return <ActionsDashBoardItem {...this.props} isLoggedIn={this.isLoggedIn}/>;
|
return (
|
||||||
}
|
<SmallDashboardItem
|
||||||
|
image={item.image}
|
||||||
|
onPress={item.onPress}
|
||||||
|
badgeCount={this.currentDashboard != null && item.badgeFunction != null
|
||||||
|
? item.badgeFunction(this.currentDashboard)
|
||||||
|
: null}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a dashboard item with a row of shortcut buttons.
|
* Gets a dashboard item with a row of shortcut buttons.
|
||||||
|
|
@ -390,7 +450,7 @@ class HomeScreen extends React.Component<Props, State> {
|
||||||
* @param content
|
* @param content
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
getDashboardRow(content: Array<ServiceItem>) {
|
getDashboardRow(content: Array<DashboardItem>) {
|
||||||
return (
|
return (
|
||||||
//$FlowFixMe
|
//$FlowFixMe
|
||||||
<FlatList
|
<FlatList
|
||||||
|
|
@ -406,24 +466,6 @@ class HomeScreen extends React.Component<Props, State> {
|
||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a dashboard shortcut item
|
|
||||||
*
|
|
||||||
* @param item
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
dashboardRowRenderItem = ({item}: { item: ServiceItem }) => {
|
|
||||||
return (
|
|
||||||
<SmallDashboardItem
|
|
||||||
image={item.image}
|
|
||||||
onPress={item.onPress}
|
|
||||||
badgeCount={this.currentDashboard != null && item.badgeFunction != null
|
|
||||||
? item.badgeFunction(this.currentDashboard)
|
|
||||||
: null}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a render item for the given feed object
|
* Gets a render item for the given feed object
|
||||||
*
|
*
|
||||||
|
|
@ -449,15 +491,28 @@ class HomeScreen extends React.Component<Props, State> {
|
||||||
* @param section The current section
|
* @param section The current section
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
getRenderItem = ({item}: { item: feedItem, }) => this.getFeedItem(item);
|
getRenderItem = ({item, section}: {
|
||||||
|
item: { [key: string]: any },
|
||||||
|
section: listSection
|
||||||
|
}) => {
|
||||||
|
if (section.id === SECTIONS_ID[0]) {
|
||||||
|
const data: dashboardItem = item;
|
||||||
|
return this.getDashboardItem(data);
|
||||||
|
} else {
|
||||||
|
const data: feedItem = item;
|
||||||
|
return this.getFeedItem(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
openScanner = () => this.props.navigation.navigate("scanner");
|
||||||
|
|
||||||
onScroll = (event: SyntheticEvent<EventTarget>) => {
|
onScroll = (event: SyntheticEvent<EventTarget>) => {
|
||||||
if (this.fabRef.current != null)
|
if (this.fabRef.current != null)
|
||||||
this.fabRef.current.onScroll(event);
|
this.fabRef.current.onScroll(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderSectionHeader = (data: { section: { [key: string]: any } }, isLoading: boolean) => {
|
renderSectionHeader = (data: { [key: string]: any }) => {
|
||||||
if (data.section.data.length > 0)
|
if (data.section.title !== "")
|
||||||
return (
|
return (
|
||||||
<Headline style={{
|
<Headline style={{
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
|
|
@ -468,59 +523,7 @@ class HomeScreen extends React.Component<Props, State> {
|
||||||
</Headline>
|
</Headline>
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
return (
|
return null;
|
||||||
<View>
|
|
||||||
<Headline style={{
|
|
||||||
textAlign: "center",
|
|
||||||
marginTop: 50,
|
|
||||||
marginBottom: 10,
|
|
||||||
marginLeft: 20,
|
|
||||||
marginRight: 20,
|
|
||||||
color: this.props.theme.colors.textDisabled
|
|
||||||
}}>
|
|
||||||
{data.section.title}
|
|
||||||
</Headline>
|
|
||||||
{isLoading
|
|
||||||
? <ActivityIndicator
|
|
||||||
style={{
|
|
||||||
marginTop: 10
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
: <MaterialCommunityIcons
|
|
||||||
name={"access-point-network-off"}
|
|
||||||
size={100}
|
|
||||||
color={this.props.theme.colors.textDisabled}
|
|
||||||
style={{
|
|
||||||
marginLeft: "auto",
|
|
||||||
marginRight: "auto",
|
|
||||||
}}
|
|
||||||
/>}
|
|
||||||
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getListHeader = (fetchedData: rawDashboard) => {
|
|
||||||
let dashboard = null;
|
|
||||||
if (fetchedData != null) {
|
|
||||||
dashboard = fetchedData.dashboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Animatable.View
|
|
||||||
animation={"fadeInDown"}
|
|
||||||
duration={500}
|
|
||||||
useNativeDriver={true}
|
|
||||||
>
|
|
||||||
{this.getDashboardActions()}
|
|
||||||
{this.getDashboardRow(this.dashboardManager.getCurrentDashboard())}
|
|
||||||
{this.getDashboardEvent(
|
|
||||||
dashboard == null
|
|
||||||
? []
|
|
||||||
: dashboard.today_events
|
|
||||||
)}
|
|
||||||
</Animatable.View>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -553,7 +556,6 @@ class HomeScreen extends React.Component<Props, State> {
|
||||||
onScroll={this.onScroll}
|
onScroll={this.onScroll}
|
||||||
showError={false}
|
showError={false}
|
||||||
renderSectionHeader={this.renderSectionHeader}
|
renderSectionHeader={this.renderSectionHeader}
|
||||||
renderListHeaderComponent={this.getListHeader}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<MascotPopup
|
<MascotPopup
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Avatar, Button, Card, Paragraph, withTheme} from "react-native-paper";
|
import {Avatar, Button, Card, Paragraph, withTheme} from "react-native-paper";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {Linking} from "react-native";
|
import {Linking, ScrollView} from "react-native";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import CollapsibleScrollView from "../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
theme: CustomTheme
|
theme: CustomTheme
|
||||||
|
|
@ -77,7 +76,7 @@ class FeedbackScreen extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<CollapsibleScrollView style={{padding: 5}}>
|
<ScrollView style={{padding: 5}}>
|
||||||
<Card>
|
<Card>
|
||||||
<Card.Title
|
<Card.Title
|
||||||
title={i18n.t('screens.feedback.bugs')}
|
title={i18n.t('screens.feedback.bugs')}
|
||||||
|
|
@ -108,7 +107,7 @@ class FeedbackScreen extends React.Component<Props> {
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
{this.getButtons(false)}
|
{this.getButtons(false)}
|
||||||
</Card>
|
</Card>
|
||||||
</CollapsibleScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import DashboardEditAccordion from "../../../components/Lists/DashboardEdit/Dash
|
||||||
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 i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import CollapsibleFlatList from "../../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
|
@ -109,43 +108,43 @@ class DashboardEditScreen extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getListHeader() {
|
|
||||||
return (
|
|
||||||
<Card style={{margin: 5}}>
|
|
||||||
<Card.Content>
|
|
||||||
<View style={{padding: 5}}>
|
|
||||||
<Button
|
|
||||||
mode={"contained"}
|
|
||||||
onPress={this.undoDashboard}
|
|
||||||
style={{
|
|
||||||
marginLeft: "auto",
|
|
||||||
marginRight: "auto",
|
|
||||||
marginBottom: 10,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{i18n.t("screens.settings.dashboardEdit.undo")}
|
|
||||||
</Button>
|
|
||||||
<View style={{height: 50}}>
|
|
||||||
{this.getDashboard(this.state.currentDashboard)}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<Paragraph style={{textAlign: "center"}}>
|
|
||||||
{i18n.t("screens.settings.dashboardEdit.message")}
|
|
||||||
</Paragraph>
|
|
||||||
</Card.Content>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<CollapsibleFlatList
|
<View style={{flex: 1}}>
|
||||||
data={this.content}
|
<View style={{
|
||||||
renderItem={this.renderItem}
|
padding: 5
|
||||||
ListHeaderComponent={this.getListHeader()}
|
}}>
|
||||||
style={{}}
|
<Button
|
||||||
/>
|
mode={"contained"}
|
||||||
|
onPress={this.undoDashboard}
|
||||||
|
style={{
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18n.t("screens.settings.dashboardEdit.undo")}
|
||||||
|
</Button>
|
||||||
|
<View style={{
|
||||||
|
height: 50
|
||||||
|
}}>
|
||||||
|
{this.getDashboard(this.state.currentDashboard)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<FlatList
|
||||||
|
data={this.content}
|
||||||
|
renderItem={this.renderItem}
|
||||||
|
ListHeaderComponent={<Card style={{margin: 5}}>
|
||||||
|
<Card.Content>
|
||||||
|
<Paragraph
|
||||||
|
style={{textAlign: "center"}}>{i18n.t("screens.settings.dashboardEdit.message")}</Paragraph>
|
||||||
|
</Card.Content>
|
||||||
|
|
||||||
|
</Card>}
|
||||||
|
style={{}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {View} from "react-native";
|
import {ScrollView, View} from "react-native";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import ThemeManager from '../../../managers/ThemeManager';
|
import ThemeManager from '../../../managers/ThemeManager';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
|
|
@ -10,7 +10,6 @@ import {Card, List, Switch, ToggleButton, withTheme} from 'react-native-paper';
|
||||||
import {Appearance} from "react-native-appearance";
|
import {Appearance} from "react-native-appearance";
|
||||||
import CustomSlider from "../../../components/Overrides/CustomSlider";
|
import CustomSlider from "../../../components/Overrides/CustomSlider";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import CollapsibleScrollView from "../../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
|
@ -188,7 +187,7 @@ class SettingsScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<CollapsibleScrollView>
|
<ScrollView>
|
||||||
<Card style={{margin: 5}}>
|
<Card style={{margin: 5}}>
|
||||||
<Card.Title title={i18n.t('screens.settings.generalCard')}/>
|
<Card.Title title={i18n.t('screens.settings.generalCard')}/>
|
||||||
<List.Section>
|
<List.Section>
|
||||||
|
|
@ -244,11 +243,11 @@ class SettingsScreen extends React.Component<Props, State> {
|
||||||
<List.Section>
|
<List.Section>
|
||||||
{this.state.isDebugUnlocked
|
{this.state.isDebugUnlocked
|
||||||
? this.getNavigateItem(
|
? this.getNavigateItem(
|
||||||
"debug",
|
"debug",
|
||||||
"bug-check",
|
"bug-check",
|
||||||
i18n.t('screens.debug.title'),
|
i18n.t('screens.debug.title'),
|
||||||
""
|
""
|
||||||
)
|
)
|
||||||
: null}
|
: null}
|
||||||
{this.getNavigateItem(
|
{this.getNavigateItem(
|
||||||
"about",
|
"about",
|
||||||
|
|
@ -265,7 +264,7 @@ class SettingsScreen extends React.Component<Props, State> {
|
||||||
)}
|
)}
|
||||||
</List.Section>
|
</List.Section>
|
||||||
</Card>
|
</Card>
|
||||||
</CollapsibleScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Image, View} from 'react-native';
|
import {Image, ScrollView, View} from 'react-native';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {Card, List, Paragraph, Text} from 'react-native-paper';
|
import {Card, List, Paragraph, Text} from 'react-native-paper';
|
||||||
import CustomTabBar from "../../../components/Tabbar/CustomTabBar";
|
import CustomTabBar from "../../../components/Tabbar/CustomTabBar";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import CollapsibleScrollView from "../../../components/Collapsible/CollapsibleScrollView";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
|
@ -21,7 +20,7 @@ export default class ProximoAboutScreen extends React.Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<CollapsibleScrollView style={{padding: 5}}>
|
<ScrollView style={{padding: 5}}>
|
||||||
<View style={{
|
<View style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 100,
|
height: 100,
|
||||||
|
|
@ -53,7 +52,7 @@ export default class ProximoAboutScreen extends React.Component<Props> {
|
||||||
<Paragraph>{i18n.t('screens.proximo.paymentMethodsDescription')}</Paragraph>
|
<Paragraph>{i18n.t('screens.proximo.paymentMethodsDescription')}</Paragraph>
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card>
|
</Card>
|
||||||
</CollapsibleScrollView>
|
</ScrollView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Image, Platform, ScrollView, View} from "react-native";
|
import {Animated, Image, Platform, ScrollView, View} from "react-native";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import CustomModal from "../../../components/Overrides/CustomModal";
|
import CustomModal from "../../../components/Overrides/CustomModal";
|
||||||
import {RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper";
|
import {RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper";
|
||||||
import {stringMatchQuery} from "../../../utils/Search";
|
import {stringMatchQuery} from "../../../utils/Search";
|
||||||
import ProximoListItem from "../../../components/Lists/Proximo/ProximoListItem";
|
import ProximoListItem from "../../../components/Lists/Proximo/ProximoListItem";
|
||||||
import MaterialHeaderButtons, {Item} from "../../../components/Overrides/CustomHeaderButton";
|
import MaterialHeaderButtons, {Item} from "../../../components/Overrides/CustomHeaderButton";
|
||||||
|
import {withCollapsible} from "../../../utils/withCollapsible";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
import CollapsibleFlatList from "../../../components/Collapsible/CollapsibleFlatList";
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
|
||||||
function sortPrice(a, b) {
|
function sortPrice(a, b) {
|
||||||
return a.price - b.price;
|
return a.price - b.price;
|
||||||
|
|
@ -42,6 +43,7 @@ type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
route: { params: { data: { data: Object }, shouldFocusSearchBar: boolean } },
|
route: { params: { data: { data: Object }, shouldFocusSearchBar: boolean } },
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -298,6 +300,7 @@ class ProximoListScreen extends React.Component<Props, State> {
|
||||||
itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
|
itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<View style={{
|
<View style={{
|
||||||
height: '100%'
|
height: '100%'
|
||||||
|
|
@ -305,7 +308,7 @@ class ProximoListScreen extends React.Component<Props, State> {
|
||||||
<CustomModal onRef={this.onModalRef}>
|
<CustomModal onRef={this.onModalRef}>
|
||||||
{this.state.modalCurrentDisplayItem}
|
{this.state.modalCurrentDisplayItem}
|
||||||
</CustomModal>
|
</CustomModal>
|
||||||
<CollapsibleFlatList
|
<Animated.FlatList
|
||||||
data={this.listData}
|
data={this.listData}
|
||||||
extraData={this.state.currentSearchString + this.state.currentSortMode}
|
extraData={this.state.currentSearchString + this.state.currentSortMode}
|
||||||
keyExtractor={this.keyExtractor}
|
keyExtractor={this.keyExtractor}
|
||||||
|
|
@ -314,10 +317,16 @@ class ProximoListScreen extends React.Component<Props, State> {
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
getItemLayout={this.itemLayout}
|
getItemLayout={this.itemLayout}
|
||||||
initialNumToRender={10}
|
initialNumToRender={10}
|
||||||
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(ProximoListScreen);
|
export default withCollapsible(withTheme(ProximoListScreen));
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,24 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import type {cardList} from "../../components/Lists/CardList/CardList";
|
import type {cardList} from "../../components/Lists/CardList/CardList";
|
||||||
import CardList from "../../components/Lists/CardList/CardList";
|
import CardList from "../../components/Lists/CardList/CardList";
|
||||||
import {Image, View} from "react-native";
|
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||||
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {Animated, Image, View} from "react-native";
|
||||||
import {Avatar, Card, Divider, List, TouchableRipple, withTheme} from "react-native-paper";
|
import {Avatar, Card, Divider, List, TouchableRipple, withTheme} from "react-native-paper";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
||||||
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
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 AsyncStorageManager from "../../managers/AsyncStorageManager";
|
import AsyncStorageManager from "../../managers/AsyncStorageManager";
|
||||||
import ServicesManager, {SERVICES_CATEGORIES_KEY} from "../../managers/ServicesManager";
|
import ServicesManager, {SERVICES_CATEGORIES_KEY} from "../../managers/ServicesManager";
|
||||||
import CollapsibleFlatList from "../../components/Collapsible/CollapsibleFlatList";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: StackNavigationProp,
|
navigation: StackNavigationProp,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,6 +106,18 @@ class ServicesScreen extends React.Component<Props, State> {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects to the given route or to the login screen if user is not logged in.
|
||||||
|
*
|
||||||
|
* @param route The route to navigate to
|
||||||
|
*/
|
||||||
|
onAmicaleServicePress(route: string) {
|
||||||
|
if (ConnectionManager.getInstance().isLoggedIn())
|
||||||
|
this.props.navigation.navigate(route);
|
||||||
|
else
|
||||||
|
this.props.navigation.navigate("login", {nextScreen: route});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list item showing a list of available services for the current category
|
* A list item showing a list of available services for the current category
|
||||||
*
|
*
|
||||||
|
|
@ -139,14 +155,20 @@ class ServicesScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<CollapsibleFlatList
|
<Animated.FlatList
|
||||||
data={this.finalDataset}
|
data={this.finalDataset}
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
keyExtractor={this.keyExtractor}
|
keyExtractor={this.keyExtractor}
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
ItemSeparatorComponent={() => <Divider/>}
|
ItemSeparatorComponent={() => <Divider/>}
|
||||||
hasTab={true}
|
|
||||||
/>
|
/>
|
||||||
<MascotPopup
|
<MascotPopup
|
||||||
visible={this.state.mascotDialogVisible}
|
visible={this.state.mascotDialogVisible}
|
||||||
|
|
@ -168,4 +190,4 @@ class ServicesScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(ServicesScreen);
|
export default withCollapsible(withTheme(ServicesScreen));
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import StackNavigator, {StackNavigationOptions} from "@react-navigation/stack";
|
||||||
export function createScreenCollapsibleStack(
|
export function createScreenCollapsibleStack(
|
||||||
name: string,
|
name: string,
|
||||||
Stack: StackNavigator,
|
Stack: StackNavigator,
|
||||||
component: React.ComponentType<any>,
|
component: React.Node,
|
||||||
title: string,
|
title: string,
|
||||||
useNativeDriver?: boolean,
|
useNativeDriver?: boolean,
|
||||||
options?: StackNavigationOptions,
|
options?: StackNavigationOptions,
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,30 @@ import {useCollapsibleStack} from "react-navigation-collapsible";
|
||||||
* This component will then receive the collapsibleStack prop.
|
* This component will then receive the collapsibleStack prop.
|
||||||
*
|
*
|
||||||
* @param Component The component to use Collapsible with
|
* @param Component The component to use Collapsible with
|
||||||
* @returns {React.ComponentType<any>}
|
* @returns {React.ComponentType<React.ClassAttributes<unknown>>}
|
||||||
*/
|
*/
|
||||||
export const withCollapsible = (Component: React.ComponentType<any>) => {
|
export const withCollapsible = (Component: any) => {
|
||||||
return React.forwardRef((props: any, ref: any) => {
|
return React.forwardRef((props: any, ref: any) => {
|
||||||
|
|
||||||
|
const {
|
||||||
|
onScroll,
|
||||||
|
onScrollWithListener,
|
||||||
|
containerPaddingTop,
|
||||||
|
scrollIndicatorInsetTop,
|
||||||
|
translateY,
|
||||||
|
progress,
|
||||||
|
opacity,
|
||||||
|
} = useCollapsibleStack();
|
||||||
return <Component
|
return <Component
|
||||||
collapsibleStack={useCollapsibleStack()}
|
collapsibleStack={{
|
||||||
|
onScroll,
|
||||||
|
onScrollWithListener,
|
||||||
|
containerPaddingTop: containerPaddingTop,
|
||||||
|
scrollIndicatorInsetTop: scrollIndicatorInsetTop,
|
||||||
|
translateY,
|
||||||
|
progress,
|
||||||
|
opacity,
|
||||||
|
}}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
{...props}
|
{...props}
|
||||||
/>;
|
/>;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue