diff --git a/app/AppContainer.tsx b/app/AppContainer.tsx index 441220fe..0ae892b7 100644 --- a/app/AppContainer.tsx +++ b/app/AppContainer.tsx @@ -6,7 +6,7 @@ import { connect } from 'react-redux'; import { SetUsernameStackParamList, StackParamList } from './definitions/navigationTypes'; import Navigation from './lib/Navigation'; import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation'; -import { ROOT_INSIDE, ROOT_LOADING, ROOT_OUTSIDE, ROOT_SET_USERNAME } from './actions/app'; +import { RootEnum } from './definitions'; // Stacks import AuthLoadingView from './views/AuthLoadingView'; // SetUsername Stack @@ -56,13 +56,13 @@ const App = React.memo(({ root, isMasterDetail }: { root: string; isMasterDetail }}> <> - {root === ROOT_LOADING ? : null} - {root === ROOT_OUTSIDE ? : null} - {root === ROOT_INSIDE && isMasterDetail ? ( + {root === RootEnum.ROOT_LOADING ? : null} + {root === RootEnum.ROOT_OUTSIDE ? : null} + {root === RootEnum.ROOT_INSIDE && isMasterDetail ? ( ) : null} - {root === ROOT_INSIDE && !isMasterDetail ? : null} - {root === ROOT_SET_USERNAME ? : null} + {root === RootEnum.ROOT_INSIDE && !isMasterDetail ? : null} + {root === RootEnum.ROOT_SET_USERNAME ? : null} diff --git a/app/actions/actionsTypes.ts b/app/actions/actionsTypes.ts index ad2d1718..f8852f28 100644 --- a/app/actions/actionsTypes.ts +++ b/app/actions/actionsTypes.ts @@ -2,8 +2,8 @@ const REQUEST = 'REQUEST'; const SUCCESS = 'SUCCESS'; const FAILURE = 'FAILURE'; const defaultTypes = [REQUEST, SUCCESS, FAILURE]; -function createRequestTypes(base = {}, types = defaultTypes): Record { - const res: Record = {}; +function createRequestTypes(base = {}, types = defaultTypes): Record { + const res: Record = {}; types.forEach(type => (res[type] = `${base}_${type}`)); return res; } diff --git a/app/actions/activeUsers.ts b/app/actions/activeUsers.ts index 737ae86b..1612e3a8 100644 --- a/app/actions/activeUsers.ts +++ b/app/actions/activeUsers.ts @@ -3,7 +3,7 @@ import { Action } from 'redux'; import { IActiveUsers } from '../reducers/activeUsers'; import { SET_ACTIVE_USERS } from './actionsTypes'; -export interface ISetActiveUsers extends Action { +interface ISetActiveUsers extends Action { activeUsers: IActiveUsers; } diff --git a/app/actions/app.js b/app/actions/app.js deleted file mode 100644 index fe6981d6..00000000 --- a/app/actions/app.js +++ /dev/null @@ -1,39 +0,0 @@ -import { APP } from './actionsTypes'; - -export const ROOT_OUTSIDE = 'outside'; -export const ROOT_INSIDE = 'inside'; -export const ROOT_LOADING = 'loading'; -export const ROOT_SET_USERNAME = 'setUsername'; - -export function appStart({ root, ...args }) { - return { - type: APP.START, - root, - ...args - }; -} - -export function appReady() { - return { - type: APP.READY - }; -} - -export function appInit() { - return { - type: APP.INIT - }; -} - -export function appInitLocalSettings() { - return { - type: APP.INIT_LOCAL_SETTINGS - }; -} - -export function setMasterDetail(isMasterDetail) { - return { - type: APP.SET_MASTER_DETAIL, - isMasterDetail - }; -} diff --git a/app/actions/app.ts b/app/actions/app.ts new file mode 100644 index 00000000..8285c527 --- /dev/null +++ b/app/actions/app.ts @@ -0,0 +1,53 @@ +import { Action } from 'redux'; + +import { RootEnum } from '../definitions'; +import { APP } from './actionsTypes'; + +interface IAppStart extends Action { + root: RootEnum; + text?: string; +} + +interface ISetMasterDetail extends Action { + isMasterDetail: boolean; +} + +export type TActionApp = IAppStart & ISetMasterDetail; + +interface Params { + root: RootEnum; + [key: string]: any; +} + +export function appStart({ root, ...args }: Params): IAppStart { + return { + type: APP.START, + root, + ...args + }; +} + +export function appReady(): Action { + return { + type: APP.READY + }; +} + +export function appInit(): Action { + return { + type: APP.INIT + }; +} + +export function appInitLocalSettings(): Action { + return { + type: APP.INIT_LOCAL_SETTINGS + }; +} + +export function setMasterDetail(isMasterDetail: boolean): ISetMasterDetail { + return { + type: APP.SET_MASTER_DETAIL, + isMasterDetail + }; +} diff --git a/app/definitions/index.ts b/app/definitions/index.ts index e37eae1f..1c154388 100644 --- a/app/definitions/index.ts +++ b/app/definitions/index.ts @@ -30,3 +30,4 @@ export interface IBaseScreen, S ext } export * from './redux'; +export * from './redux/TRootEnum'; diff --git a/app/definitions/redux/TRootEnum.ts b/app/definitions/redux/TRootEnum.ts new file mode 100644 index 00000000..8b0faca4 --- /dev/null +++ b/app/definitions/redux/TRootEnum.ts @@ -0,0 +1,6 @@ +export enum RootEnum { + ROOT_OUTSIDE = 'outside', + ROOT_INSIDE = 'inside', + ROOT_LOADING = 'loading', + ROOT_SET_USERNAME = 'setUsername' +} diff --git a/app/definitions/redux/index.ts b/app/definitions/redux/index.ts index c3d28158..c99152a4 100644 --- a/app/definitions/redux/index.ts +++ b/app/definitions/redux/index.ts @@ -1,5 +1,6 @@ // ACTIONS import { TActionActiveUsers } from '../../actions/activeUsers'; +import { TActionApp } from '../../actions/app'; import { TActionCreateChannel } from '../../actions/createChannel'; import { TActionCustomEmojis } from '../../actions/customEmojis'; import { TActionEncryption } from '../../actions/encryption'; @@ -13,6 +14,7 @@ import { TActionSortPreferences } from '../../actions/sortPreferences'; import { TActionUserTyping } from '../../actions/usersTyping'; // REDUCERS import { IActiveUsers } from '../../reducers/activeUsers'; +import { IApp } from '../../reducers/app'; import { IConnect } from '../../reducers/connect'; import { ICreateChannel } from '../../reducers/createChannel'; import { IEncryption } from '../../reducers/encryption'; @@ -29,8 +31,8 @@ export interface IApplicationState { meteor: IConnect; server: IServer; selectedUsers: ISelectedUsers; + app: IApp; createChannel: ICreateChannel; - app: any; room: any; rooms: any; sortPreferences: any; @@ -58,4 +60,5 @@ export type TApplicationActions = TActionActiveUsers & TActionUserTyping & TActionCreateChannel & TActionsShare & - TActionServer; + TActionServer & + TActionApp; diff --git a/app/reducers/app.test.ts b/app/reducers/app.test.ts new file mode 100644 index 00000000..a4910ab0 --- /dev/null +++ b/app/reducers/app.test.ts @@ -0,0 +1,44 @@ +import { appStart, appInit, setMasterDetail } from '../actions/app'; +import { initialState } from './app'; +import { mockedStore } from './mockedStore'; +import { RootEnum } from '../definitions'; +import { APP_STATE } from '../actions/actionsTypes'; + +describe('test reducer', () => { + it('should return initial state', () => { + const state = mockedStore.getState().app; + expect(state).toEqual(initialState); + }); + + it('should return root state after dispatch appStart action', () => { + mockedStore.dispatch(appStart({ root: RootEnum.ROOT_INSIDE })); + const { root } = mockedStore.getState().app; + expect(root).toEqual(RootEnum.ROOT_INSIDE); + }); + + it('should return ready state after dispatch appInit action', () => { + mockedStore.dispatch(appInit()); + const { ready } = mockedStore.getState().app; + expect(ready).toEqual(false); + }); + + it('should return ready state after dispatch setMasterDetail action', () => { + mockedStore.dispatch(setMasterDetail(false)); + const { isMasterDetail } = mockedStore.getState().app; + expect(isMasterDetail).toEqual(false); + }); + + it('should return correct state after app go to foreground', () => { + mockedStore.dispatch({ type: APP_STATE.FOREGROUND }); + const { foreground, background } = mockedStore.getState().app; + expect(foreground).toEqual(true); + expect(background).toEqual(false); + }); + + it('should return correct state after app go to background', () => { + mockedStore.dispatch({ type: APP_STATE.BACKGROUND }); + const { foreground, background } = mockedStore.getState().app; + expect(foreground).toEqual(false); + expect(background).toEqual(true); + }); +}); diff --git a/app/reducers/app.js b/app/reducers/app.ts similarity index 65% rename from app/reducers/app.js rename to app/reducers/app.ts index 4ed04dcd..5cd94897 100644 --- a/app/reducers/app.js +++ b/app/reducers/app.ts @@ -1,15 +1,26 @@ +import { TActionApp } from '../actions/app'; +import { RootEnum } from '../definitions'; import { APP, APP_STATE } from '../actions/actionsTypes'; -const initialState = { - root: null, +export interface IApp { + root?: RootEnum; + isMasterDetail: boolean; + text?: string; + ready: boolean; + foreground: boolean; + background: boolean; +} + +export const initialState: IApp = { + root: undefined, isMasterDetail: false, - text: null, + text: undefined, ready: false, foreground: true, background: false }; -export default function app(state = initialState, action) { +export default function app(state = initialState, action: TActionApp): IApp { switch (action.type) { case APP_STATE.FOREGROUND: return { diff --git a/app/sagas/deepLinking.js b/app/sagas/deepLinking.js index 240771b3..900e6a14 100644 --- a/app/sagas/deepLinking.js +++ b/app/sagas/deepLinking.js @@ -8,11 +8,12 @@ import { inviteLinksRequest, inviteLinksSetToken } from '../actions/inviteLinks' import database from '../lib/database'; import RocketChat from '../lib/rocketchat'; import EventEmitter from '../utils/events'; -import { ROOT_INSIDE, ROOT_OUTSIDE, appInit, appStart } from '../actions/app'; +import { appInit, appStart } from '../actions/app'; import { localAuthenticate } from '../utils/localAuthentication'; import { goRoom } from '../utils/goRoom'; import { loginRequest } from '../actions/login'; import log from '../utils/log'; +import { RootEnum } from '../definitions'; const roomTypes = { channel: 'c', @@ -41,7 +42,7 @@ const popToRoot = function popToRoot({ isMasterDetail }) { }; const navigate = function* navigate({ params }) { - yield put(appStart({ root: ROOT_INSIDE })); + yield put(appStart({ root: RootEnum.ROOT_INSIDE })); if (params.path || params.rid) { let type; let name; @@ -192,7 +193,7 @@ const handleOpen = function* handleOpen({ params }) { yield fallbackNavigation(); return; } - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); yield put(serverInitAdd(server)); yield delay(1000); EventEmitter.emit('NewServer', { server: host }); diff --git a/app/sagas/init.js b/app/sagas/init.js index af42c4fa..3d7fbd9d 100644 --- a/app/sagas/init.js +++ b/app/sagas/init.js @@ -9,7 +9,8 @@ import RocketChat from '../lib/rocketchat'; import log from '../utils/log'; import database from '../lib/database'; import { localAuthenticate } from '../utils/localAuthentication'; -import { ROOT_OUTSIDE, appReady, appStart } from '../actions/app'; +import { appReady, appStart } from '../actions/app'; +import { RootEnum } from '../definitions'; export const initLocalSettings = function* initLocalSettings() { const sortPreferences = yield RocketChat.getSortPreferences(); @@ -22,7 +23,7 @@ const restore = function* restore() { let userId = yield UserPreferences.getStringAsync(`${RocketChat.TOKEN_KEY}-${server}`); if (!server) { - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); } else if (!userId) { const serversDB = database.servers; const serversCollection = serversDB.get('servers'); @@ -38,7 +39,7 @@ const restore = function* restore() { } } } - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); } else { const serversDB = database.servers; const serverCollections = serversDB.get('servers'); @@ -56,7 +57,7 @@ const restore = function* restore() { yield put(appReady({})); } catch (e) { log(e); - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); } }; diff --git a/app/sagas/login.js b/app/sagas/login.js index 1d8f688f..26435ad5 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -3,7 +3,7 @@ import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { Q } from '@nozbe/watermelondb'; import * as types from '../actions/actionsTypes'; -import { ROOT_INSIDE, ROOT_LOADING, ROOT_OUTSIDE, ROOT_SET_USERNAME, appStart } from '../actions/app'; +import { appStart } from '../actions/app'; import { selectServerRequest, serverFinishAdd } from '../actions/server'; import { loginFailure, loginSuccess, logout, setUser } from '../actions/login'; import { roomsRequest } from '../actions/rooms'; @@ -20,6 +20,7 @@ import { encryptionInit, encryptionStop } from '../actions/encryption'; import UserPreferences from '../lib/userPreferences'; import { inquiryRequest, inquiryReset } from '../ee/omnichannel/actions/inquiry'; import { isOmnichannelStatusAvailable } from '../ee/omnichannel/lib'; +import { RootEnum } from '../definitions'; const getServer = state => state.server.server; const loginWithPasswordCall = args => RocketChat.loginWithPassword(args); @@ -38,7 +39,7 @@ const handleLoginRequest = function* handleLoginRequest({ credentials, logoutOnE if (!result.username) { yield put(serverFinishAdd()); yield put(setUser(result)); - yield put(appStart({ root: ROOT_SET_USERNAME })); + yield put(appStart({ root: RootEnum.ROOT_SET_USERNAME })); } else { const server = yield select(getServer); yield localAuthenticate(server); @@ -167,7 +168,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) { yield put(setUser(user)); EventEmitter.emit('connected'); - yield put(appStart({ root: ROOT_INSIDE })); + yield put(appStart({ root: RootEnum.ROOT_INSIDE })); const inviteLinkToken = yield select(state => state.inviteLinks.token); if (inviteLinkToken) { yield put(inviteLinksRequest(inviteLinkToken)); @@ -179,7 +180,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) { const handleLogout = function* handleLogout({ forcedByServer }) { yield put(encryptionStop()); - yield put(appStart({ root: ROOT_LOADING, text: I18n.t('Logging_out') })); + yield put(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Logging_out') })); const server = yield select(getServer); if (server) { try { @@ -187,7 +188,7 @@ const handleLogout = function* handleLogout({ forcedByServer }) { // if the user was logged out by the server if (forcedByServer) { - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); showErrorAlert(I18n.t('Logged_out_by_server'), I18n.t('Oops')); yield delay(300); EventEmitter.emit('NewServer', { server }); @@ -209,10 +210,10 @@ const handleLogout = function* handleLogout({ forcedByServer }) { } } // if there's no servers, go outside - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); } } catch (e) { - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); log(e); } } diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js index 5aacd2b1..26131a31 100644 --- a/app/sagas/selectServer.js +++ b/app/sagas/selectServer.js @@ -15,11 +15,12 @@ import database from '../lib/database'; import log, { logServerVersion } from '../utils/log'; import I18n from '../i18n'; import { BASIC_AUTH_KEY, setBasicAuth } from '../utils/fetch'; -import { ROOT_INSIDE, ROOT_OUTSIDE, appStart } from '../actions/app'; +import { appStart } from '../actions/app'; import UserPreferences from '../lib/userPreferences'; import { encryptionStop } from '../actions/encryption'; import SSLPinning from '../utils/sslPinning'; import { inquiryReset } from '../ee/omnichannel/actions/inquiry'; +import { RootEnum } from '../definitions'; const getServerInfo = function* getServerInfo({ server, raiseError = true }) { try { @@ -111,10 +112,10 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch yield put(clearSettings()); yield RocketChat.connect({ server, user, logoutOnError: true }); yield put(setUser(user)); - yield put(appStart({ root: ROOT_INSIDE })); + yield put(appStart({ root: RootEnum.ROOT_INSIDE })); } else { yield RocketChat.connect({ server }); - yield put(appStart({ root: ROOT_OUTSIDE })); + yield put(appStart({ root: RootEnum.ROOT_OUTSIDE })); } // We can't use yield here because fetch of Settings & Custom Emojis is slower diff --git a/app/sagas/state.js b/app/sagas/state.js index b9afeb4d..8f122b4d 100644 --- a/app/sagas/state.js +++ b/app/sagas/state.js @@ -5,11 +5,11 @@ import { setBadgeCount } from '../notifications/push'; import log from '../utils/log'; import { localAuthenticate, saveLastLocalAuthenticationSession } from '../utils/localAuthentication'; import { APP_STATE } from '../actions/actionsTypes'; -import { ROOT_OUTSIDE } from '../actions/app'; +import { RootEnum } from '../definitions'; const appHasComeBackToForeground = function* appHasComeBackToForeground() { const appRoot = yield select(state => state.app.root); - if (appRoot === ROOT_OUTSIDE) { + if (appRoot === RootEnum.ROOT_OUTSIDE) { return; } const login = yield select(state => state.login); @@ -29,7 +29,7 @@ const appHasComeBackToForeground = function* appHasComeBackToForeground() { const appHasComeBackToBackground = function* appHasComeBackToBackground() { const appRoot = yield select(state => state.app.root); - if (appRoot === ROOT_OUTSIDE) { + if (appRoot === RootEnum.ROOT_OUTSIDE) { return; } try { diff --git a/app/views/LanguageView/index.tsx b/app/views/LanguageView/index.tsx index f544fc54..af45f41a 100644 --- a/app/views/LanguageView/index.tsx +++ b/app/views/LanguageView/index.tsx @@ -1,31 +1,29 @@ import React from 'react'; import { FlatList } from 'react-native'; -import { connect } from 'react-redux'; import RNRestart from 'react-native-restart'; -import { Dispatch } from 'redux'; +import { connect } from 'react-redux'; +import { appStart } from '../../actions/app'; +import { setUser } from '../../actions/login'; +import { themes } from '../../constants/colors'; +import * as List from '../../containers/List'; +import SafeAreaView from '../../containers/SafeAreaView'; +import StatusBar from '../../containers/StatusBar'; +import { IApplicationState, IBaseScreen, RootEnum } from '../../definitions'; +import I18n, { isRTL, LANGUAGES } from '../../i18n'; +import database from '../../lib/database'; import RocketChat from '../../lib/rocketchat'; -import I18n, { LANGUAGES, isRTL } from '../../i18n'; +import { getUserSelector } from '../../selectors/login'; +import { SettingsStackParamList } from '../../stacks/types'; +import { withTheme } from '../../theme'; import { showErrorAlert } from '../../utils/info'; import log, { events, logEvent } from '../../utils/log'; -import { setUser as setUserAction } from '../../actions/login'; -import StatusBar from '../../containers/StatusBar'; -import * as List from '../../containers/List'; -import { themes } from '../../constants/colors'; -import { withTheme } from '../../theme'; -import { ROOT_INSIDE, ROOT_LOADING, appStart as appStartAction } from '../../actions/app'; -import { getUserSelector } from '../../selectors/login'; -import database from '../../lib/database'; -import SafeAreaView from '../../containers/SafeAreaView'; -interface ILanguageViewProps { +interface ILanguageViewProps extends IBaseScreen { user: { id: string; language: string; }; - setUser(user: object): void; - appStart(params: any): void; - theme: string; } interface ILanguageViewState { @@ -69,11 +67,11 @@ class LanguageView extends React.Component setTimeout(resolve, 300))]); @@ -81,13 +79,13 @@ class LanguageView extends React.Component { logEvent(events.LANG_SET_LANGUAGE); - const { user, setUser } = this.props; + const { user, dispatch } = this.props; const params: { language?: string } = {}; @@ -98,7 +96,7 @@ class LanguageView extends React.Component ({ +const mapStateToProps = (state: IApplicationState) => ({ user: getUserSelector(state) }); -const mapDispatchToProps = (dispatch: Dispatch) => ({ - setUser: (params: any) => dispatch(setUserAction(params)), - appStart: (params: any) => dispatch(appStartAction(params)) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(withTheme(LanguageView)); +export default connect(mapStateToProps)(withTheme(LanguageView)); diff --git a/app/views/RoomsListView/ServerDropdown.js b/app/views/RoomsListView/ServerDropdown.js index 94232acc..2596fc36 100644 --- a/app/views/RoomsListView/ServerDropdown.js +++ b/app/views/RoomsListView/ServerDropdown.js @@ -8,7 +8,7 @@ import * as List from '../../containers/List'; import Button from '../../containers/Button'; import { toggleServerDropdown } from '../../actions/rooms'; import { selectServerRequest, serverInitAdd } from '../../actions/server'; -import { appStart, ROOT_OUTSIDE } from '../../actions/app'; +import { appStart } from '../../actions/app'; import RocketChat from '../../lib/rocketchat'; import I18n from '../../i18n'; import EventEmitter from '../../utils/events'; @@ -24,6 +24,8 @@ import log, { events, logEvent } from '../../utils/log'; import { headerHeight } from '../../containers/Header'; import { goRoom } from '../../utils/goRoom'; import UserPreferences from '../../lib/userPreferences'; +import { RootEnum } from '../../definitions'; + import styles from './styles'; const ROW_HEIGHT = 68; @@ -106,7 +108,7 @@ class ServerDropdown extends Component { navToNewServer = previousServer => { const { dispatch } = this.props; batch(() => { - dispatch(appStart({ root: ROOT_OUTSIDE })); + dispatch(appStart({ root: RootEnum.ROOT_OUTSIDE })); dispatch(serverInitAdd(previousServer)); }); }; diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js index 45065b90..0ca1e5fe 100644 --- a/app/views/RoomsListView/index.js +++ b/app/views/RoomsListView/index.js @@ -13,12 +13,13 @@ import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../presentation/R import log, { logEvent, events } from '../../utils/log'; import I18n from '../../i18n'; import { closeSearchHeader, closeServerDropdown, openSearchHeader, roomsRequest } from '../../actions/rooms'; -import { appStart, ROOT_OUTSIDE } from '../../actions/app'; +import { appStart } from '../../actions/app'; import debounce from '../../utils/debounce'; import { isIOS, isTablet } from '../../utils/deviceInfo'; import * as HeaderButton from '../../containers/HeaderButton'; import StatusBar from '../../containers/StatusBar'; import ActivityIndicator from '../../containers/ActivityIndicator'; +import { serverInitAdd } from '../../actions/server'; import { animateNextTransition } from '../../utils/layoutAnimation'; import { withTheme } from '../../theme'; import { themes } from '../../constants/colors'; @@ -43,6 +44,7 @@ import { showConfirmationAlert, showErrorAlert } from '../../utils/info'; import { E2E_BANNER_TYPE } from '../../lib/encryption/constants'; import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry'; import { changeLivechatStatus, isOmnichannelStatusAvailable } from '../../ee/omnichannel/lib'; +import { RootEnum } from '../../definitions'; import { DisplayMode, SortBy } from '../../constants/constantDisplayMode'; import styles from './styles'; import ServerDropdown from './ServerDropdown'; @@ -132,8 +134,7 @@ class RoomsListView extends React.Component { createDirectMessagePermission: PropTypes.array, createPublicChannelPermission: PropTypes.array, createPrivateChannelPermission: PropTypes.array, - createDiscussionPermission: PropTypes.array, - initAdd: PropTypes.func + createDiscussionPermission: PropTypes.array }; constructor(props) { @@ -831,7 +832,7 @@ class RoomsListView extends React.Component { }; handleCommands = ({ event }) => { - const { navigation, server, isMasterDetail, dispatch, initAdd } = this.props; + const { navigation, server, isMasterDetail, dispatch } = this.props; const { input } = event; if (handleCommandShowPreferences(event)) { navigation.navigate('SettingsView'); @@ -851,8 +852,8 @@ class RoomsListView extends React.Component { } } else if (handleCommandAddNewServer(event)) { batch(() => { - dispatch(appStart({ root: ROOT_OUTSIDE })); - initAdd(server); + dispatch(appStart({ root: RootEnum.ROOT_OUTSIDE })); + dispatch(serverInitAdd(server)); }); } }; diff --git a/app/views/SettingsView/index.tsx b/app/views/SettingsView/index.tsx index e77474c4..b2fd3bcc 100644 --- a/app/views/SettingsView/index.tsx +++ b/app/views/SettingsView/index.tsx @@ -1,50 +1,44 @@ +import CookieManager from '@react-native-cookies/cookies'; +import { StackNavigationOptions } from '@react-navigation/stack'; +import FastImage from '@rocket.chat/react-native-fast-image'; import React from 'react'; import { Clipboard, Linking, Share } from 'react-native'; import { connect } from 'react-redux'; -import FastImage from '@rocket.chat/react-native-fast-image'; -import CookieManager from '@react-native-cookies/cookies'; -import { StackNavigationOptions, StackNavigationProp } from '@react-navigation/stack'; -import { SettingsStackParamList } from '../../stacks/types'; -import { logout as logoutAction } from '../../actions/login'; -import { selectServerRequest as selectServerRequestAction } from '../../actions/server'; +import { appStart } from '../../actions/app'; +import { logout } from '../../actions/login'; +import { selectServerRequest } from '../../actions/server'; import { themes } from '../../constants/colors'; +import { isFDroidBuild } from '../../constants/environment'; +import { APP_STORE_LINK, FDROID_MARKET_LINK, LICENSE_LINK, PLAY_MARKET_LINK } from '../../constants/links'; import * as HeaderButton from '../../containers/HeaderButton'; -import StatusBar from '../../containers/StatusBar'; import * as List from '../../containers/List'; +import SafeAreaView from '../../containers/SafeAreaView'; +import StatusBar from '../../containers/StatusBar'; +import { LISTENER } from '../../containers/Toast'; +import { IApplicationState, IBaseScreen, RootEnum } from '../../definitions'; import I18n from '../../i18n'; +import database from '../../lib/database'; import RocketChat from '../../lib/rocketchat'; +import { IServer } from '../../reducers/server'; +import { getUserSelector } from '../../selectors/login'; +import { SettingsStackParamList } from '../../stacks/types'; +import { withTheme } from '../../theme'; import { getDeviceModel, getReadableVersion, isAndroid } from '../../utils/deviceInfo'; -import openLink from '../../utils/openLink'; +import EventEmitter from '../../utils/events'; import { showConfirmationAlert, showErrorAlert } from '../../utils/info'; import { events, logEvent } from '../../utils/log'; -import { APP_STORE_LINK, FDROID_MARKET_LINK, LICENSE_LINK, PLAY_MARKET_LINK } from '../../constants/links'; -import { withTheme } from '../../theme'; -import SidebarView from '../SidebarView'; -import { LISTENER } from '../../containers/Toast'; -import EventEmitter from '../../utils/events'; -import { ROOT_LOADING, appStart as appStartAction } from '../../actions/app'; +import openLink from '../../utils/openLink'; import { onReviewPress } from '../../utils/review'; -import SafeAreaView from '../../containers/SafeAreaView'; -import database from '../../lib/database'; -import { isFDroidBuild } from '../../constants/environment'; -import { getUserSelector } from '../../selectors/login'; +import SidebarView from '../SidebarView'; -interface ISettingsViewProps { - navigation: StackNavigationProp; - server: { - version: string; - server: string; - }; - theme: string; +interface ISettingsViewProps extends IBaseScreen { + server: IServer; isMasterDetail: boolean; - logout: Function; - selectServerRequest: Function; user: { roles: []; id: string; }; - appStart: Function; } class SettingsView extends React.Component { @@ -59,7 +53,7 @@ class SettingsView extends React.Component { }); checkCookiesAndLogout = async () => { - const { logout, user } = this.props; + const { dispatch, user } = this.props; const db = database.servers; const usersCollection = db.get('users'); try { @@ -72,14 +66,14 @@ class SettingsView extends React.Component { dismissText: I18n.t('Clear_cookies_no'), onPress: async () => { await CookieManager.clearAll(true); - logout(); + dispatch(logout()); }, onCancel: () => { - logout(); + dispatch(logout()); } }); } else { - logout(); + dispatch(logout()); } } catch { // Do nothing: user not found @@ -103,15 +97,14 @@ class SettingsView extends React.Component { onPress: async () => { const { server: { server }, - appStart, - selectServerRequest + dispatch } = this.props; - appStart({ root: ROOT_LOADING, text: I18n.t('Clear_cache_loading') }); + dispatch(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Clear_cache_loading') })); await RocketChat.clearCache({ server }); await FastImage.clearMemoryCache(); await FastImage.clearDiskCache(); RocketChat.disconnect(); - selectServerRequest(server); + dispatch(selectServerRequest(server)); } }); }; @@ -156,8 +149,9 @@ class SettingsView extends React.Component { const { server: { version } } = this.props; - logEvent(events.SE_COPY_SERVER_VERSION, { serverVersion: version }); - this.saveToClipboard(version); + const vers = version as string; + logEvent(events.SE_COPY_SERVER_VERSION, { serverVersion: vers }); + this.saveToClipboard(vers); }; copyAppVersion = () => { @@ -298,16 +292,10 @@ class SettingsView extends React.Component { } } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: IApplicationState) => ({ server: state.server, user: getUserSelector(state), isMasterDetail: state.app.isMasterDetail }); -const mapDispatchToProps = (dispatch: any) => ({ - logout: () => dispatch(logoutAction()), - selectServerRequest: (params: any) => dispatch(selectServerRequestAction(params)), - appStart: (params: any) => dispatch(appStartAction(params)) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(withTheme(SettingsView)); +export default connect(mapStateToProps)(withTheme(SettingsView));