[RN] Reduce authentication actions

This commit is contained in:
Lyubo Marinov 2017-09-24 18:41:20 -05:00
parent 9ae26a087e
commit 266d8f72c5
5 changed files with 77 additions and 57 deletions

View File

@ -38,22 +38,13 @@ export const STOP_WAIT_FOR_OWNER = Symbol('STOP_WAIT_FOR_OWNER');
*
* {
* type: UPGRADE_ROLE_FINISHED,
* error: Object
* error: Object,
* progress: number,
* thenableWithCancel: Object
* }
*/
export const UPGRADE_ROLE_FINISHED = Symbol('UPGRADE_ROLE_FINISHED');
/**
* The type of (redux) action which informs that the authentication and role
* upgrade process has finished the XMPP authentication part of the process
* (which means that the XMPP credentials are OK).
*
* {
* type: UPGRADE_ROLE_LOGIN_ON
* }
*/
export const UPGRADE_ROLE_LOGIN_OK = Symbol('UPGRADE_ROLE_LOGIN_OK');
/**
* The type of (redux) action which signals that the process of authenticating
* and upgrading the local participant's role has been started.

View File

@ -8,7 +8,6 @@ import {
CANCEL_WAIT_FOR_OWNER,
STOP_WAIT_FOR_OWNER,
UPGRADE_ROLE_FINISHED,
UPGRADE_ROLE_LOGIN_OK,
UPGRADE_ROLE_STARTED,
WAIT_FOR_OWNER
} from './actionTypes';
@ -42,20 +41,22 @@ export function authenticateAndUpgradeRole(
roomPassword,
onLoginSuccessful() {
return dispatch({ type: UPGRADE_ROLE_LOGIN_OK });
// When the login succeeds, the process has completed half
// of its job (i.e. 0.5).
return dispatch(_upgradeRoleFinished(process, 0.5));
}
});
dispatch(_upgradeRoleStarted(process));
process.then(
/* onFulfilled */ () => dispatch(_upgradeRoleFinished()),
/* onFulfilled */ () => dispatch(_upgradeRoleFinished(process, 1)),
/* onRejected */ error => {
// The lack of an error signals a cancellation.
if (error.authenticationError || error.connectionError) {
logger.error('authenticateAndUpgradeRole failed', error);
}
dispatch(_upgradeRoleFinished(error));
dispatch(_upgradeRoleFinished(process, error));
});
return process;
@ -126,36 +127,49 @@ export function stopWaitForOwner() {
* Signals that the process of authenticating and upgrading the local
* participant's role has finished either with success or with a specific error.
*
* @param {Object} error - If <tt>undefined</tt>, then the process of
* authenticating and upgrading the local participant's role has succeeded;
* otherwise, it has failed with the specified error. Refer to
* {@link JitsiConference#authenticateAndUpgradeRole} in lib-jitsi-meet for the
* error details.
* @param {Object} thenableWithCancel - The process of authenticating and
* upgrading the local participant's role.
* @param {Object} progressOrError - If the value is a <tt>number</tt>, then the
* process of authenticating and upgrading the local participant's role has
* succeeded in one of its two/multiple steps; otherwise, it has failed with the
* specified error. Refer to {@link JitsiConference#authenticateAndUpgradeRole}
* in lib-jitsi-meet for the error details.
* @private
* @returns {{
* type: UPGRADE_ROLE_FINISHED,
* error: ?Object
* error: ?Object,
* progress: number
* }}
*/
function _upgradeRoleFinished(error: ?Object) {
if (error) {
function _upgradeRoleFinished(
thenableWithCancel,
progressOrError: number | Object) {
let error;
let progress;
if (typeof progressOrError === 'number') {
progress = progressOrError;
} else {
// Make the specified error object resemble an Error instance (to the
// extent that jitsi-meet needs it).
const {
authenticationError,
connectionError,
...other
} = error;
} = progressOrError;
error = { // eslint-disable-line no-param-reassign
error = {
name: authenticationError || connectionError,
...other
};
progress = authenticationError ? 0.5 : 0;
}
return {
type: UPGRADE_ROLE_FINISHED,
error
error,
progress,
thenableWithCancel
};
}

View File

@ -67,11 +67,10 @@ class LoginDialog extends Component {
_error: PropTypes.object,
/**
* Flag indicates that during the "upgrade role and authenticate"
* process the login part was successful and the next step is to obtain
* a session ID from Jicofo.
* The progress in the floating range between 0 and 1 of the
* authenticating and upgrading the role of the local participant/user.
*/
_upgradeRoleLoginOk: PropTypes.bool,
_progress: PropTypes.number,
/**
* Redux store dispatch method.
@ -115,14 +114,14 @@ class LoginDialog extends Component {
const {
_connecting: connecting,
_error: error,
_upgradeRoleLoginOk: upgradeRoleLoginOk,
_progress: progress,
t
} = this.props;
let messageKey;
let messageOptions;
if (upgradeRoleLoginOk) {
if (progress && progress < 1) {
messageKey = 'connection.FETCH_SESSION_ID';
} else if (error) {
const { name } = error;
@ -254,14 +253,14 @@ class LoginDialog extends Component {
* _configHosts: Object,
* _connecting: boolean,
* _error: Object,
* _upgradeRoleLoginOk: boolean
* _progress: number
* }}
*/
function _mapStateToProps(state) {
const {
upgradeRoleError,
upgradeRoleInProgress,
upgradeRoleLoginOk
error: authenticateAndUpgradeRoleError,
progress,
thenableWithCancel
} = state['features/authentication'];
const { authRequired } = state['features/base/conference'];
const { hosts: configHosts } = state['features/base/config'];
@ -273,9 +272,9 @@ function _mapStateToProps(state) {
return {
_conference: authRequired,
_configHosts: configHosts,
_connecting: Boolean(connecting) || Boolean(upgradeRoleInProgress),
_error: connectionError || upgradeRoleError,
_upgradeRoleLoginOk: upgradeRoleLoginOk
_connecting: Boolean(connecting) || Boolean(thenableWithCancel),
_error: connectionError || authenticateAndUpgradeRoleError,
_progress: progress
};
}

View File

@ -38,10 +38,10 @@ import { LoginDialog, WaitForOwnerDialog } from './components';
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case CANCEL_LOGIN: {
const { upgradeRoleInProgress }
const { thenableWithCancel }
= store.getState()['features/authentication'];
upgradeRoleInProgress && upgradeRoleInProgress.cancel();
thenableWithCancel && thenableWithCancel.cancel();
// The LoginDialog can be opened on top of "wait for owner". The app
// should navigate only if LoginDialog was open without the
@ -117,7 +117,7 @@ MiddlewareRegistry.register(store => next => action => {
action.waitForOwnerTimeoutID = setTimeout(handler, timeoutMs);
// The WAIT_FOR_OWNER action is cyclic and we don't want to hide the
// login dialog every few seconds...
// login dialog every few seconds.
isDialogOpen(store, LoginDialog)
|| store.dispatch(_openWaitForOwnerDialog());
break;

View File

@ -6,7 +6,6 @@ import {
CANCEL_LOGIN,
STOP_WAIT_FOR_OWNER,
UPGRADE_ROLE_FINISHED,
UPGRADE_ROLE_LOGIN_OK,
UPGRADE_ROLE_STARTED,
WAIT_FOR_OWNER
} from './actionTypes';
@ -15,28 +14,45 @@ ReducerRegistry.register('features/authentication', (state = {}, action) => {
switch (action.type) {
case CANCEL_LOGIN:
return assign(state, {
upgradeRoleError: undefined,
upgradeRoleInProgress: undefined,
upgradeRoleLoginOk: false
error: undefined,
progress: undefined,
thenableWithCancel: undefined
});
case STOP_WAIT_FOR_OWNER:
return assign(state, {
upgradeRoleError: undefined,
error: undefined,
waitForOwnerTimeoutID: undefined
});
case UPGRADE_ROLE_FINISHED:
case UPGRADE_ROLE_FINISHED: {
let { thenableWithCancel } = action;
if (state.thenableWithCancel === thenableWithCancel) {
const { error, progress } = action;
// An error interrupts the process of authenticating and upgrading
// the role of the local participant/user i.e. the process is no
// more. Obviously, the process seizes to exist also when it does
// its whole job.
if (error || progress === 1) {
thenableWithCancel = undefined;
}
return assign(state, {
error,
progress: progress || undefined,
thenableWithCancel
});
}
break;
}
case UPGRADE_ROLE_STARTED:
return assign(state, {
upgradeRoleError: action.error,
upgradeRoleInProgress: action.thenableWithCancel,
upgradeRoleLoginOk: false
});
case UPGRADE_ROLE_LOGIN_OK:
return assign(state, {
upgradeRoleLoginOk: true
error: undefined,
progress: undefined,
thenableWithCancel: action.thenableWithCancel
});
case WAIT_FOR_OWNER: