From 01e3195be7c16a8aedb648ab56d0bffc23f765f1 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Mon, 20 Apr 2020 19:27:23 +0200 Subject: [PATCH] Improved screen changing performances and removed tab screen animations --- App.js | 15 +++-- .../Animations/AnimatedFocusView.js | 55 ----------------- src/components/Sidebar/Sidebar.js | 36 ++++++----- src/components/Tabbar/CustomTabBar.js | 5 +- src/navigation/DrawerNavigator.js | 5 +- src/screens/Home/HomeScreen.js | 18 ++---- src/screens/Planex/PlanexScreen.js | 7 +-- src/screens/Planning/PlanningScreen.js | 59 +++++++++---------- src/screens/Proximo/ProximoMainScreen.js | 19 +++--- src/screens/Proxiwash/ProxiwashScreen.js | 11 ++-- 10 files changed, 79 insertions(+), 151 deletions(-) delete mode 100644 src/components/Animations/AnimatedFocusView.js diff --git a/App.js b/App.js index 930e35c..61ad740 100644 --- a/App.js +++ b/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 { state = { @@ -190,9 +192,10 @@ export default class App extends React.Component { return ( - - - + ); diff --git a/src/components/Animations/AnimatedFocusView.js b/src/components/Animations/AnimatedFocusView.js deleted file mode 100644 index 1ff8e45..0000000 --- a/src/components/Animations/AnimatedFocusView.js +++ /dev/null @@ -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 { - - 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 ( - - {this.props.children} - - ); - } -} diff --git a/src/components/Sidebar/Sidebar.js b/src/components/Sidebar/Sidebar.js index 44d9ea3..0d87ed6 100644 --- a/src/components/Sidebar/Sidebar.js +++ b/src/components/Sidebar/Sidebar.js @@ -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 { dataSet: Array; - + activeRoute: string; /** * Generate the dataset * @@ -35,6 +36,7 @@ class SideBar extends React.Component { */ 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 { }, ]; 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 { return { {/*$FlowFixMe*/} { }); 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); } } diff --git a/src/navigation/DrawerNavigator.js b/src/navigation/DrawerNavigator.js index ec784d5..6d11f98 100644 --- a/src/navigation/DrawerNavigator.js +++ b/src/navigation/DrawerNavigator.js @@ -541,7 +541,10 @@ export default class DrawerNavigator extends React.Component { this.createTabNavigator = () => } - getDrawerContent = (props: { navigation: DrawerNavigationProp }) => + getDrawerContent = (props: { + navigation: DrawerNavigationProp, + state: {[key: string] : any} + }) => render() { return ( diff --git a/src/screens/Home/HomeScreen.js b/src/screens/Home/HomeScreen.js index 18f86da..f1a75fc 100644 --- a/src/screens/Home/HomeScreen.js +++ b/src/screens/Home/HomeScreen.js @@ -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 { }; 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 { render() { return ( - { icon="qrcode-scan" onPress={this.openScanner} /> - + ); } } diff --git a/src/screens/Planex/PlanexScreen.js b/src/screens/Planex/PlanexScreen.js index a25de48..d7e157c 100644 --- a/src/screens/Planex/PlanexScreen.js +++ b/src/screens/Planex/PlanexScreen.js @@ -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 { render() { const {containerPaddingTop} = this.props.collapsibleStack; return ( - { onPress={this.sendMessage} seekAttention={this.state.currentGroup.id === -1} /> - + ); } } diff --git a/src/screens/Planning/PlanningScreen.js b/src/screens/Planning/PlanningScreen.js index 16bcfe1..4dddc91 100644 --- a/src/screens/Planning/PlanningScreen.js +++ b/src/screens/Planning/PlanningScreen.js @@ -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 { render() { // console.log("rendering PlanningScreen"); return ( - - - + // 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} + /> ); } } diff --git a/src/screens/Proximo/ProximoMainScreen.js b/src/screens/Proximo/ProximoMainScreen.js index ba683d8..7684a6a 100644 --- a/src/screens/Proximo/ProximoMainScreen.js +++ b/src/screens/Proximo/ProximoMainScreen.js @@ -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 { render() { const nav = this.props.navigation; return ( - - - + ); } } diff --git a/src/screens/Proxiwash/ProxiwashScreen.js b/src/screens/Proxiwash/ProxiwashScreen.js index 65efb2c..4a7f5ba 100644 --- a/src/screens/Proxiwash/ProxiwashScreen.js +++ b/src/screens/Proxiwash/ProxiwashScreen.js @@ -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 { const nav = this.props.navigation; const {containerPaddingTop} = this.props.collapsibleStack; return ( - { autoRefreshTime={REFRESH_TIME} refreshOnFocus={true} updateData={this.state.machinesWatched.length}/> - + ); } }