Refactor appStart

This commit is contained in:
Diego Mello 2020-05-26 14:35:56 -03:00
parent 3b93c11001
commit 988d3a396f
18 changed files with 90 additions and 97 deletions

View File

@ -7,6 +7,9 @@ import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-c
import { defaultHeader, onNavigationStateChange } from './utils/navigation';
import Navigation from './lib/Navigation';
import {
ROOT_LOADING, ROOT_OUTSIDE, ROOT_NEW_SERVER, ROOT_INSIDE, ROOT_SET_USERNAME, ROOT_BACKGROUND
} from './actions/app';
// Stacks
import AuthLoadingView from './views/AuthLoadingView';
@ -31,7 +34,7 @@ const SetUsernameStack = () => (
// App
const Stack = createStackNavigator();
const App = React.memo(({ root }) => {
if (!root || root === 'background') {
if (!root || root === ROOT_BACKGROUND) {
return null;
}
@ -45,25 +48,25 @@ const App = React.memo(({ root }) => {
>
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
<>
{root === 'loading' ? (
{root === ROOT_LOADING ? (
<Stack.Screen
name='AuthLoading'
component={AuthLoadingView}
/>
) : null}
{root === 'outside' || root === 'newServer' ? (
{root === ROOT_OUTSIDE || root === ROOT_NEW_SERVER ? (
<Stack.Screen
name='OutsideStack'
component={OutsideStack}
/>
) : null}
{root === 'inside' ? (
{root === ROOT_INSIDE ? (
<Stack.Screen
name='InsideStack'
component={InsideStack}
/>
) : null}
{root === 'setUsername' ? (
{root === ROOT_SET_USERNAME ? (
<Stack.Screen
name='SetUsernameStack'
component={SetUsernameStack}

34
app/actions/app.js Normal file
View File

@ -0,0 +1,34 @@
import { APP } from './actionsTypes';
export const ROOT_OUTSIDE = 'outside';
export const ROOT_INSIDE = 'inside';
export const ROOT_LOADING = 'loading';
export const ROOT_NEW_SERVER = 'newServer';
export const ROOT_SET_USERNAME = 'setUsername';
export const ROOT_BACKGROUND = 'background';
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
};
}

View File

@ -1,41 +0,0 @@
import * as types from '../constants/types';
import { APP } from './actionsTypes';
export function appStart(root, text) {
return {
type: APP.START,
root,
text
};
}
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 setCurrentServer(server) {
return {
type: types.SET_CURRENT_SERVER,
payload: server
};
}
export function login() {
return {
type: 'LOGIN'
};
}

View File

@ -1,4 +0,0 @@
export const SET_CURRENT_SERVER = 'SET_CURRENT_SERVER';
export const SET_CUSTOM_EMOJIS = 'SET_CUSTOM_EMOJIS';
export const ADD_SETTINGS = 'ADD_SETTINGS';
export const CLEAR_SETTINGS = 'CLEAR_SETTINGS';

View File

@ -13,7 +13,7 @@ import {
unsubscribeTheme
} from './utils/theme';
import EventEmitter from './utils/events';
import { appInit, appInitLocalSettings } from './actions';
import { appInit, appInitLocalSettings } from './actions/app';
import { deepLinkingOpen } from './actions/deepLinking';
import Navigation from './lib/Navigation';
import parseQuery from './lib/methods/helpers/parseQuery';

View File

@ -2,7 +2,8 @@ import { APP, APP_STATE } from '../actions/actionsTypes';
const initialState = {
root: null,
text: null,
text: '',
previousServer: '',
ready: false,
foreground: true,
background: false
@ -27,6 +28,7 @@ export default function app(state = initialState, action) {
...state,
root: action.root,
text: action.text,
previousServer: action.previousServer
};
case APP.INIT:
return {

View File

@ -10,7 +10,7 @@ import { inviteLinksSetToken, inviteLinksRequest } from '../actions/inviteLinks'
import database from '../lib/database';
import RocketChat from '../lib/rocketchat';
import EventEmitter from '../utils/events';
import { appStart } from '../actions';
import { appStart, ROOT_INSIDE } from '../actions/app';
import { localAuthenticate } from '../utils/localAuthentication';
const roomTypes = {
@ -29,7 +29,7 @@ const handleInviteLink = function* handleInviteLink({ params, requireLogin = fal
};
const navigate = function* navigate({ params }) {
yield put(appStart('inside'));
yield put(appStart({ root: ROOT_INSIDE }));
if (params.path) {
const [type, name] = params.path.split('/');
if (type !== 'invite') {

View File

@ -4,14 +4,12 @@ import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import RNBootSplash from 'react-native-bootsplash';
import AsyncStorage from '@react-native-community/async-storage';
import * as actions from '../actions';
import { selectServerRequest } from '../actions/server';
import { setAllPreferences } from '../actions/sortPreferences';
import { toggleCrashReport } from '../actions/crashReport';
import { APP } from '../actions/actionsTypes';
import RocketChat from '../lib/rocketchat';
import log from '../utils/log';
import Navigation from '../lib/Navigation';
import {
SERVERS, SERVER_ICON, SERVER_NAME, SERVER_URL, TOKEN, USER_ID
} from '../constants/userDefaults';
@ -19,6 +17,7 @@ import { isIOS } from '../utils/deviceInfo';
import database from '../lib/database';
import protectedFunction from '../lib/methods/helpers/protectedFunction';
import { localAuthenticate } from '../utils/localAuthentication';
import { appStart, ROOT_OUTSIDE, appReady } from '../actions/app';
export const initLocalSettings = function* initLocalSettings() {
const sortPreferences = yield RocketChat.getSortPreferences();
@ -96,7 +95,7 @@ const restore = function* restore() {
RNUserDefaults.clear(RocketChat.TOKEN_KEY),
RNUserDefaults.clear('currentServer')
]);
yield put(actions.appStart('outside'));
yield put(appStart({ root: ROOT_OUTSIDE }));
} else {
const serversDB = database.servers;
const serverCollections = serversDB.collections.get('servers');
@ -106,10 +105,10 @@ const restore = function* restore() {
yield put(selectServerRequest(server, serverObj && serverObj.version));
}
yield put(actions.appReady({}));
yield put(appReady({}));
} catch (e) {
log(e);
yield put(actions.appStart('outside'));
yield put(appStart({ root: ROOT_OUTSIDE }));
}
};

View File

@ -7,7 +7,7 @@ import moment from 'moment';
import 'moment/min/locales';
import * as types from '../actions/actionsTypes';
import { appStart } from '../actions';
import { appStart, ROOT_SET_USERNAME, ROOT_INSIDE, ROOT_LOADING, ROOT_OUTSIDE } from '../actions/app';
import { serverFinishAdd, selectServerRequest } from '../actions/server';
import {
loginFailure, loginSuccess, setUser, logout
@ -40,7 +40,7 @@ const handleLoginRequest = function* handleLoginRequest({ credentials, logoutOnE
if (!result.username) {
yield put(serverFinishAdd());
yield put(setUser(result));
yield put(appStart('setUsername'));
yield put(appStart({ root: ROOT_SET_USERNAME }));
} else {
const server = yield select(getServer);
yield localAuthenticate(server);
@ -133,17 +133,17 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
let currentRoot;
if (adding) {
yield put(serverFinishAdd());
yield put(appStart('inside'));
yield put(appStart({ root: ROOT_INSIDE }));
} else {
currentRoot = yield select(state => state.app.root);
if (currentRoot !== 'inside') {
yield put(appStart('inside'));
if (currentRoot !== ROOT_INSIDE) {
yield put(appStart({ root: ROOT_INSIDE }));
}
}
// after a successful login, check if it's been invited via invite link
currentRoot = yield select(state => state.app.root);
if (currentRoot === 'inside') {
if (currentRoot === ROOT_INSIDE) {
const inviteLinkToken = yield select(state => state.inviteLinks.token);
if (inviteLinkToken) {
yield put(inviteLinksRequest(inviteLinkToken));
@ -155,7 +155,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
};
const handleLogout = function* handleLogout({ forcedByServer }) {
yield put(appStart('loading', I18n.t('Logging_out')));
yield put(appStart({ root: ROOT_LOADING, text: I18n.t('Logging_out') }));
const server = yield select(getServer);
if (server) {
try {
@ -163,7 +163,7 @@ const handleLogout = function* handleLogout({ forcedByServer }) {
// if the user was logged out by the server
if (forcedByServer) {
yield put(appStart('outside'));
yield put(appStart({ root: ROOT_OUTSIDE }));
showErrorAlert(I18n.t('Logged_out_by_server'), I18n.t('Oops'));
EventEmitter.emit('NewServer', { server });
} else {
@ -183,10 +183,10 @@ const handleLogout = function* handleLogout({ forcedByServer }) {
}
}
// if there's no servers, go outside
yield put(appStart('outside'));
yield put(appStart({ root: ROOT_OUTSIDE }));
}
} catch (e) {
yield put(appStart('outside'));
yield put(appStart({ root: ROOT_OUTSIDE }));
log(e);
}
}

View File

@ -6,7 +6,6 @@ import semver from 'semver';
import Navigation from '../lib/Navigation';
import { SERVER } from '../actions/actionsTypes';
import * as actions from '../actions';
import {
serverFailure, selectServerRequest, selectServerSuccess, selectServerFailure
} from '../actions/server';
@ -19,6 +18,7 @@ import { extractHostname } from '../utils/server';
import I18n from '../i18n';
import { SERVERS, TOKEN, SERVER_URL } from '../constants/userDefaults';
import { BASIC_AUTH_KEY, setBasicAuth } from '../utils/fetch';
import { appStart, ROOT_INSIDE, ROOT_OUTSIDE } from '../actions/app';
const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
try {
@ -103,10 +103,10 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
yield put(clearSettings());
yield RocketChat.connect({ server, user, logoutOnError: true });
yield put(setUser(user));
yield put(actions.appStart('inside'));
yield put(appStart({ root: ROOT_INSIDE }));
} else {
yield RocketChat.connect({ server });
yield put(actions.appStart('outside'));
yield put(appStart({ root: ROOT_OUTSIDE }));
}
// We can't use yield here because fetch of Settings & Custom Emojis is slower

View File

@ -5,10 +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';
const appHasComeBackToForeground = function* appHasComeBackToForeground() {
const appRoot = yield select(state => state.app.root);
if (appRoot === 'outside') {
if (appRoot === ROOT_OUTSIDE) {
return;
}
const auth = yield select(state => state.login.isAuthenticated);
@ -27,7 +28,7 @@ const appHasComeBackToForeground = function* appHasComeBackToForeground() {
const appHasComeBackToBackground = function* appHasComeBackToBackground() {
const appRoot = yield select(state => state.app.root);
if (appRoot === 'outside') {
if (appRoot === ROOT_OUTSIDE) {
return;
}
const auth = yield select(state => state.login.isAuthenticated);

View File

@ -14,6 +14,7 @@ import ForgotPasswordView from '../views/ForgotPasswordView';
import RegisterView from '../views/RegisterView';
import LegalView from '../views/LegalView';
import AuthenticationWebView from '../views/AuthenticationWebView';
import { ROOT_OUTSIDE } from '../actions/app';
// Outside
const Outside = createStackNavigator();
@ -22,7 +23,7 @@ const _OutsideStack = ({ root }) => {
return (
<Outside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme) }}>
{root === 'outside' ? (
{root === ROOT_OUTSIDE ? (
<Outside.Screen
name='OnboardingView'
component={OnboardingView}

View File

@ -15,7 +15,7 @@ import ListItem from '../../containers/ListItem';
import Separator from '../../containers/Separator';
import { themes } from '../../constants/colors';
import { withTheme } from '../../theme';
import { appStart as appStartAction } from '../../actions';
import { appStart as appStartAction, ROOT_LOADING, ROOT_INSIDE } from '../../actions/app';
import { getUserSelector } from '../../selectors/login';
import database from '../../lib/database';
import SafeAreaView from '../../containers/SafeAreaView';
@ -103,12 +103,12 @@ class LanguageView extends React.Component {
const { appStart } = this.props;
await appStart('loading', I18n.t('Change_language_loading'));
await appStart({ root: ROOT_LOADING, text: I18n.t('Change_language_loading') });
// shows loading for at least 300ms
await Promise.all([this.changeLanguage(language), new Promise(resolve => setTimeout(resolve, 300))]);
await appStart('inside');
await appStart({ root: ROOT_INSIDE });
}
changeLanguage = async(language) => {
@ -199,7 +199,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({
setUser: params => dispatch(setUserAction(params)),
appStart: (...params) => dispatch(appStartAction(...params))
appStart: params => dispatch(appStartAction(params))
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(LanguageView));

View File

@ -15,7 +15,6 @@ import EventEmitter from '../utils/events';
import {
selectServerRequest, serverRequest, serverInitAdd, serverFinishAdd
} from '../actions/server';
import { appStart as appStartAction } from '../actions';
import sharedStyles from './Styles';
import Button from '../containers/Button';
import TextInput from '../containers/TextInput';
@ -342,15 +341,14 @@ class NewServerView extends React.Component {
const mapStateToProps = state => ({
connecting: state.server.connecting,
previousServer: state.app.text
previousServer: state.app.previousServer
});
const mapDispatchToProps = dispatch => ({
connectServer: (server, certificate) => dispatch(serverRequest(server, certificate)),
initAdd: () => dispatch(serverInitAdd()),
finishAdd: () => dispatch(serverFinishAdd()),
selectServer: server => dispatch(selectServerRequest(server)),
appStart: root => dispatch(appStartAction(root))
selectServer: server => dispatch(selectServerRequest(server))
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(NewServerView));

View File

@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Orientation from 'react-native-orientation-locker';
import { appStart as appStartAction } from '../../actions';
import { appStart as appStartAction, ROOT_BACKGROUND } from '../../actions/app';
import I18n from '../../i18n';
import Button from '../../containers/Button';
import styles from './styles';
@ -48,7 +48,7 @@ class OnboardingView extends React.Component {
handleBackPress = () => {
const { appStart } = this.props;
appStart('background');
appStart({ root: ROOT_BACKGROUND });
return false;
}
@ -98,7 +98,7 @@ class OnboardingView extends React.Component {
}
const mapDispatchToProps = dispatch => ({
appStart: root => dispatch(appStartAction(root))
appStart: params => dispatch(appStartAction(params))
});
export default connect(null, mapDispatchToProps)(withTheme(OnboardingView));

View File

@ -10,7 +10,7 @@ import RNUserDefaults from 'rn-user-defaults';
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
import { appStart as appStartAction } from '../../actions';
import { appStart as appStartAction, ROOT_NEW_SERVER } from '../../actions/app';
import styles from './styles';
import Touch from '../../utils/touch';
import RocketChat from '../../lib/rocketchat';
@ -37,6 +37,7 @@ class ServerDropdown extends Component {
split: PropTypes.bool,
server: PropTypes.string,
theme: PropTypes.string,
appStart: PropTypes.func,
toggleServerDropdown: PropTypes.func,
selectServerRequest: PropTypes.func
}
@ -128,7 +129,7 @@ class ServerDropdown extends Component {
this.close();
setTimeout(() => {
appStart('newServer', server);
appStart({ root: ROOT_NEW_SERVER, previousServer: server });
}, ANIMATION_DURATION);
}
@ -144,7 +145,7 @@ class ServerDropdown extends Component {
}
if (!userId) {
setTimeout(() => {
appStart('newServer', server);
appStart({ root: ROOT_NEW_SERVER, previousServer: server });
this.newServerTimeout = setTimeout(() => {
EventEmitter.emit('NewServer', { server });
}, ANIMATION_DURATION);
@ -287,7 +288,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({
toggleServerDropdown: () => dispatch(toggleServerDropdownAction()),
selectServerRequest: server => dispatch(selectServerRequestAction(server)),
appStart: (param, text) => dispatch(appStartAction(param, text))
appStart: params => dispatch(appStartAction(params))
});
export default withNavigation(connect(mapStateToProps, mapDispatchToProps)(withTheme(withSplit(ServerDropdown))));

View File

@ -29,7 +29,7 @@ import {
roomsRequest as roomsRequestAction,
closeServerDropdown as closeServerDropdownAction
} from '../../actions/rooms';
import { appStart as appStartAction } from '../../actions';
import { appStart as appStartAction, ROOT_BACKGROUND } from '../../actions/app';
import debounce from '../../utils/debounce';
import { isIOS, isAndroid, isTablet } from '../../utils/deviceInfo';
import RoomsListHeaderView from './Header';
@ -495,7 +495,7 @@ class RoomsListView extends React.Component {
this.cancelSearch();
return true;
}
appStart('background');
appStart({ root: ROOT_BACKGROUND });
return false;
};
@ -874,7 +874,7 @@ const mapDispatchToProps = dispatch => ({
toggleSortDropdown: () => dispatch(toggleSortDropdownAction()),
openSearchHeader: () => dispatch(openSearchHeaderAction()),
closeSearchHeader: () => dispatch(closeSearchHeaderAction()),
appStart: () => dispatch(appStartAction()),
appStart: params => dispatch(appStartAction(params)),
roomsRequest: params => dispatch(roomsRequestAction(params)),
selectServerRequest: server => dispatch(selectServerRequestAction(server)),
closeServerDropdown: () => dispatch(closeServerDropdownAction())

View File

@ -28,13 +28,12 @@ import styles from './styles';
import { loggerConfig, analytics } from '../../utils/log';
import { PLAY_MARKET_LINK, APP_STORE_LINK, LICENSE_LINK } from '../../constants/links';
import { withTheme } from '../../theme';
import { themedHeader } from '../../utils/navigation';
import SidebarView from '../SidebarView';
import { withSplit } from '../../split';
import Navigation from '../../lib/Navigation';
import { LISTENER } from '../../containers/Toast';
import EventEmitter from '../../utils/events';
import { appStart as appStartAction } from '../../actions';
import { appStart as appStartAction, ROOT_LOADING } from '../../actions/app';
import { onReviewPress } from '../../utils/review';
import { getUserSelector } from '../../selectors/login';
import SafeAreaView from '../../containers/SafeAreaView';
@ -99,7 +98,7 @@ class SettingsView extends React.Component {
const {
server: { server }, appStart, selectServerRequest
} = this.props;
await appStart('loading', I18n.t('Clear_cache_loading'));
await appStart({ root: ROOT_LOADING, text: I18n.t('Clear_cache_loading') });
await RocketChat.clearCache({ server });
await selectServerRequest(server, null, true);
}
@ -345,7 +344,7 @@ const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction()),
selectServerRequest: params => dispatch(selectServerRequestAction(params)),
toggleCrashReport: params => dispatch(toggleCrashReportAction(params)),
appStart: (...params) => dispatch(appStartAction(...params))
appStart: params => dispatch(appStartAction(params))
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(withSplit(SettingsView)));