[RN] Add conference connecting overlay
This commit is contained in:
parent
84b917d708
commit
8bb56be317
|
@ -57,6 +57,9 @@
|
||||||
},
|
},
|
||||||
"title": "Chat"
|
"title": "Chat"
|
||||||
},
|
},
|
||||||
|
"connectingOverlay": {
|
||||||
|
"joiningRoom": "Connecting you to your meeting..."
|
||||||
|
},
|
||||||
"connection": {
|
"connection": {
|
||||||
"ATTACHED": "Attached",
|
"ATTACHED": "Attached",
|
||||||
"AUTHENTICATING": "Authenticating",
|
"AUTHENTICATING": "Authenticating",
|
||||||
|
|
|
@ -55,12 +55,12 @@ export function appNavigate(uri: ?string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
location.protocol || (location.protocol = 'https:');
|
location.protocol || (location.protocol = 'https:');
|
||||||
|
const { contextRoot, host, room } = location;
|
||||||
const locationURL = new URL(location.toString());
|
const locationURL = new URL(location.toString());
|
||||||
|
|
||||||
dispatch(configWillLoad(locationURL));
|
dispatch(configWillLoad(locationURL, room));
|
||||||
|
|
||||||
let protocol = location.protocol.toLowerCase();
|
let protocol = location.protocol.toLowerCase();
|
||||||
const { contextRoot, host, room } = location;
|
|
||||||
|
|
||||||
// The React Native app supports an app-specific scheme which is sure to not
|
// The React Native app supports an app-specific scheme which is sure to not
|
||||||
// be supported by fetch.
|
// be supported by fetch.
|
||||||
|
|
|
@ -117,7 +117,7 @@ export default class BaseApp extends Component<*, State> {
|
||||||
render() {
|
render() {
|
||||||
const { route: { component }, store } = this.state;
|
const { route: { component }, store } = this.state;
|
||||||
|
|
||||||
if (store && component) {
|
if (store) {
|
||||||
return (
|
return (
|
||||||
<I18nextProvider i18n = { i18next }>
|
<I18nextProvider i18n = { i18next }>
|
||||||
<Provider store = { store }>
|
<Provider store = { store }>
|
||||||
|
@ -160,7 +160,7 @@ export default class BaseApp extends Component<*, State> {
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_createMainElement(component, props) {
|
_createMainElement(component, props) {
|
||||||
return React.createElement(component, props || {});
|
return component ? React.createElement(component, props || {}) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,10 @@ export default {
|
||||||
'LargeVideo': {
|
'LargeVideo': {
|
||||||
background: ColorPalette.black
|
background: ColorPalette.black
|
||||||
},
|
},
|
||||||
|
'LoadConfigOverlay': {
|
||||||
|
background: ColorPalette.black,
|
||||||
|
text: ColorPalette.white
|
||||||
|
},
|
||||||
'Thumbnail': {
|
'Thumbnail': {
|
||||||
activeParticipantHighlight: ColorPalette.blue,
|
activeParticipantHighlight: ColorPalette.blue,
|
||||||
activeParticipantTint: ColorPalette.black,
|
activeParticipantTint: ColorPalette.black,
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* type: CONFIG_WILL_LOAD,
|
* type: CONFIG_WILL_LOAD,
|
||||||
* locationURL: URL
|
* locationURL: URL,
|
||||||
|
* room: string
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const CONFIG_WILL_LOAD = 'CONFIG_WILL_LOAD';
|
export const CONFIG_WILL_LOAD = 'CONFIG_WILL_LOAD';
|
||||||
|
|
|
@ -15,15 +15,18 @@ import { setConfigFromURLParams } from './functions';
|
||||||
*
|
*
|
||||||
* @param {URL} locationURL - The URL of the location which necessitated the
|
* @param {URL} locationURL - The URL of the location which necessitated the
|
||||||
* loading of a configuration.
|
* loading of a configuration.
|
||||||
|
* @param {string} room - The name of the room (conference) for which we're loading the config for.
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* type: CONFIG_WILL_LOAD,
|
* type: CONFIG_WILL_LOAD,
|
||||||
* locationURL: URL
|
* locationURL: URL,
|
||||||
|
* room: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function configWillLoad(locationURL: URL) {
|
export function configWillLoad(locationURL: URL, room: string) {
|
||||||
return {
|
return {
|
||||||
type: CONFIG_WILL_LOAD,
|
type: CONFIG_WILL_LOAD,
|
||||||
locationURL
|
locationURL,
|
||||||
|
room
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,11 @@ import { ColorPalette } from '../../../styles';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the spinner.
|
||||||
|
*/
|
||||||
|
color: ?string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prop to set the size of the indicator. This is the same as the
|
* Prop to set the size of the indicator. This is the same as the
|
||||||
* prop of the native component.
|
* prop of the native component.
|
||||||
|
@ -27,6 +32,7 @@ export default class LoadingIndicator extends Component<Props> {
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
|
const { color = ColorPalette.white } = this.props;
|
||||||
let { size = 'large' } = this.props;
|
let { size = 'large' } = this.props;
|
||||||
|
|
||||||
if (size === 'medium') {
|
if (size === 'medium') {
|
||||||
|
@ -35,7 +41,7 @@ export default class LoadingIndicator extends Component<Props> {
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
animating: true,
|
animating: true,
|
||||||
color: ColorPalette.white,
|
color,
|
||||||
...this.props,
|
...this.props,
|
||||||
size
|
size
|
||||||
};
|
};
|
||||||
|
@ -43,7 +49,6 @@ export default class LoadingIndicator extends Component<Props> {
|
||||||
return (
|
return (
|
||||||
<ActivityIndicator
|
<ActivityIndicator
|
||||||
animating = { true }
|
animating = { true }
|
||||||
color = { ColorPalette.white }
|
|
||||||
{ ...props }
|
{ ...props }
|
||||||
size = { size } />
|
size = { size } />
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,16 +14,6 @@
|
||||||
export const MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
export const MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
||||||
= 'MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED';
|
= 'MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED';
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the Redux action which signals that a suspend was detected.
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* type: SUSPEND_DETECTED
|
|
||||||
* }
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export const SUSPEND_DETECTED = 'SUSPEND_DETECTED';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjust the state of the fatal error which shows/hides the reload screen. See
|
* 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.
|
* action methods's description for more info about each of the fields.
|
||||||
|
@ -35,3 +25,13 @@ export const SUSPEND_DETECTED = 'SUSPEND_DETECTED';
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export const SET_FATAL_ERROR = 'SET_FATAL_ERROR';
|
export const SET_FATAL_ERROR = 'SET_FATAL_ERROR';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the Redux action which signals that a suspend was detected.
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* type: SUSPEND_DETECTED
|
||||||
|
* }
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export const SUSPEND_DETECTED = 'SUSPEND_DETECTED';
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { SafeAreaView, Text } from 'react-native';
|
||||||
|
|
||||||
|
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||||
|
import { translate } from '../../../base/i18n';
|
||||||
|
import { LoadingIndicator } from '../../../base/react';
|
||||||
|
import { connect } from '../../../base/redux';
|
||||||
|
import { StyleType } from '../../../base/styles';
|
||||||
|
|
||||||
|
import OverlayFrame from './OverlayFrame';
|
||||||
|
import styles from './styles';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color schemed style of the component.
|
||||||
|
*/
|
||||||
|
_styles: StyleType,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Function to be invoked to translate i18n keys.
|
||||||
|
*/
|
||||||
|
t: Function
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements an overlay to tell the user that there is an operation in progress in the background during connect
|
||||||
|
* so then the app doesn't seem hung.
|
||||||
|
*/
|
||||||
|
class LoadConfigOverlay extends Component<Props> {
|
||||||
|
/**
|
||||||
|
* 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 needsRender(state: Object) {
|
||||||
|
return Boolean(state['features/overlay'].loadConfigOverlayVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements React's {@link Component#render()}.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {ReactElement}
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { _styles } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayFrame>
|
||||||
|
<SafeAreaView
|
||||||
|
style = { [
|
||||||
|
styles.loadingOverlayWrapper,
|
||||||
|
_styles.loadingOverlayWrapper
|
||||||
|
] }>
|
||||||
|
<LoadingIndicator
|
||||||
|
color = { _styles.indicatorColor }
|
||||||
|
size = 'large'
|
||||||
|
style = { styles.connectIndicator } />
|
||||||
|
<Text
|
||||||
|
style = { [
|
||||||
|
styles.loadingOverlayText,
|
||||||
|
_styles.loadingOverlayText
|
||||||
|
] }>
|
||||||
|
{ this.props.t('connectingOverlay.joiningRoom') }
|
||||||
|
</Text>
|
||||||
|
</SafeAreaView>
|
||||||
|
</OverlayFrame>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps part of the Redux state to the props of this component.
|
||||||
|
*
|
||||||
|
* @param {Object} state - The Redux state.
|
||||||
|
* @returns {{
|
||||||
|
* _styles: StyleType
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
|
function _mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
_styles: ColorSchemeRegistry.get(state, 'LoadConfigOverlay')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default translate(connect(_mapStateToProps)(LoadConfigOverlay));
|
|
@ -3,7 +3,7 @@
|
||||||
import React, { Component, type Node } from 'react';
|
import React, { Component, type Node } from 'react';
|
||||||
import { SafeAreaView, View } from 'react-native';
|
import { SafeAreaView, View } from 'react-native';
|
||||||
|
|
||||||
import { overlayFrame as styles } from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@code OverlayFrame}.
|
* The type of the React {@code Component} props of {@code OverlayFrame}.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
export { default as LoadConfigOverlay } from './LoadConfigOverlay';
|
||||||
export { default as OverlayFrame } from './OverlayFrame';
|
export { default as OverlayFrame } from './OverlayFrame';
|
||||||
export { default as PageReloadOverlay } from './PageReloadOverlay';
|
export { default as PageReloadOverlay } from './PageReloadOverlay';
|
||||||
|
|
|
@ -2,12 +2,17 @@
|
||||||
|
|
||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
import { ColorPalette } from '../../../base/styles';
|
import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
|
||||||
|
import { BoxModel, ColorPalette } from '../../../base/styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The React {@code Component} styles of {@code OverlayFrame}.
|
* The React {@code Component} styles of the overlay feature.
|
||||||
*/
|
*/
|
||||||
export const overlayFrame = createStyleSheet({
|
export default {
|
||||||
|
connectIndicator: {
|
||||||
|
margin: BoxModel.margin
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Style for a backdrop overlay covering the screen the the overlay is
|
* Style for a backdrop overlay covering the screen the the overlay is
|
||||||
* rendered.
|
* rendered.
|
||||||
|
@ -17,7 +22,33 @@ export const overlayFrame = createStyleSheet({
|
||||||
backgroundColor: ColorPalette.black
|
backgroundColor: ColorPalette.black
|
||||||
},
|
},
|
||||||
|
|
||||||
|
loadingOverlayText: {
|
||||||
|
color: ColorPalette.white
|
||||||
|
},
|
||||||
|
|
||||||
|
loadingOverlayWrapper: {
|
||||||
|
alignItems: 'center',
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
|
||||||
safeContainer: {
|
safeContainer: {
|
||||||
flex: 1
|
flex: 1
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color schemed styles for all the component based on the abstract dialog.
|
||||||
|
*/
|
||||||
|
ColorSchemeRegistry.register('LoadConfigOverlay', {
|
||||||
|
indicatorColor: schemeColor('text'),
|
||||||
|
|
||||||
|
loadingOverlayText: {
|
||||||
|
color: schemeColor('text')
|
||||||
|
},
|
||||||
|
|
||||||
|
loadingOverlayWrapper: {
|
||||||
|
backgroundColor: schemeColor('background')
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,49 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import {
|
import { getOverlays } from './overlays';
|
||||||
PageReloadFilmstripOnlyOverlay,
|
|
||||||
PageReloadOverlay,
|
|
||||||
SuspendedFilmstripOnlyOverlay,
|
|
||||||
SuspendedOverlay,
|
|
||||||
UserMediaPermissionsFilmstripOnlyOverlay,
|
|
||||||
UserMediaPermissionsOverlay
|
|
||||||
} from './components';
|
|
||||||
|
|
||||||
declare var interfaceConfig: Object;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of available overlays that might be rendered.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @returns {Array<?React$ComponentType<*>>}
|
|
||||||
*/
|
|
||||||
function _getOverlays() {
|
|
||||||
const filmstripOnly
|
|
||||||
= typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly;
|
|
||||||
let overlays;
|
|
||||||
|
|
||||||
if (filmstripOnly) {
|
|
||||||
overlays = [
|
|
||||||
PageReloadFilmstripOnlyOverlay,
|
|
||||||
SuspendedFilmstripOnlyOverlay,
|
|
||||||
UserMediaPermissionsFilmstripOnlyOverlay
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
overlays = [
|
|
||||||
PageReloadOverlay
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mobile only has a PageReloadOverlay.
|
|
||||||
if (navigator.product !== 'ReactNative') {
|
|
||||||
overlays.push(...[
|
|
||||||
SuspendedOverlay,
|
|
||||||
UserMediaPermissionsOverlay
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return overlays;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the overlay to be currently rendered.
|
* Returns the overlay to be currently rendered.
|
||||||
|
@ -52,7 +9,7 @@ function _getOverlays() {
|
||||||
* @returns {?React$ComponentType<*>}
|
* @returns {?React$ComponentType<*>}
|
||||||
*/
|
*/
|
||||||
export function getOverlayToRender(state: Object) {
|
export function getOverlayToRender(state: Object) {
|
||||||
for (const overlay of _getOverlays()) {
|
for (const overlay of getOverlays()) {
|
||||||
// react-i18n / react-redux wrap components and thus we cannot access
|
// react-i18n / react-redux wrap components and thus we cannot access
|
||||||
// the wrapped component's static methods directly.
|
// the wrapped component's static methods directly.
|
||||||
const component = overlay.WrappedComponent || overlay;
|
const component = overlay.WrappedComponent || overlay;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import {
|
||||||
|
LoadConfigOverlay,
|
||||||
|
PageReloadOverlay
|
||||||
|
} from './components/native';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of available platform specific overlays.
|
||||||
|
*
|
||||||
|
* @returns {Array<React$Element>}
|
||||||
|
*/
|
||||||
|
export function getOverlays(): Array<React$Element<*>> {
|
||||||
|
return [
|
||||||
|
LoadConfigOverlay,
|
||||||
|
PageReloadOverlay
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import {
|
||||||
|
PageReloadFilmstripOnlyOverlay,
|
||||||
|
PageReloadOverlay,
|
||||||
|
SuspendedFilmstripOnlyOverlay,
|
||||||
|
SuspendedOverlay,
|
||||||
|
UserMediaPermissionsFilmstripOnlyOverlay,
|
||||||
|
UserMediaPermissionsOverlay
|
||||||
|
} from './components/web';
|
||||||
|
|
||||||
|
declare var interfaceConfig: Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of available platform specific overlays.
|
||||||
|
*
|
||||||
|
* @returns {Array<Object>}
|
||||||
|
*/
|
||||||
|
export function getOverlays(): Array<Object> {
|
||||||
|
const overlays = [
|
||||||
|
SuspendedOverlay,
|
||||||
|
UserMediaPermissionsOverlay
|
||||||
|
];
|
||||||
|
|
||||||
|
const filmstripOnly
|
||||||
|
= typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly;
|
||||||
|
|
||||||
|
if (filmstripOnly) {
|
||||||
|
overlays.push(
|
||||||
|
PageReloadFilmstripOnlyOverlay,
|
||||||
|
SuspendedFilmstripOnlyOverlay,
|
||||||
|
UserMediaPermissionsFilmstripOnlyOverlay);
|
||||||
|
} else {
|
||||||
|
overlays.push(PageReloadOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
return overlays;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from '../base/config';
|
||||||
import { assign, ReducerRegistry, set } from '../base/redux';
|
import { assign, ReducerRegistry, set } from '../base/redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -15,6 +16,13 @@ import {
|
||||||
*/
|
*/
|
||||||
ReducerRegistry.register('features/overlay', (state = { }, action) => {
|
ReducerRegistry.register('features/overlay', (state = { }, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
case CONFIG_WILL_LOAD:
|
||||||
|
return _setShowLoadConfigOverlay(state, Boolean(action.room));
|
||||||
|
|
||||||
|
case LOAD_CONFIG_ERROR:
|
||||||
|
case SET_CONFIG:
|
||||||
|
return _setShowLoadConfigOverlay(false);
|
||||||
|
|
||||||
case MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED:
|
case MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED:
|
||||||
return _mediaPermissionPromptVisibilityChanged(state, action);
|
return _mediaPermissionPromptVisibilityChanged(state, action);
|
||||||
|
|
||||||
|
@ -48,15 +56,15 @@ function _mediaPermissionPromptVisibilityChanged(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces a specific redux action SUSPEND_DETECTED of the feature overlay.
|
* Sets the {@code LoadConfigOverlay} overlay visible or not.
|
||||||
*
|
*
|
||||||
* @param {Object} state - The redux state of the feature overlay.
|
* @param {Object} state - The redux state of the feature overlay.
|
||||||
* @private
|
* @param {boolean} show - Whether to show or not the overlay.
|
||||||
* @returns {Object} The new state of the feature overlay after the reduction of
|
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||||
* the specified action.
|
* the specified action.
|
||||||
*/
|
*/
|
||||||
function _suspendDetected(state) {
|
function _setShowLoadConfigOverlay(state, show) {
|
||||||
return set(state, 'suspendDetected', true);
|
return set(state, 'loadConfigOverlayVisible', show);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,3 +80,15 @@ function _suspendDetected(state) {
|
||||||
function _setFatalError(state, { fatalError }) {
|
function _setFatalError(state, { fatalError }) {
|
||||||
return set(state, 'fatalError', fatalError);
|
return set(state, 'fatalError', fatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduces a specific redux action SUSPEND_DETECTED of the feature overlay.
|
||||||
|
*
|
||||||
|
* @param {Object} state - The redux state of the feature overlay.
|
||||||
|
* @private
|
||||||
|
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||||
|
* the specified action.
|
||||||
|
*/
|
||||||
|
function _suspendDetected(state) {
|
||||||
|
return set(state, 'suspendDetected', true);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue