From 55ebf4f5e40dae090fbc90ee57e45ef9bd262780 Mon Sep 17 00:00:00 2001 From: Miguel Alatzar Date: Thu, 27 Feb 2020 13:15:45 -0700 Subject: [PATCH] [MM-20950] Don't reset the navigation root when clearing data (#3929) * No need to resetToChannel on clearing data * Don't use componentWillReceiveProps * Dismiss all modals on iOS too * Use centerChannelBg when channel as root * Fix resetToChannel test * Fix removal of loadChannels call when rebasing with master * Add new line * Address PR review comments --- app/init/global_event_handler.js | 16 ++-- app/screens/channel/channel_base.js | 3 +- .../advanced_settings/advanced_settings.js | 4 +- app/store/store.js | 24 +----- app/store/utils.js | 35 +++++++- app/store/utils.test.js | 79 +++++++++++++++++++ 6 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 app/store/utils.test.js diff --git a/app/init/global_event_handler.js b/app/init/global_event_handler.js index 7ce8e9ad5..cdf99c78a 100644 --- a/app/init/global_event_handler.js +++ b/app/init/global_event_handler.js @@ -14,7 +14,7 @@ import {Client4} from 'mattermost-redux/client'; import {General} from 'mattermost-redux/constants'; import EventEmitter from 'mattermost-redux/utils/event_emitter'; import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels'; -import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; +import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users'; import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone'; import {setDeviceDimensions, setDeviceOrientation, setDeviceAsTablet, setStatusBarHeight} from 'app/actions/device'; @@ -203,8 +203,13 @@ class GlobalEventHandler { }; onRestartApp = async () => { - await this.store.dispatch(loadConfigAndLicense()); - await this.store.dispatch(loadMe()); + const {dispatch, getState} = this.store; + const state = getState(); + const {currentUserId} = state.entities.users; + const user = getUser(state, currentUserId); + + await dispatch(loadConfigAndLicense()); + await dispatch(loadMe(user)); const window = Dimensions.get('window'); this.onOrientationChange({window}); @@ -216,11 +221,6 @@ class GlobalEventHandler { }, ); } - - if (this.launchApp) { - const credentials = await getAppCredentials(); - this.launchApp(credentials); - } }; onServerVersionChanged = async (serverVersion) => { diff --git a/app/screens/channel/channel_base.js b/app/screens/channel/channel_base.js index 22016084d..09b8cf0fb 100644 --- a/app/screens/channel/channel_base.js +++ b/app/screens/channel/channel_base.js @@ -117,7 +117,8 @@ export default class ChannelBase extends PureComponent { }); } - if (this.props.currentTeamId && this.props.currentTeamId !== prevProps.currentTeamId) { + if (this.props.currentTeamId && + (!this.props.currentChannelId || this.props.currentTeamId !== prevProps.currentTeamId)) { this.loadChannels(this.props.currentTeamId); } diff --git a/app/screens/settings/advanced_settings/advanced_settings.js b/app/screens/settings/advanced_settings/advanced_settings.js index ee0f17420..c90c969c4 100644 --- a/app/screens/settings/advanced_settings/advanced_settings.js +++ b/app/screens/settings/advanced_settings/advanced_settings.js @@ -80,9 +80,7 @@ class AdvancedSettings extends Component { this.setState({cacheSize: 0, cacheSizedFetched: true}); actions.purgeOfflineStore(); - if (Platform.OS === 'android') { - dismissAllModals(); - } + dismissAllModals(); }); renderCacheFileSize = () => { diff --git a/app/store/store.js b/app/store/store.js index 2e245ab6e..386b012dc 100644 --- a/app/store/store.js +++ b/app/store/store.js @@ -6,7 +6,6 @@ import {Platform} from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import {createBlacklistFilter} from 'redux-persist-transform-filter'; import {createTransform, persistStore} from 'redux-persist'; -import merge from 'deepmerge'; import {ErrorTypes, GeneralTypes} from 'mattermost-redux/action_types'; import {General} from 'mattermost-redux/constants'; @@ -24,7 +23,7 @@ import mattermostBucket from 'app/mattermost_bucket'; import {messageRetention} from './middleware'; import {createThunkMiddleware} from './thunk'; -import {transformSet} from './utils'; +import {transformSet, getStateForReset} from './utils'; function getAppReducer() { return require('../../app/reducers'); // eslint-disable-line global-require @@ -211,29 +210,12 @@ export default function configureAppStore(initialState) { await persistor.purge(); - const {currentTeamId} = state.entities.teams; - const myPreferences = {...state.entities.preferences.myPreferences}; - Object.keys(myPreferences).forEach((key) => { - if (!key.startsWith('theme--')) { - Reflect.deleteProperty(myPreferences, key); - } - }); - - const initialStateWithTeamAndThemePreferences = merge(initialState, { - entities: { - teams: { - currentTeamId, - }, - preferences: { - myPreferences, - }, - }, - }); + const resetState = getStateForReset(initialState, state); store.dispatch(batchActions([ { type: General.OFFLINE_STORE_RESET, - data: initialStateWithTeamAndThemePreferences, + data: resetState, }, { type: ErrorTypes.RESTORE_ERRORS, diff --git a/app/store/utils.js b/app/store/utils.js index 7d091ac02..f99430dff 100644 --- a/app/store/utils.js +++ b/app/store/utils.js @@ -1,6 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import merge from 'deepmerge'; + function transformFromSet(incoming) { const state = {...incoming}; @@ -61,4 +63,35 @@ export function waitForHydration(store, callback) { const unsubscribeFromStore = store.subscribe(subscription); } -} \ No newline at end of file +} + +export function getStateForReset(initialState, currentState) { + const {currentUserId} = currentState.entities.users; + const currentUserProfile = currentState.entities.users.profiles[currentUserId]; + const {currentTeamId} = currentState.entities.teams; + const myPreferences = {...currentState.entities.preferences.myPreferences}; + Object.keys(myPreferences).forEach((key) => { + if (!key.startsWith('theme--')) { + Reflect.deleteProperty(myPreferences, key); + } + }); + + const resetState = merge(initialState, { + entities: { + users: { + currentUserId, + profiles: { + [currentUserId]: currentUserProfile, + }, + }, + teams: { + currentTeamId, + }, + preferences: { + myPreferences, + }, + }, + }); + + return resetState; +} diff --git a/app/store/utils.test.js b/app/store/utils.test.js new file mode 100644 index 000000000..305fbce97 --- /dev/null +++ b/app/store/utils.test.js @@ -0,0 +1,79 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import initialState from 'app/initial_state'; +import {getStateForReset} from 'app/store/utils'; + +/* +const {currentUserId} = currentState.entities.users; + const currentUserProfile = currentState.entities.users.profiles[currentUserId]; + const {currentTeamId} = currentState.entities.teams; + const myPreferences = {...currentState.entities.preferences.myPreferences}; + Object.keys(myPreferences).forEach((key) => { + if (!key.startsWith('theme--')) { + Reflect.deleteProperty(myPreferences, key); + } + }); +*/ +describe('getStateForReset', () => { + const currentUserId = 'current-user-id'; + const otherUserId = 'other-user-id'; + const currentTeamId = 'current-team-id'; + const currentState = { + entities: { + users: { + currentUserId, + profiles: { + [currentUserId]: {}, + [otherUserId]: {}, + }, + }, + teams: { + currentTeamId, + }, + preferences: { + myPreferences: { + 'channel_open_time--1': {}, + 'channel_open_time--2': {}, + 'direct_channel_show--1': {}, + 'direct_channel_show--2': {}, + 'display_settings--1': {}, + 'display_settings--2': {}, + 'favorite_channel--1': {}, + 'favorite_channel--2': {}, + 'flagged_post--1': {}, + 'flagged_post--2': {}, + 'group_channel_show--1': {}, + 'group_channel_show--2': {}, + 'tutorial_step--1': {}, + 'tutorial_step--2': {}, + 'theme--1': {}, + 'theme--2': {}, + }, + }, + }, + }; + + it('should keep the current user\'s ID and profile', () => { + const resetState = getStateForReset(initialState, currentState); + const {users} = resetState.entities; + expect(users.currentUserId).toEqual(currentUserId); + expect(Object.keys(users.profiles).length).toEqual(1); + expect(users.profiles[currentUserId]).toBeDefined(); + }); + + it('should keep the current team ID', () => { + const resetState = getStateForReset(initialState, currentState); + const {teams} = resetState.entities; + expect(teams.currentTeamId).toEqual(currentTeamId); + }); + + it('should keep theme preferences', () => { + const resetState = getStateForReset(initialState, currentState); + const {myPreferences} = resetState.entities.preferences; + const preferenceKeys = Object.keys(myPreferences); + const themeKeys = preferenceKeys.filter((key) => key.startsWith('theme--')); + expect(themeKeys.length).not.toEqual(0); + expect(themeKeys.length).toEqual(preferenceKeys.length); + }); +});