From e66dbd8ca3cd24e58c59efebe231fac711e5da35 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 27 Nov 2018 17:40:53 -0200 Subject: [PATCH] [FIX] Android stuck on splash screen after hardware back button is pressed (#550) * [FIX] Android stuck on splash screen after hardware button is pressed * Fix empty user at asyncstorage * Remove unused subscribe --- app/lib/rocketchat.js | 1 - app/sagas/login.js | 6 ++---- app/views/OnboardingView/index.js | 17 ++++++++++++++--- app/views/ProfileView/index.js | 19 +++++++++++++++++-- app/views/RoomsListView/index.js | 24 ++++++++++++++++++------ app/views/SettingsView/index.js | 22 +++++++++++++++++++--- package-lock.json | 3 ++- 7 files changed, 72 insertions(+), 20 deletions(-) diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index a03230199..ea98fe248 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -192,7 +192,6 @@ const RocketChat = { SDK.driver.on('connected', () => { reduxStore.dispatch(connectSuccess()); - SDK.driver.subscribe('meteor.loginServiceConfiguration'); SDK.driver.subscribe('activeUsers'); SDK.driver.subscribe('roles'); RocketChat.getSettings(); diff --git a/app/sagas/login.js b/app/sagas/login.js index b5981cf3b..480482643 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -105,14 +105,12 @@ const handleForgotPasswordRequest = function* handleForgotPasswordRequest({ emai const handleSetUser = function* handleSetUser() { yield delay(2000); const [server, user] = yield all([select(getServer), select(getUser)]); - if (user) { - // TODO: temporary... remove in future releases - // delete user.user; + if (user && user.id) { if (user.language) { I18n.locale = user.language; } + yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user)); } - yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user)); }; const root = function* root() { diff --git a/app/views/OnboardingView/index.js b/app/views/OnboardingView/index.js index e74938b89..63eab53d4 100644 --- a/app/views/OnboardingView/index.js +++ b/app/views/OnboardingView/index.js @@ -1,6 +1,6 @@ import React from 'react'; import { - View, Text, Image, TouchableOpacity + View, Text, Image, TouchableOpacity, BackHandler } from 'react-native'; import PropTypes from 'prop-types'; import Icon from 'react-native-vector-icons/MaterialIcons'; @@ -10,6 +10,7 @@ import SafeAreaView from 'react-native-safe-area-view'; import { gestureHandlerRootHOC } from 'react-native-gesture-handler'; import { selectServerRequest, serverInitAdd, serverFinishAdd } from '../../actions/server'; +import { appStart as appStartAction } from '../../actions'; import I18n from '../../i18n'; import openLink from '../../utils/openLink'; import Button from './Button'; @@ -28,7 +29,8 @@ let NewServerView = null; }), dispatch => ({ initAdd: () => dispatch(serverInitAdd()), finishAdd: () => dispatch(serverFinishAdd()), - selectServer: server => dispatch(selectServerRequest(server)) + selectServer: server => dispatch(selectServerRequest(server)), + appStart: () => dispatch(appStartAction()) })) /** @extends React.Component */ export default class OnboardingView extends LoggedView { @@ -49,11 +51,13 @@ export default class OnboardingView extends LoggedView { selectServer: PropTypes.func.isRequired, currentServer: PropTypes.string, initAdd: PropTypes.func, - finishAdd: PropTypes.func + finishAdd: PropTypes.func, + appStart: PropTypes.func } constructor(props) { super('OnboardingView', props); + BackHandler.addEventListener('hardwareBackPress', this.handleBackPress); } componentDidMount() { @@ -75,6 +79,13 @@ export default class OnboardingView extends LoggedView { finishAdd(); } EventEmitter.removeListener('NewServer', this.handleNewServerEvent); + BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress); + } + + handleBackPress = () => { + const { appStart } = this.props; + appStart('background'); + return false; } close = () => { diff --git a/app/views/ProfileView/index.js b/app/views/ProfileView/index.js index e3ee4edd1..c688327d0 100644 --- a/app/views/ProfileView/index.js +++ b/app/views/ProfileView/index.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { - View, ScrollView, Keyboard, Dimensions + View, ScrollView, Keyboard, Dimensions, BackHandler } from 'react-native'; import { connect } from 'react-redux'; import Dialog from 'react-native-dialog'; @@ -28,6 +28,7 @@ import Avatar from '../../containers/Avatar'; import Touch from '../../utils/touch'; import Drawer from '../../Drawer'; import { DEFAULT_HEADER } from '../../constants/headerOptions'; +import { appStart as appStartAction } from '../../actions'; @connect(state => ({ user: { @@ -38,6 +39,8 @@ import { DEFAULT_HEADER } from '../../constants/headerOptions'; }, Accounts_CustomFields: state.settings.Accounts_CustomFields, baseUrl: state.settings.Site_Url || state.server ? state.server.server : '' +}), dispatch => ({ + appStart: () => dispatch(appStartAction()) })) /** @extends React.Component */ export default class ProfileView extends LoggedView { @@ -71,7 +74,8 @@ export default class ProfileView extends LoggedView { baseUrl: PropTypes.string, componentId: PropTypes.string, user: PropTypes.object, - Accounts_CustomFields: PropTypes.string + Accounts_CustomFields: PropTypes.string, + appStart: PropTypes.func } constructor(props) { @@ -90,6 +94,7 @@ export default class ProfileView extends LoggedView { customFields: {} }; Navigation.events().bindComponent(this); + BackHandler.addEventListener('hardwareBackPress', this.handleBackPress); } async componentDidMount() { @@ -110,12 +115,22 @@ export default class ProfileView extends LoggedView { } } + componentWillUnmount() { + BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress); + } + navigationButtonPressed = ({ buttonId }) => { if (buttonId === 'settings') { Drawer.toggle(); } } + handleBackPress = () => { + const { appStart } = this.props; + appStart('background'); + return false; + } + setAvatar = (avatar) => { this.setState({ avatar }); } diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index 9a5e44e85..ee77977c4 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -22,6 +22,7 @@ import SortDropdown from './SortDropdown'; import ServerDropdown from './ServerDropdown'; import Touch from '../../utils/touch'; import { toggleSortDropdown as toggleSortDropdownAction, openSearchHeader as openSearchHeaderAction, closeSearchHeader as closeSearchHeaderAction } from '../../actions/rooms'; +import { appStart as appStartAction } from '../../actions'; import store from '../../lib/createStore'; import Drawer from '../../Drawer'; import { DEFAULT_HEADER } from '../../constants/headerOptions'; @@ -69,7 +70,8 @@ let NewMessageView = null; }), dispatch => ({ toggleSortDropdown: () => dispatch(toggleSortDropdownAction()), openSearchHeader: () => dispatch(openSearchHeaderAction()), - closeSearchHeader: () => dispatch(closeSearchHeaderAction()) + closeSearchHeader: () => dispatch(closeSearchHeaderAction()), + appStart: () => dispatch(appStartAction()) })) /** @extends React.Component */ export default class RoomsListView extends LoggedView { @@ -114,7 +116,8 @@ export default class RoomsListView extends LoggedView { useRealName: PropTypes.bool, toggleSortDropdown: PropTypes.func, openSearchHeader: PropTypes.func, - closeSearchHeader: PropTypes.func + closeSearchHeader: PropTypes.func, + appStart: PropTypes.func } constructor(props) { @@ -122,6 +125,7 @@ export default class RoomsListView extends LoggedView { this.data = []; this.state = { + searching: false, search: [], loading: true, chats: [], @@ -133,6 +137,7 @@ export default class RoomsListView extends LoggedView { livechat: [] }; Navigation.events().bindComponent(this); + BackHandler.addEventListener('hardwareBackPress', this.handleBackPress); } componentDidMount() { @@ -180,6 +185,7 @@ export default class RoomsListView extends LoggedView { this.removeListener(this.privateGroup); this.removeListener(this.direct); this.removeListener(this.livechat); + BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress); if (this.timeout) { clearTimeout(this.timeout); @@ -336,6 +342,7 @@ export default class RoomsListView extends LoggedView { initSearchingAndroid = () => { const { openSearchHeader } = this.props; + this.setState({ searching: true }); openSearchHeader(); Navigation.mergeOptions('RoomsListView', { topBar: { @@ -347,12 +354,12 @@ export default class RoomsListView extends LoggedView { rightButtons: [] } }); - BackHandler.addEventListener('hardwareBackPress', this.handleBackPress); } cancelSearchingAndroid = () => { if (Platform.OS === 'android') { const { closeSearchHeader } = this.props; + this.setState({ searching: false }); closeSearchHeader(); Navigation.mergeOptions('RoomsListView', { topBar: { @@ -362,7 +369,6 @@ export default class RoomsListView extends LoggedView { }); this.internalSetState({ search: [] }); Keyboard.dismiss(); - BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress); } } @@ -370,8 +376,14 @@ export default class RoomsListView extends LoggedView { hasActiveDB = () => database && database.databases && database.databases.activeDB; handleBackPress = () => { - this.cancelSearchingAndroid(); - return true; + const { searching } = this.state; + const { appStart } = this.props; + if (searching) { + this.cancelSearchingAndroid(); + return true; + } + appStart('background'); + return false; } _isUnread = item => item.unread > 0 || item.alert diff --git a/app/views/SettingsView/index.js b/app/views/SettingsView/index.js index d6698e31b..10a29fb4b 100644 --- a/app/views/SettingsView/index.js +++ b/app/views/SettingsView/index.js @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { View, ScrollView, Dimensions } from 'react-native'; +import { + View, ScrollView, Dimensions, BackHandler +} from 'react-native'; import RNPickerSelect from 'react-native-picker-select'; import { connect } from 'react-redux'; import { Navigation } from 'react-native-navigation'; @@ -18,13 +20,15 @@ import Loading from '../../containers/Loading'; import { showErrorAlert, showToast } from '../../utils/info'; import log from '../../utils/log'; import { setUser as setUserAction } from '../../actions/login'; +import { appStart as appStartAction } from '../../actions'; import Drawer from '../../Drawer'; import { DEFAULT_HEADER } from '../../constants/headerOptions'; @connect(state => ({ userLanguage: state.login.user && state.login.user.language }), dispatch => ({ - setUser: params => dispatch(setUserAction(params)) + setUser: params => dispatch(setUserAction(params)), + appStart: () => dispatch(appStartAction()) })) /** @extends React.Component */ export default class SettingsView extends LoggedView { @@ -57,7 +61,8 @@ export default class SettingsView extends LoggedView { static propTypes = { componentId: PropTypes.string, userLanguage: PropTypes.string, - setUser: PropTypes.func + setUser: PropTypes.func, + appStart: PropTypes.func } constructor(props) { @@ -81,6 +86,11 @@ export default class SettingsView extends LoggedView { saving: false }; Navigation.events().bindComponent(this); + BackHandler.addEventListener('hardwareBackPress', this.handleBackPress); + } + + componentWillUnmount() { + BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress); } navigationButtonPressed = ({ buttonId }) => { @@ -89,6 +99,12 @@ export default class SettingsView extends LoggedView { } } + handleBackPress = () => { + const { appStart } = this.props; + appStart('background'); + return false; + } + getLabel = (language) => { const { languages } = this.state; const l = languages.find(i => i.value === language); diff --git a/package-lock.json b/package-lock.json index 0164c19d4..3c27dc22d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18454,7 +18454,8 @@ }, "react-native-scrollable-tab-view": { "version": "0.10.0", - "resolved": "git+https://github.com/skv-headless/react-native-scrollable-tab-view.git#2419c25a03f0fb346af8ce2c39fca869f259e716", + "resolved": "https://registry.npmjs.org/react-native-scrollable-tab-view/-/react-native-scrollable-tab-view-0.10.0.tgz", + "integrity": "sha512-7FWw9X2hLozWqpGJTAU/p7ONdTTO635bbAZ5AUPDrB4JwaLbhNV6ePjsNUjsCaopgCwz/EdmH0hTCPeja9dh4w==", "requires": { "create-react-class": "^15.6.2", "prop-types": "^15.6.0",