From 1f32d81bf0dd7f70cd3183dc12dc2710d8cae369 Mon Sep 17 00:00:00 2001 From: AlixH Date: Fri, 26 Nov 2021 15:00:50 +0100 Subject: [PATCH] Fixed Android back button behavior --- src/App.tsx | 1 - .../header/TransactionHeaderComponent.tsx | 3 +-- src/screens/auth/AuthHeader.tsx | 8 +------ src/screens/auth/login/Login.tsx | 7 +++--- src/screens/auth/sign-up/SignUp.tsx | 2 +- src/screens/base-screen/BaseScreen.tsx | 21 ++++++++---------- .../list/ChargingStations.tsx | 2 +- .../StripePaymentMethodCreationForm.tsx | 2 +- src/screens/sidebar/SideBar.tsx | 22 +++++++++++++++---- src/screens/site-areas/SiteAreas.tsx | 2 +- src/screens/sites/Sites.tsx | 2 +- 11 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 091bdc389..91a617b0f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -418,7 +418,6 @@ function createPaymentMethodsNavigator(props: BaseProps) { } function createAppDrawerNavigator(props: BaseProps) { - const appStyles = computeStyleSheet(); return ( { +export default class TransactionHeaderComponent extends React.Component { public state: State; public props: Props; diff --git a/src/screens/auth/AuthHeader.tsx b/src/screens/auth/AuthHeader.tsx index 7572e6cb6..7315209df 100644 --- a/src/screens/auth/AuthHeader.tsx +++ b/src/screens/auth/AuthHeader.tsx @@ -5,7 +5,6 @@ import { Image, ImageStyle } from 'react-native'; import DeviceInfo from 'react-native-device-info'; import BaseProps from '../../types/BaseProps'; -import BaseScreen from '../base-screen/BaseScreen'; import computeStyleSheet from './AuthStyles'; export interface Props extends BaseProps { @@ -15,15 +14,10 @@ export interface Props extends BaseProps { interface State {} -export default class AuthHeader extends BaseScreen { +export default class AuthHeader extends React.Component{ public state: State; public props: Props; - // eslint-disable-next-line no-useless-constructor - public constructor(props: Props) { - super(props); - } - public setState = ( state: State | ((prevState: Readonly, props: Readonly) => State | Pick) | Pick, callback?: () => void diff --git a/src/screens/auth/login/Login.tsx b/src/screens/auth/login/Login.tsx index 3671284d5..f8d7ce2e9 100644 --- a/src/screens/auth/login/Login.tsx +++ b/src/screens/auth/login/Login.tsx @@ -23,6 +23,7 @@ import Utils from '../../../utils/Utils'; import BaseScreen from '../../base-screen/BaseScreen'; import AuthHeader from '../AuthHeader'; import computeStyleSheet from '../AuthStyles'; +import BaseAutoRefreshScreen from '../../base-screen/BaseAutoRefreshScreen'; export interface Props extends BaseProps {} @@ -47,7 +48,7 @@ interface State { showNoTenantFoundDialog: boolean; } -export default class Login extends BaseScreen { +export default class Login extends BaseAutoRefreshScreen { public state: State; public props: Props; private tenants: TenantConnection[] = []; @@ -171,7 +172,7 @@ export default class Login extends BaseScreen { public async componentDidFocus() { super.componentDidFocus(); const tenantSubDomain = Utils.getParamFromNavigation(this.props.route, 'tenantSubDomain', this.state.tenantSubDomain); - // Check if current Tenant selection is still valid (handle delete tenant usee case) + // Check if current Tenant selection is still valid (handle delete tenant use case) if (tenantSubDomain) { // Get the current Tenant const tenant = await this.centralServerProvider.getTenant(tenantSubDomain.toString()); @@ -272,7 +273,7 @@ export default class Login extends BaseScreen { } }; - public onBack = (): boolean => { + public onBack(): boolean { BackHandler.exitApp(); return true; } diff --git a/src/screens/auth/sign-up/SignUp.tsx b/src/screens/auth/sign-up/SignUp.tsx index 0af690f4c..f193ef328 100644 --- a/src/screens/auth/sign-up/SignUp.tsx +++ b/src/screens/auth/sign-up/SignUp.tsx @@ -214,7 +214,7 @@ export default class SignUp extends BaseScreen { } }; - public onBack = (): boolean => { + public onBack(): boolean { // Back mobile button: Force navigation this.props.navigation.navigate('Login', { tenantSubDomain: this.state.tenantSubDomain diff --git a/src/screens/base-screen/BaseScreen.tsx b/src/screens/base-screen/BaseScreen.tsx index 58198e4c4..632fbf2a2 100644 --- a/src/screens/base-screen/BaseScreen.tsx +++ b/src/screens/base-screen/BaseScreen.tsx @@ -6,7 +6,7 @@ import CentralServerProvider from '../../provider/CentralServerProvider'; import ProviderFactory from '../../provider/ProviderFactory'; import SecurityProvider from '../../provider/SecurityProvider'; import BaseProps from '../../types/BaseProps'; -import { AppState, AppStateStatus, BackHandler, NativeEventSubscription } from 'react-native'; +import { AppStateStatus, BackHandler, NativeEventSubscription } from 'react-native'; export interface Props extends BaseProps {} @@ -21,7 +21,6 @@ export default class BaseScreen extends React.Component { private componentFocusUnsubscribe: () => void; private componentBlurUnsubscribe: () => void; backHandler: NativeEventSubscription; - appStateUnsubscribe: NativeEventSubscription; public constructor(props: Props) { super(props); @@ -33,15 +32,15 @@ export default class BaseScreen extends React.Component { } public async componentDidMount() { + const { navigation } = this.props; // Get providers this.centralServerProvider = await ProviderFactory.getProvider(); - this.securityProvider = this.centralServerProvider.getSecurityProvider(); + this.securityProvider = this.centralServerProvider?.getSecurityProvider(); // Add listeners - this.componentFocusUnsubscribe = this.props.navigation.addListener('focus', this.componentDidFocus.bind(this)); - this.componentBlurUnsubscribe = this.props.navigation.addListener('blur', this.componentDidBlur.bind(this)); + this.componentFocusUnsubscribe = navigation?.addListener('focus', () => this.componentDidFocus()); + this.componentBlurUnsubscribe = navigation?.addListener('blur', () => this.componentDidBlur()); // Bind the back button to the onBack method (Android) - this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.onBack.bind(this)); - this.appStateUnsubscribe = AppState.addEventListener('change', (nextAppState) => this.onAppStateChange(nextAppState)); + this.backHandler = BackHandler.addEventListener('hardwareBackPress', () => this.onBack()); // Ok this.mounted = true; } @@ -52,8 +51,6 @@ export default class BaseScreen extends React.Component { this.componentBlurUnsubscribe?.(); // Unbind the back button and reset its default behavior (Android) this.backHandler.remove(); - // Unsubscribe from App State change event. - this.appStateUnsubscribe?.remove(); } public setHeaderComponent(headerComponent: HeaderComponent) { @@ -67,8 +64,8 @@ export default class BaseScreen extends React.Component { } public onAppStateChange(nextAppState: AppStateStatus): void { - if(AppState.currentState.match(/inactive|background/) && nextAppState === 'active') { - this.componentDidFocus(); + if(nextAppState === 'active') { + this.componentDidFocus(); } } @@ -97,7 +94,7 @@ export default class BaseScreen extends React.Component { public componentDidFocus(): void { // Bind the back button to the onBack method (Android) - this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.onBack.bind(this)); + this.backHandler = BackHandler.addEventListener('hardwareBackPress', () => this.onBack()); } public componentDidBlur(): void { diff --git a/src/screens/charging-stations/list/ChargingStations.tsx b/src/screens/charging-stations/list/ChargingStations.tsx index f45ff00b2..7df41bdee 100644 --- a/src/screens/charging-stations/list/ChargingStations.tsx +++ b/src/screens/charging-stations/list/ChargingStations.tsx @@ -199,7 +199,7 @@ export default class ChargingStations extends BaseAutoRefreshScreen { + public onBack (): boolean { if (!this.state.showMap) { this.setState({ showMap: true }); return true; diff --git a/src/screens/payment-methods/stripe/StripePaymentMethodCreationForm.tsx b/src/screens/payment-methods/stripe/StripePaymentMethodCreationForm.tsx index ae7737ee4..70aba6213 100644 --- a/src/screens/payment-methods/stripe/StripePaymentMethodCreationForm.tsx +++ b/src/screens/payment-methods/stripe/StripePaymentMethodCreationForm.tsx @@ -1,7 +1,7 @@ import { CardField, CardFieldInput, initStripe, useConfirmSetupIntent } from '@stripe/stripe-react-native'; import I18n from 'i18n-js'; import { Button, CheckBox, Spinner, View } from 'native-base'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { BackHandler, Text, TouchableOpacity } from 'react-native'; import { scale } from 'react-native-size-matters'; import { useFocusEffect } from '@react-navigation/native'; diff --git a/src/screens/sidebar/SideBar.tsx b/src/screens/sidebar/SideBar.tsx index 2bdf22239..9071fa606 100644 --- a/src/screens/sidebar/SideBar.tsx +++ b/src/screens/sidebar/SideBar.tsx @@ -13,8 +13,10 @@ import BaseProps from '../../types/BaseProps'; import User from '../../types/User'; import UserToken from '../../types/UserToken'; import Utils from '../../utils/Utils'; -import BaseScreen from '../base-screen/BaseScreen'; import computeStyleSheet from './SideBarStyles'; +import CentralServerProvider from '../../provider/CentralServerProvider'; +import ProviderFactory from '../../provider/ProviderFactory'; +import SecurityProvider from '../../provider/SecurityProvider'; export interface Props extends BaseProps {} @@ -27,12 +29,18 @@ interface State { appVersion?: CheckVersionResponse; } -export default class SideBar extends BaseScreen { +export default class SideBar extends React.Component { public state: State; public props: Props; + private centralServerProvider: CentralServerProvider; + private securityProvider: SecurityProvider; + private componentFocusUnsubscribe: () => void; + private componentBlurUnsubscribe: () => void; public constructor(props: Props) { super(props); + this.componentFocusUnsubscribe = this.props.navigation?.addListener('focus', () => this.componentDidFocus()); + this.componentBlurUnsubscribe = this.props.navigation?.addListener('blur', () => this.componentDidFocus()); this.state = { userToken: null, tenantName: '', @@ -50,13 +58,19 @@ export default class SideBar extends BaseScreen { super.setState(state, callback); }; - public async componentDidMount() { - await super.componentDidMount(); + public async componentDidFocus(): Promise { + this.centralServerProvider = await ProviderFactory.getProvider(); + this.securityProvider = this.centralServerProvider?.getSecurityProvider(); await this.getUpdateDate(); // Init User (delay it) this.refresh(); } + public componentWillUnmount() { + this.componentFocusUnsubscribe?.(); + this.componentBlurUnsubscribe?.(); + } + public refresh = async () => { await this.getUserInfo(); const appVersion = await checkVersion(); diff --git a/src/screens/site-areas/SiteAreas.tsx b/src/screens/site-areas/SiteAreas.tsx index 67f763326..d63fbce64 100644 --- a/src/screens/site-areas/SiteAreas.tsx +++ b/src/screens/site-areas/SiteAreas.tsx @@ -146,7 +146,7 @@ export default class SiteAreas extends BaseAutoRefreshScreen { return null; }; - public onBack = () => { + public onBack () { // Back mobile button: Force navigation if (this.state.showMap) { this.setState({ showMap: false }); diff --git a/src/screens/sites/Sites.tsx b/src/screens/sites/Sites.tsx index 24e3e026a..efee6659b 100644 --- a/src/screens/sites/Sites.tsx +++ b/src/screens/sites/Sites.tsx @@ -147,7 +147,7 @@ export default class Sites extends BaseAutoRefreshScreen { return null; }; - public onBack = () => { + public onBack () { // Back mobile button: Force navigation if (this.state.showMap) { this.setState({ showMap: false });