forked from vergnet/application-amicale
Improved screen changing performances and removed tab screen animations
This commit is contained in:
parent
da92856478
commit
01e3195be7
10 changed files with 79 additions and 151 deletions
15
App.js
15
App.js
|
@ -9,7 +9,6 @@ import {AppLoading} from 'expo';
|
|||
import type {CustomTheme} from "./src/managers/ThemeManager";
|
||||
import ThemeManager from './src/managers/ThemeManager';
|
||||
import {NavigationContainer} from '@react-navigation/native';
|
||||
import {createStackNavigator} from '@react-navigation/stack';
|
||||
import DrawerNavigator from './src/navigation/DrawerNavigator';
|
||||
import {initExpoToken} from "./src/utils/Notifications";
|
||||
import {Provider as PaperProvider} from 'react-native-paper';
|
||||
|
@ -18,6 +17,11 @@ import Update from "./src/constants/Update";
|
|||
import ConnectionManager from "./src/managers/ConnectionManager";
|
||||
import URLHandler from "./src/utils/URLHandler";
|
||||
import {setSafeBounceHeight} from "react-navigation-collapsible";
|
||||
import {enableScreens} from 'react-native-screens';
|
||||
|
||||
// Native optimizations https://reactnavigation.org/docs/react-native-screens
|
||||
enableScreens();
|
||||
|
||||
|
||||
YellowBox.ignoreWarnings([ // collapsible headers cause this warning, just ignore as it is not an issue
|
||||
'Non-serializable values were found in the navigation state',
|
||||
|
@ -33,8 +37,6 @@ type State = {
|
|||
currentTheme: CustomTheme | null,
|
||||
};
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
export default class App extends React.Component<Props, State> {
|
||||
|
||||
state = {
|
||||
|
@ -190,9 +192,10 @@ export default class App extends React.Component<Props, State> {
|
|||
return (
|
||||
<PaperProvider theme={this.state.currentTheme}>
|
||||
<NavigationContainer theme={this.state.currentTheme} ref={this.navigatorRef}>
|
||||
<Stack.Navigator headerMode="none">
|
||||
<Stack.Screen name="Root" component={this.createDrawerNavigator}/>
|
||||
</Stack.Navigator>
|
||||
<DrawerNavigator
|
||||
defaultHomeRoute={this.defaultHomeRoute}
|
||||
defaultHomeData={this.defaultHomeData}
|
||||
/>
|
||||
</NavigationContainer>
|
||||
</PaperProvider>
|
||||
);
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import * as Animatable from "react-native-animatable";
|
||||
import {CommonActions} from "@react-navigation/native";
|
||||
import {StackNavigationProp} from "@react-navigation/stack";
|
||||
|
||||
type Props = {
|
||||
navigation: StackNavigationProp,
|
||||
route: { params?: any, ... },
|
||||
children: React.Node
|
||||
}
|
||||
|
||||
export default class AnimatedFocusView extends React.Component<Props> {
|
||||
|
||||
ref: { current: null | Animatable.View };
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.ref = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.navigation.addListener('focus', this.onScreenFocus);
|
||||
}
|
||||
|
||||
onScreenFocus = () => {
|
||||
if (this.props.route.params != null) {
|
||||
if (this.props.route.params.animationDir && this.ref.current) {
|
||||
if (this.props.route.params.animationDir === "right")
|
||||
this.ref.current.fadeInRight(300);
|
||||
else
|
||||
this.ref.current.fadeInLeft(300);
|
||||
// reset params to prevent infinite loop
|
||||
this.props.navigation.dispatch(CommonActions.setParams({animationDir: null}));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Animatable.View
|
||||
ref={this.ref}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
useNativeDriver
|
||||
>
|
||||
{this.props.children}
|
||||
</Animatable.View>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,18 +7,19 @@ import {TouchableRipple} from "react-native-paper";
|
|||
import ConnectionManager from "../../managers/ConnectionManager";
|
||||
import LogoutDialog from "../Amicale/LogoutDialog";
|
||||
import SideBarSection from "./SideBarSection";
|
||||
import {DrawerNavigationProp} from "@react-navigation/drawer";
|
||||
|
||||
const deviceWidth = Dimensions.get("window").width;
|
||||
|
||||
type Props = {
|
||||
navigation: Object,
|
||||
navigation: DrawerNavigationProp,
|
||||
state: {[key: string] : any},
|
||||
theme?: Object,
|
||||
};
|
||||
|
||||
type State = {
|
||||
isLoggedIn: boolean,
|
||||
dialogVisible: boolean,
|
||||
activeRoute: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -27,7 +28,7 @@ type State = {
|
|||
class SideBar extends React.Component<Props, State> {
|
||||
|
||||
dataSet: Array<Object>;
|
||||
|
||||
activeRoute: string;
|
||||
/**
|
||||
* Generate the dataset
|
||||
*
|
||||
|
@ -35,6 +36,7 @@ class SideBar extends React.Component<Props, State> {
|
|||
*/
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.activeRoute = 'main';
|
||||
// Dataset used to render the drawer
|
||||
const mainData = [
|
||||
{
|
||||
|
@ -179,27 +181,23 @@ class SideBar extends React.Component<Props, State> {
|
|||
},
|
||||
];
|
||||
ConnectionManager.getInstance().addLoginStateListener(this.onLoginStateChange);
|
||||
this.props.navigation.addListener('state', this.onRouteChange);
|
||||
this.state = {
|
||||
isLoggedIn: ConnectionManager.getInstance().isLoggedIn(),
|
||||
dialogVisible: false,
|
||||
activeRoute: 'Main',
|
||||
};
|
||||
}
|
||||
|
||||
onRouteChange = (event: Object) => {
|
||||
try {
|
||||
const state = event.data.state.routes[0].state; // Get the Drawer's state if it exists
|
||||
// Get the current route name. This will only show Drawer routes.
|
||||
// Tabbar routes will be shown as 'Main'
|
||||
const routeName = state.routeNames[state.index];
|
||||
if (this.state.activeRoute !== routeName)
|
||||
this.setState({activeRoute: routeName});
|
||||
} catch (e) {
|
||||
this.setState({activeRoute: 'Main'});
|
||||
}
|
||||
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
|
||||
const nextNavigationState = nextProps.state;
|
||||
const nextRoute = nextNavigationState.routes[nextNavigationState.index].name;
|
||||
|
||||
};
|
||||
const currentNavigationState = this.props.state;
|
||||
const currentRoute = currentNavigationState.routes[currentNavigationState.index].name;
|
||||
|
||||
this.activeRoute = nextRoute;
|
||||
return (nextState !== this.state)
|
||||
|| (nextRoute !== currentRoute);
|
||||
}
|
||||
|
||||
showDisconnectDialog = () => this.setState({dialogVisible: true});
|
||||
|
||||
|
@ -217,7 +215,7 @@ class SideBar extends React.Component<Props, State> {
|
|||
return <SideBarSection
|
||||
{...this.props}
|
||||
listKey={item.key}
|
||||
activeRoute={this.state.activeRoute}
|
||||
activeRoute={this.activeRoute}
|
||||
isLoggedIn={this.state.isLoggedIn}
|
||||
sectionName={item.name}
|
||||
startOpen={item.startOpen}
|
||||
|
@ -239,7 +237,7 @@ class SideBar extends React.Component<Props, State> {
|
|||
{/*$FlowFixMe*/}
|
||||
<FlatList
|
||||
data={this.dataSet}
|
||||
extraData={this.state.isLoggedIn.toString() + this.state.activeRoute}
|
||||
extraData={this.state.isLoggedIn.toString() + this.activeRoute}
|
||||
renderItem={this.getRenderItem}
|
||||
/>
|
||||
<LogoutDialog
|
||||
|
|
|
@ -61,10 +61,7 @@ class CustomTabBar extends React.Component<Props, State> {
|
|||
});
|
||||
if (currentIndex !== destIndex && !event.defaultPrevented) {
|
||||
this.state.translateY = new Animated.Value(0);
|
||||
this.props.navigation.navigate(route.name, {
|
||||
screen: 'index',
|
||||
params: {animationDir: currentIndex < destIndex ? "right" : "left"}
|
||||
});
|
||||
this.props.navigation.navigate(route.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -541,7 +541,10 @@ export default class DrawerNavigator extends React.Component<Props> {
|
|||
this.createTabNavigator = () => <TabNavigator {...props}/>
|
||||
}
|
||||
|
||||
getDrawerContent = (props: { navigation: DrawerNavigationProp }) => <Sidebar {...props}/>
|
||||
getDrawerContent = (props: {
|
||||
navigation: DrawerNavigationProp,
|
||||
state: {[key: string] : any}
|
||||
}) => <Sidebar {...props}/>
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
|
|
@ -15,9 +15,9 @@ import ConnectionManager from "../../managers/ConnectionManager";
|
|||
import {CommonActions} from '@react-navigation/native';
|
||||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
||||
import AnimatedFAB from "../../components/Animations/AnimatedFAB";
|
||||
import AnimatedFocusView from "../../components/Animations/AnimatedFocusView";
|
||||
import {StackNavigationProp} from "@react-navigation/stack";
|
||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||
import {View} from "react-native-animatable";
|
||||
// import DATA from "../dashboard_data.json";
|
||||
|
||||
|
||||
|
@ -166,17 +166,11 @@ class HomeScreen extends React.Component<Props> {
|
|||
};
|
||||
|
||||
onProxiwashClick = () => {
|
||||
this.props.navigation.navigate("proxiwash", {
|
||||
screen: 'index',
|
||||
params: {animationDir: "right"} // Play tab animation
|
||||
});
|
||||
this.props.navigation.navigate("proxiwash");
|
||||
};
|
||||
|
||||
onProximoClick = () => {
|
||||
this.props.navigation.navigate("proximo", {
|
||||
screen: 'index',
|
||||
params: {animationDir: "left"} // Play tab animation
|
||||
});
|
||||
this.props.navigation.navigate("proximo");
|
||||
};
|
||||
|
||||
onTutorInsaClick = () => this.props.navigation.navigate('tutorinsa');
|
||||
|
@ -513,8 +507,8 @@ class HomeScreen extends React.Component<Props> {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<AnimatedFocusView
|
||||
{...this.props}
|
||||
<View
|
||||
style={{flex: 1}}
|
||||
>
|
||||
<WebSectionList
|
||||
{...this.props}
|
||||
|
@ -532,7 +526,7 @@ class HomeScreen extends React.Component<Props> {
|
|||
icon="qrcode-scan"
|
||||
onPress={this.openScanner}
|
||||
/>
|
||||
</AnimatedFocusView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import DateManager from "../../managers/DateManager";
|
|||
import AnimatedBottomBar from "../../components/Animations/AnimatedBottomBar";
|
||||
import {CommonActions} from "@react-navigation/native";
|
||||
import ErrorView from "../../components/Screens/ErrorView";
|
||||
import AnimatedFocusView from "../../components/Animations/AnimatedFocusView";
|
||||
|
||||
type Props = {
|
||||
navigation: Object,
|
||||
|
@ -300,8 +299,8 @@ class PlanexScreen extends React.Component<Props, State> {
|
|||
render() {
|
||||
const {containerPaddingTop} = this.props.collapsibleStack;
|
||||
return (
|
||||
<AnimatedFocusView
|
||||
{...this.props}
|
||||
<View
|
||||
style={{flex: 1}}
|
||||
>
|
||||
<Banner
|
||||
style={{
|
||||
|
@ -340,7 +339,7 @@ class PlanexScreen extends React.Component<Props, State> {
|
|||
onPress={this.sendMessage}
|
||||
seekAttention={this.state.currentGroup.id === -1}
|
||||
/>
|
||||
</AnimatedFocusView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import {
|
|||
} from '../../utils/Planning';
|
||||
import {Avatar, Divider, List} from 'react-native-paper';
|
||||
import CustomAgenda from "../../components/Overrides/CustomAgenda";
|
||||
import AnimatedFocusView from "../../components/Animations/AnimatedFocusView";
|
||||
|
||||
LocaleConfig.locales['fr'] = {
|
||||
monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
|
||||
|
@ -231,38 +230,34 @@ class PlanningScreen extends React.Component<Props, State> {
|
|||
render() {
|
||||
// console.log("rendering PlanningScreen");
|
||||
return (
|
||||
<AnimatedFocusView
|
||||
<CustomAgenda
|
||||
{...this.props}
|
||||
>
|
||||
<CustomAgenda
|
||||
{...this.props}
|
||||
// the list of items that have to be displayed in agenda. If you want to render item as empty date
|
||||
// the value of date key kas to be an empty array []. If there exists no value for date key it is
|
||||
// considered that the date in question is not yet loaded
|
||||
items={this.state.agendaItems}
|
||||
// initially selected day
|
||||
selected={this.currentDate}
|
||||
// Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
|
||||
minDate={this.currentDate}
|
||||
// Max amount of months allowed to scroll to the past. Default = 50
|
||||
pastScrollRange={1}
|
||||
// Max amount of months allowed to scroll to the future. Default = 50
|
||||
futureScrollRange={AGENDA_MONTH_SPAN}
|
||||
// If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly.
|
||||
onRefresh={this.onRefresh}
|
||||
// callback that fires when the calendar is opened or closed
|
||||
onCalendarToggled={this.onCalendarToggled}
|
||||
// Set this true while waiting for new data from a refresh
|
||||
refreshing={this.state.refreshing}
|
||||
renderItem={this.getRenderItem}
|
||||
renderEmptyDate={this.getRenderEmptyDate}
|
||||
rowHasChanged={this.rowHasChanged}
|
||||
// If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
|
||||
firstDay={1}
|
||||
// ref to this agenda in order to handle back button event
|
||||
onRef={this.onAgendaRef}
|
||||
/>
|
||||
</AnimatedFocusView>
|
||||
// the list of items that have to be displayed in agenda. If you want to render item as empty date
|
||||
// the value of date key kas to be an empty array []. If there exists no value for date key it is
|
||||
// considered that the date in question is not yet loaded
|
||||
items={this.state.agendaItems}
|
||||
// initially selected day
|
||||
selected={this.currentDate}
|
||||
// Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
|
||||
minDate={this.currentDate}
|
||||
// Max amount of months allowed to scroll to the past. Default = 50
|
||||
pastScrollRange={1}
|
||||
// Max amount of months allowed to scroll to the future. Default = 50
|
||||
futureScrollRange={AGENDA_MONTH_SPAN}
|
||||
// If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly.
|
||||
onRefresh={this.onRefresh}
|
||||
// callback that fires when the calendar is opened or closed
|
||||
onCalendarToggled={this.onCalendarToggled}
|
||||
// Set this true while waiting for new data from a refresh
|
||||
refreshing={this.state.refreshing}
|
||||
renderItem={this.getRenderItem}
|
||||
renderEmptyDate={this.getRenderEmptyDate}
|
||||
rowHasChanged={this.rowHasChanged}
|
||||
// If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
|
||||
firstDay={1}
|
||||
// ref to this agenda in order to handle back button event
|
||||
onRef={this.onAgendaRef}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import i18n from "i18n-js";
|
|||
import WebSectionList from "../../components/Screens/WebSectionList";
|
||||
import {List, withTheme} from 'react-native-paper';
|
||||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
||||
import AnimatedFocusView from "../../components/Animations/AnimatedFocusView";
|
||||
|
||||
const DATA_URL = "https://etud.insa-toulouse.fr/~proximo/data/stock-v2.json";
|
||||
const LIST_ITEM_HEIGHT = 84;
|
||||
|
@ -234,17 +233,13 @@ class ProximoMainScreen extends React.Component<Props, State> {
|
|||
render() {
|
||||
const nav = this.props.navigation;
|
||||
return (
|
||||
<AnimatedFocusView
|
||||
{...this.props}
|
||||
>
|
||||
<WebSectionList
|
||||
createDataset={this.createDataset}
|
||||
navigation={nav}
|
||||
autoRefreshTime={0}
|
||||
refreshOnFocus={false}
|
||||
fetchUrl={DATA_URL}
|
||||
renderItem={this.getRenderItem}/>
|
||||
</AnimatedFocusView>
|
||||
<WebSectionList
|
||||
createDataset={this.createDataset}
|
||||
navigation={nav}
|
||||
autoRefreshTime={0}
|
||||
refreshOnFocus={false}
|
||||
fetchUrl={DATA_URL}
|
||||
renderItem={this.getRenderItem}/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import AprilFoolsManager from "../../managers/AprilFoolsManager";
|
|||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
||||
import ProxiwashSectionHeader from "../../components/Lists/Proxiwash/ProxiwashSectionHeader";
|
||||
import {withCollapsible} from "../../utils/withCollapsible";
|
||||
import AnimatedFocusView from "../../components/Animations/AnimatedFocusView";
|
||||
|
||||
const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/washinsa/washinsa.json";
|
||||
|
||||
|
@ -422,13 +421,13 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
const nav = this.props.navigation;
|
||||
const {containerPaddingTop} = this.props.collapsibleStack;
|
||||
return (
|
||||
<AnimatedFocusView
|
||||
{...this.props}
|
||||
<View
|
||||
style={{flex: 1}}
|
||||
>
|
||||
<Banner
|
||||
style={{
|
||||
marginTop: this.state.bannerVisible ? containerPaddingTop : 0,
|
||||
}}
|
||||
marginTop: this.state.bannerVisible ? containerPaddingTop : 0,
|
||||
}}
|
||||
visible={this.state.bannerVisible}
|
||||
actions={[
|
||||
{
|
||||
|
@ -455,7 +454,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
autoRefreshTime={REFRESH_TIME}
|
||||
refreshOnFocus={true}
|
||||
updateData={this.state.machinesWatched.length}/>
|
||||
</AnimatedFocusView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue