[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
This commit is contained in:
Diego Mello 2018-11-27 17:40:53 -02:00 committed by GitHub
parent 35fac39594
commit e66dbd8ca3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 72 additions and 20 deletions

View File

@ -192,7 +192,6 @@ const RocketChat = {
SDK.driver.on('connected', () => { SDK.driver.on('connected', () => {
reduxStore.dispatch(connectSuccess()); reduxStore.dispatch(connectSuccess());
SDK.driver.subscribe('meteor.loginServiceConfiguration');
SDK.driver.subscribe('activeUsers'); SDK.driver.subscribe('activeUsers');
SDK.driver.subscribe('roles'); SDK.driver.subscribe('roles');
RocketChat.getSettings(); RocketChat.getSettings();

View File

@ -105,14 +105,12 @@ const handleForgotPasswordRequest = function* handleForgotPasswordRequest({ emai
const handleSetUser = function* handleSetUser() { const handleSetUser = function* handleSetUser() {
yield delay(2000); yield delay(2000);
const [server, user] = yield all([select(getServer), select(getUser)]); const [server, user] = yield all([select(getServer), select(getUser)]);
if (user) { if (user && user.id) {
// TODO: temporary... remove in future releases
// delete user.user;
if (user.language) { if (user.language) {
I18n.locale = 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() { const root = function* root() {

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { import {
View, Text, Image, TouchableOpacity View, Text, Image, TouchableOpacity, BackHandler
} from 'react-native'; } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/MaterialIcons'; 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 { gestureHandlerRootHOC } from 'react-native-gesture-handler';
import { selectServerRequest, serverInitAdd, serverFinishAdd } from '../../actions/server'; import { selectServerRequest, serverInitAdd, serverFinishAdd } from '../../actions/server';
import { appStart as appStartAction } from '../../actions';
import I18n from '../../i18n'; import I18n from '../../i18n';
import openLink from '../../utils/openLink'; import openLink from '../../utils/openLink';
import Button from './Button'; import Button from './Button';
@ -28,7 +29,8 @@ let NewServerView = null;
}), dispatch => ({ }), dispatch => ({
initAdd: () => dispatch(serverInitAdd()), initAdd: () => dispatch(serverInitAdd()),
finishAdd: () => dispatch(serverFinishAdd()), finishAdd: () => dispatch(serverFinishAdd()),
selectServer: server => dispatch(selectServerRequest(server)) selectServer: server => dispatch(selectServerRequest(server)),
appStart: () => dispatch(appStartAction())
})) }))
/** @extends React.Component */ /** @extends React.Component */
export default class OnboardingView extends LoggedView { export default class OnboardingView extends LoggedView {
@ -49,11 +51,13 @@ export default class OnboardingView extends LoggedView {
selectServer: PropTypes.func.isRequired, selectServer: PropTypes.func.isRequired,
currentServer: PropTypes.string, currentServer: PropTypes.string,
initAdd: PropTypes.func, initAdd: PropTypes.func,
finishAdd: PropTypes.func finishAdd: PropTypes.func,
appStart: PropTypes.func
} }
constructor(props) { constructor(props) {
super('OnboardingView', props); super('OnboardingView', props);
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
} }
componentDidMount() { componentDidMount() {
@ -75,6 +79,13 @@ export default class OnboardingView extends LoggedView {
finishAdd(); finishAdd();
} }
EventEmitter.removeListener('NewServer', this.handleNewServerEvent); EventEmitter.removeListener('NewServer', this.handleNewServerEvent);
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
}
handleBackPress = () => {
const { appStart } = this.props;
appStart('background');
return false;
} }
close = () => { close = () => {

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
View, ScrollView, Keyboard, Dimensions View, ScrollView, Keyboard, Dimensions, BackHandler
} from 'react-native'; } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import Dialog from 'react-native-dialog'; import Dialog from 'react-native-dialog';
@ -28,6 +28,7 @@ import Avatar from '../../containers/Avatar';
import Touch from '../../utils/touch'; import Touch from '../../utils/touch';
import Drawer from '../../Drawer'; import Drawer from '../../Drawer';
import { DEFAULT_HEADER } from '../../constants/headerOptions'; import { DEFAULT_HEADER } from '../../constants/headerOptions';
import { appStart as appStartAction } from '../../actions';
@connect(state => ({ @connect(state => ({
user: { user: {
@ -38,6 +39,8 @@ import { DEFAULT_HEADER } from '../../constants/headerOptions';
}, },
Accounts_CustomFields: state.settings.Accounts_CustomFields, Accounts_CustomFields: state.settings.Accounts_CustomFields,
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '' baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
}), dispatch => ({
appStart: () => dispatch(appStartAction())
})) }))
/** @extends React.Component */ /** @extends React.Component */
export default class ProfileView extends LoggedView { export default class ProfileView extends LoggedView {
@ -71,7 +74,8 @@ export default class ProfileView extends LoggedView {
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
componentId: PropTypes.string, componentId: PropTypes.string,
user: PropTypes.object, user: PropTypes.object,
Accounts_CustomFields: PropTypes.string Accounts_CustomFields: PropTypes.string,
appStart: PropTypes.func
} }
constructor(props) { constructor(props) {
@ -90,6 +94,7 @@ export default class ProfileView extends LoggedView {
customFields: {} customFields: {}
}; };
Navigation.events().bindComponent(this); Navigation.events().bindComponent(this);
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
} }
async componentDidMount() { async componentDidMount() {
@ -110,12 +115,22 @@ export default class ProfileView extends LoggedView {
} }
} }
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
}
navigationButtonPressed = ({ buttonId }) => { navigationButtonPressed = ({ buttonId }) => {
if (buttonId === 'settings') { if (buttonId === 'settings') {
Drawer.toggle(); Drawer.toggle();
} }
} }
handleBackPress = () => {
const { appStart } = this.props;
appStart('background');
return false;
}
setAvatar = (avatar) => { setAvatar = (avatar) => {
this.setState({ avatar }); this.setState({ avatar });
} }

View File

@ -22,6 +22,7 @@ import SortDropdown from './SortDropdown';
import ServerDropdown from './ServerDropdown'; import ServerDropdown from './ServerDropdown';
import Touch from '../../utils/touch'; import Touch from '../../utils/touch';
import { toggleSortDropdown as toggleSortDropdownAction, openSearchHeader as openSearchHeaderAction, closeSearchHeader as closeSearchHeaderAction } from '../../actions/rooms'; 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 store from '../../lib/createStore';
import Drawer from '../../Drawer'; import Drawer from '../../Drawer';
import { DEFAULT_HEADER } from '../../constants/headerOptions'; import { DEFAULT_HEADER } from '../../constants/headerOptions';
@ -69,7 +70,8 @@ let NewMessageView = null;
}), dispatch => ({ }), dispatch => ({
toggleSortDropdown: () => dispatch(toggleSortDropdownAction()), toggleSortDropdown: () => dispatch(toggleSortDropdownAction()),
openSearchHeader: () => dispatch(openSearchHeaderAction()), openSearchHeader: () => dispatch(openSearchHeaderAction()),
closeSearchHeader: () => dispatch(closeSearchHeaderAction()) closeSearchHeader: () => dispatch(closeSearchHeaderAction()),
appStart: () => dispatch(appStartAction())
})) }))
/** @extends React.Component */ /** @extends React.Component */
export default class RoomsListView extends LoggedView { export default class RoomsListView extends LoggedView {
@ -114,7 +116,8 @@ export default class RoomsListView extends LoggedView {
useRealName: PropTypes.bool, useRealName: PropTypes.bool,
toggleSortDropdown: PropTypes.func, toggleSortDropdown: PropTypes.func,
openSearchHeader: PropTypes.func, openSearchHeader: PropTypes.func,
closeSearchHeader: PropTypes.func closeSearchHeader: PropTypes.func,
appStart: PropTypes.func
} }
constructor(props) { constructor(props) {
@ -122,6 +125,7 @@ export default class RoomsListView extends LoggedView {
this.data = []; this.data = [];
this.state = { this.state = {
searching: false,
search: [], search: [],
loading: true, loading: true,
chats: [], chats: [],
@ -133,6 +137,7 @@ export default class RoomsListView extends LoggedView {
livechat: [] livechat: []
}; };
Navigation.events().bindComponent(this); Navigation.events().bindComponent(this);
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
} }
componentDidMount() { componentDidMount() {
@ -180,6 +185,7 @@ export default class RoomsListView extends LoggedView {
this.removeListener(this.privateGroup); this.removeListener(this.privateGroup);
this.removeListener(this.direct); this.removeListener(this.direct);
this.removeListener(this.livechat); this.removeListener(this.livechat);
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
if (this.timeout) { if (this.timeout) {
clearTimeout(this.timeout); clearTimeout(this.timeout);
@ -336,6 +342,7 @@ export default class RoomsListView extends LoggedView {
initSearchingAndroid = () => { initSearchingAndroid = () => {
const { openSearchHeader } = this.props; const { openSearchHeader } = this.props;
this.setState({ searching: true });
openSearchHeader(); openSearchHeader();
Navigation.mergeOptions('RoomsListView', { Navigation.mergeOptions('RoomsListView', {
topBar: { topBar: {
@ -347,12 +354,12 @@ export default class RoomsListView extends LoggedView {
rightButtons: [] rightButtons: []
} }
}); });
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
} }
cancelSearchingAndroid = () => { cancelSearchingAndroid = () => {
if (Platform.OS === 'android') { if (Platform.OS === 'android') {
const { closeSearchHeader } = this.props; const { closeSearchHeader } = this.props;
this.setState({ searching: false });
closeSearchHeader(); closeSearchHeader();
Navigation.mergeOptions('RoomsListView', { Navigation.mergeOptions('RoomsListView', {
topBar: { topBar: {
@ -362,7 +369,6 @@ export default class RoomsListView extends LoggedView {
}); });
this.internalSetState({ search: [] }); this.internalSetState({ search: [] });
Keyboard.dismiss(); Keyboard.dismiss();
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
} }
} }
@ -370,8 +376,14 @@ export default class RoomsListView extends LoggedView {
hasActiveDB = () => database && database.databases && database.databases.activeDB; hasActiveDB = () => database && database.databases && database.databases.activeDB;
handleBackPress = () => { handleBackPress = () => {
this.cancelSearchingAndroid(); const { searching } = this.state;
return true; const { appStart } = this.props;
if (searching) {
this.cancelSearchingAndroid();
return true;
}
appStart('background');
return false;
} }
_isUnread = item => item.unread > 0 || item.alert _isUnread = item => item.unread > 0 || item.alert

View File

@ -1,6 +1,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; 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 RNPickerSelect from 'react-native-picker-select';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Navigation } from 'react-native-navigation'; import { Navigation } from 'react-native-navigation';
@ -18,13 +20,15 @@ import Loading from '../../containers/Loading';
import { showErrorAlert, showToast } from '../../utils/info'; import { showErrorAlert, showToast } from '../../utils/info';
import log from '../../utils/log'; import log from '../../utils/log';
import { setUser as setUserAction } from '../../actions/login'; import { setUser as setUserAction } from '../../actions/login';
import { appStart as appStartAction } from '../../actions';
import Drawer from '../../Drawer'; import Drawer from '../../Drawer';
import { DEFAULT_HEADER } from '../../constants/headerOptions'; import { DEFAULT_HEADER } from '../../constants/headerOptions';
@connect(state => ({ @connect(state => ({
userLanguage: state.login.user && state.login.user.language userLanguage: state.login.user && state.login.user.language
}), dispatch => ({ }), dispatch => ({
setUser: params => dispatch(setUserAction(params)) setUser: params => dispatch(setUserAction(params)),
appStart: () => dispatch(appStartAction())
})) }))
/** @extends React.Component */ /** @extends React.Component */
export default class SettingsView extends LoggedView { export default class SettingsView extends LoggedView {
@ -57,7 +61,8 @@ export default class SettingsView extends LoggedView {
static propTypes = { static propTypes = {
componentId: PropTypes.string, componentId: PropTypes.string,
userLanguage: PropTypes.string, userLanguage: PropTypes.string,
setUser: PropTypes.func setUser: PropTypes.func,
appStart: PropTypes.func
} }
constructor(props) { constructor(props) {
@ -81,6 +86,11 @@ export default class SettingsView extends LoggedView {
saving: false saving: false
}; };
Navigation.events().bindComponent(this); Navigation.events().bindComponent(this);
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
} }
navigationButtonPressed = ({ buttonId }) => { navigationButtonPressed = ({ buttonId }) => {
@ -89,6 +99,12 @@ export default class SettingsView extends LoggedView {
} }
} }
handleBackPress = () => {
const { appStart } = this.props;
appStart('background');
return false;
}
getLabel = (language) => { getLabel = (language) => {
const { languages } = this.state; const { languages } = this.state;
const l = languages.find(i => i.value === language); const l = languages.find(i => i.value === language);

3
package-lock.json generated
View File

@ -18454,7 +18454,8 @@
}, },
"react-native-scrollable-tab-view": { "react-native-scrollable-tab-view": {
"version": "0.10.0", "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": { "requires": {
"create-react-class": "^15.6.2", "create-react-class": "^15.6.2",
"prop-types": "^15.6.0", "prop-types": "^15.6.0",