Merge pull request #3179 from jitsi/reload_screen_a_catch_all
[RN] Reload screen a catch all
This commit is contained in:
commit
a5d0bfe1d4
|
@ -21,3 +21,15 @@ export const MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
|||
* @public
|
||||
*/
|
||||
export const SUSPEND_DETECTED = Symbol('SUSPEND_DETECTED');
|
||||
|
||||
/**
|
||||
* Adjust the state of the fatal error which shows/hides the reload screen. See
|
||||
* action methods's description for more info about each of the fields.
|
||||
*
|
||||
* {
|
||||
* type: SET_FATAL_ERROR,
|
||||
* fatalError: ?Object
|
||||
* }
|
||||
* @public
|
||||
*/
|
||||
export const SET_FATAL_ERROR = Symbol('SET_FATAL_ERROR');
|
||||
|
|
|
@ -3,6 +3,7 @@ import { toURLString } from '../base/util';
|
|||
|
||||
import {
|
||||
MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
||||
SET_FATAL_ERROR,
|
||||
SUSPEND_DETECTED
|
||||
} from './actionTypes';
|
||||
|
||||
|
@ -37,6 +38,8 @@ export function mediaPermissionPromptVisibilityChanged(isVisible, browser) {
|
|||
*/
|
||||
export function _reloadNow() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(setFatalError(undefined));
|
||||
|
||||
const { locationURL } = getState()['features/base/connection'];
|
||||
|
||||
logger.info(`Reloading the conference using URL: ${locationURL}`);
|
||||
|
@ -62,3 +65,22 @@ export function suspendDetected() {
|
|||
type: SUSPEND_DETECTED
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The action indicates that an unrecoverable error has occurred and the reload
|
||||
* screen will be displayed or hidden.
|
||||
*
|
||||
* @param {Object} fatalError - A critical error which was not claimed by any
|
||||
* feature for error recovery (the recoverable flag was not set). If
|
||||
* {@code undefined} then any fatal error currently stored will be discarded.
|
||||
* @returns {{
|
||||
* type: SET_FATAL_ERROR,
|
||||
* fatalError: ?Error
|
||||
* }}
|
||||
*/
|
||||
export function setFatalError(fatalError) {
|
||||
return {
|
||||
type: SET_FATAL_ERROR,
|
||||
fatalError
|
||||
};
|
||||
}
|
||||
|
|
|
@ -77,6 +77,25 @@ export default class AbstractPageReloadOverlay extends Component<*, *> {
|
|||
* {@code false}, otherwise.
|
||||
*/
|
||||
static needsRender(state: Object) {
|
||||
// FIXME web does not rely on the 'recoverable' flag set on an error
|
||||
// action, but on a predefined list of fatal errors. Because of that
|
||||
// the value of 'fatalError' which relies on the flag should not be used
|
||||
// on web yet (until conference/connection and their errors handling is
|
||||
// not unified).
|
||||
return typeof APP === 'undefined'
|
||||
? Boolean(state['features/overlay'].fatalError)
|
||||
: this.needsRenderWeb(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this overlay needs to be rendered (according to a
|
||||
* specific redux state). Called by {@link OverlayContainer}.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {boolean} - If this overlay needs to be rendered, {@code true};
|
||||
* {@code false}, otherwise.
|
||||
*/
|
||||
static needsRenderWeb(state: Object) {
|
||||
const conferenceError = state['features/base/conference'].error;
|
||||
const configError = state['features/base/config'].error;
|
||||
const connectionError = state['features/base/connection'].error;
|
||||
|
@ -273,13 +292,14 @@ export default class AbstractPageReloadOverlay extends Component<*, *> {
|
|||
* }}
|
||||
*/
|
||||
export function abstractMapStateToProps(state: Object) {
|
||||
const { error: conferenceError } = state['features/base/conference'];
|
||||
const { error: configError } = state['features/base/config'];
|
||||
const { error: connectionError } = state['features/base/connection'];
|
||||
const { fatalError } = state['features/overlay'];
|
||||
|
||||
return {
|
||||
details: connectionError ? connectionError.details : undefined,
|
||||
isNetworkFailure: Boolean(configError || connectionError),
|
||||
reason: (configError || connectionError || conferenceError).message
|
||||
details: fatalError && fatalError.details,
|
||||
isNetworkFailure:
|
||||
fatalError === configError || fatalError === connectionError,
|
||||
reason: fatalError && fatalError.message
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,10 +6,9 @@ import { appNavigate } from '../../app';
|
|||
import { translate } from '../../base/i18n';
|
||||
import { LoadingIndicator } from '../../base/react';
|
||||
|
||||
import { _reloadNow } from '../actions';
|
||||
|
||||
import AbstractPageReloadOverlay, { abstractMapStateToProps }
|
||||
from './AbstractPageReloadOverlay';
|
||||
import { _reloadNow, setFatalError } from '../actions';
|
||||
import OverlayFrame from './OverlayFrame';
|
||||
import { pageReloadOverlay as styles } from './styles';
|
||||
|
||||
|
@ -42,6 +41,7 @@ class PageReloadOverlay extends AbstractPageReloadOverlay {
|
|||
*/
|
||||
_onCancel() {
|
||||
clearInterval(this._interval);
|
||||
this.props.dispatch(setFatalError(undefined));
|
||||
this.props.dispatch(appNavigate(undefined));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * from './actions';
|
||||
export * from './components';
|
||||
|
||||
import './middleware';
|
||||
import './reducer';
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// @flow
|
||||
|
||||
import { StateListenerRegistry } from '../base/redux';
|
||||
|
||||
import { setFatalError } from './actions';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* State listener which emits the {@code fatalErrorOccurred} action which works
|
||||
* as a catch all for critical errors which have not been claimed by any other
|
||||
* feature for error recovery (the recoverable flag is not set).
|
||||
*/
|
||||
StateListenerRegistry.register(
|
||||
/* selector */ state => {
|
||||
const { error: conferenceError } = state['features/base/conference'];
|
||||
const { error: configError } = state['features/base/config'];
|
||||
const { error: connectionError } = state['features/base/connection'];
|
||||
|
||||
return configError || connectionError || conferenceError;
|
||||
},
|
||||
/* listener */ (error, { dispatch }) => {
|
||||
error
|
||||
&& typeof error.recoverable === 'undefined'
|
||||
&& dispatch(setFatalError(error));
|
||||
}
|
||||
);
|
|
@ -4,6 +4,7 @@ import { assign, ReducerRegistry, set } from '../base/redux';
|
|||
|
||||
import {
|
||||
MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
||||
SET_FATAL_ERROR,
|
||||
SUSPEND_DETECTED
|
||||
} from './actionTypes';
|
||||
|
||||
|
@ -12,11 +13,14 @@ import {
|
|||
*
|
||||
* FIXME: these pieces of state should probably be in a different place.
|
||||
*/
|
||||
ReducerRegistry.register('features/overlay', (state = {}, action) => {
|
||||
ReducerRegistry.register('features/overlay', (state = { }, action) => {
|
||||
switch (action.type) {
|
||||
case MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED:
|
||||
return _mediaPermissionPromptVisibilityChanged(state, action);
|
||||
|
||||
case SET_FATAL_ERROR:
|
||||
return _setFatalError(state, action);
|
||||
|
||||
case SUSPEND_DETECTED:
|
||||
return _suspendDetected(state);
|
||||
}
|
||||
|
@ -54,3 +58,17 @@ function _mediaPermissionPromptVisibilityChanged(
|
|||
function _suspendDetected(state) {
|
||||
return set(state, 'suspendDetected', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces a specific redux action {@code SET_FATAL_ERROR} of the feature
|
||||
* overlay.
|
||||
*
|
||||
* @param {Object} state - The redux state of the feature overlay.
|
||||
* @param {Error} fatalError - If the value is set it indicates that a fatal
|
||||
* error has occurred and that the reload screen is to be displayed.
|
||||
* @returns {Object}
|
||||
* @private
|
||||
*/
|
||||
function _setFatalError(state, { fatalError }) {
|
||||
return set(state, 'fatalError', fatalError);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue