From 38629b437de5d046790a11c38542f3c4153d7eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Thu, 9 Nov 2017 14:34:42 +0100 Subject: [PATCH] feat(overlays): refactor logic for selecting current overlay Do the selection in mapStateToProps so the container itself doesn't need to receive all the props that each overlay needs. Each overlay is responsible for fetching their own props and for providing a "needsDisplay" static method wich will be called with the full redux state and should return true if the overlay needs displaying. Also eliminate duplicated state keeping: the connection and conference error states can be fetched from their respective base features. --- .../base/jwt/components/CallOverlay.js | 12 + .../features/base/lib-jitsi-meet/functions.js | 27 +- .../components/AbstractPageReloadOverlay.js | 43 +++ .../components/AbstractSuspendedOverlay.js | 45 +++ .../AbstractUserMediaPermissionsOverlay.js | 72 +++++ .../overlay/components/OverlayContainer.js | 283 ++++-------------- .../PageReloadFilmstripOnlyOverlay.js | 6 +- .../overlay/components/PageReloadOverlay.js | 5 +- .../SuspendedFilmstripOnlyOverlay.js | 22 +- .../overlay/components/SuspendedOverlay.js | 22 +- ...serMediaPermissionsFilmstripOnlyOverlay.js | 37 +-- .../components/UserMediaPermissionsOverlay.js | 38 +-- react/features/overlay/reducer.js | 120 +------- 13 files changed, 288 insertions(+), 444 deletions(-) create mode 100644 react/features/overlay/components/AbstractSuspendedOverlay.js create mode 100644 react/features/overlay/components/AbstractUserMediaPermissionsOverlay.js diff --git a/react/features/base/jwt/components/CallOverlay.js b/react/features/base/jwt/components/CallOverlay.js index 9e55ad4fa..fe0cfab96 100644 --- a/react/features/base/jwt/components/CallOverlay.js +++ b/react/features/base/jwt/components/CallOverlay.js @@ -77,6 +77,18 @@ class CallOverlay extends Component<*, *> { _callee: PropTypes.object }; + /** + * Check if this overlay needs to be rendered. This function will be called + * by the {@code OverlayContainer}. + * + * @param {Object} state - The redux state. + * @returns {boolean} - True if this overlay needs to be rendered, false + * otherwise. + */ + static needsRender(state) { + return state['features/base/jwt'].callOverlayVisible; + } + /** * Initializes a new {@code CallOverlay} instance. * diff --git a/react/features/base/lib-jitsi-meet/functions.js b/react/features/base/lib-jitsi-meet/functions.js index 8c76ba0ef..4facaffda 100644 --- a/react/features/base/lib-jitsi-meet/functions.js +++ b/react/features/base/lib-jitsi-meet/functions.js @@ -8,6 +8,7 @@ import JitsiMeetJS from './_'; declare var APP: Object; +const JitsiConferenceErrors = JitsiMeetJS.errors.conference; const JitsiConnectionErrors = JitsiMeetJS.errors.connection; /** @@ -52,11 +53,35 @@ export function isAnalyticsEnabled(stateful: Function | Object) { && Boolean(analyticsScriptUrls.length)); } +/** + * Determines whether a specific JitsiConferenceErrors instance indicates a + * fatal JitsiConference error. + * + * FIXME Figure out the category of errors defined by the function and describe + * that category. I've currently named the category fatal because it appears to + * be used in the cases of unrecoverable errors that necessitate a reload. + * + * @param {Object|string} error - The JitsiConferenceErrors instance to + * categorize/classify or an Error-like object. + * @returns {boolean} True if the specified JitsiConferenceErrors instance + * indicates a fatal JitsiConference error; otherwise, false. + */ +export function isFatalJitsiConferenceError(error: Object | string) { + if (typeof error !== 'string') { + error = error.name; // eslint-disable-line no-param-reassign + } + + return ( + error === JitsiConferenceErrors.FOCUS_DISCONNECTED + || error === JitsiConferenceErrors.FOCUS_LEFT + || error === JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE); +} + /** * Determines whether a specific JitsiConnectionErrors instance indicates a * fatal JitsiConnection error. * - * FIXME Figure out the category of errors defined by the fucntion and describe + * FIXME Figure out the category of errors defined by the function and describe * that category. I've currently named the category fatal because it appears to * be used in the cases of unrecoverable errors that necessitate a reload. * diff --git a/react/features/overlay/components/AbstractPageReloadOverlay.js b/react/features/overlay/components/AbstractPageReloadOverlay.js index 721f12375..b8cdc14ff 100644 --- a/react/features/overlay/components/AbstractPageReloadOverlay.js +++ b/react/features/overlay/components/AbstractPageReloadOverlay.js @@ -3,6 +3,10 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import { + isFatalJitsiConferenceError, + isFatalJitsiConnectionError +} from '../../base/lib-jitsi-meet'; import { randomInt } from '../../base/util'; import { _reloadNow } from '../actions'; @@ -85,6 +89,25 @@ export default class AbstractPageReloadOverlay extends Component<*, *> { title: string } + /** + * Check if this overlay needs to be rendered. This function will be called + * by the {@code OverlayContainer}. + * + * @param {Object} state - The redux state. + * @returns {boolean} - True if this overlay needs to be rendered, false + * otherwise. + */ + static needsRender(state) { + const conferenceError = state['features/base/conference'].error; + const connectionError = state['features/base/connection'].error; + + return ( + (connectionError && isFatalJitsiConnectionError(connectionError)) + || (conferenceError + && isFatalJitsiConferenceError(conferenceError)) + ); + } + /** * Initializes a new AbstractPageReloadOverlay instance. * @@ -215,3 +238,23 @@ export default class AbstractPageReloadOverlay extends Component<*, *> { ); } } + +/** + * Maps (parts of) the redux state to the associated component's props. + * + * @param {Object} state - The redux state. + * @returns {{ + * isNetworkFailure: boolean, + * reason: string + * }} + * @protected + */ +export function abstractMapStateToProps(state: Object) { + const conferenceError = state['features/base/conference'].error; + const connectionError = state['features/base/connection'].error; + + return { + isNetworkFailure: Boolean(connectionError), + reason: (connectionError || conferenceError).message + }; +} diff --git a/react/features/overlay/components/AbstractSuspendedOverlay.js b/react/features/overlay/components/AbstractSuspendedOverlay.js new file mode 100644 index 000000000..1acb17392 --- /dev/null +++ b/react/features/overlay/components/AbstractSuspendedOverlay.js @@ -0,0 +1,45 @@ +import PropTypes from 'prop-types'; +import { Component } from 'react'; + +/** + * Implements a React Component for suspended overlay. Shown when a suspend is + * detected. + */ +export default class AbstractSuspendedOverlay extends Component { + /** + * SuspendedOverlay component's property types. + * + * @static + */ + static propTypes = { + /** + * The function to translate human-readable text. + * + * @public + * @type {Function} + */ + t: PropTypes.func + }; + + /** + * Check if this overlay needs to be rendered. This function will be called + * by the {@code OverlayContainer}. + * + * @param {Object} state - The redux state. + * @returns {boolean} - True if this overlay needs to be rendered, false + * otherwise. + */ + static needsRender(state) { + return state['features/overlay'].suspendDetected; + } + + /** + * Implements React's {@link Component#render()}. + * + * @inheritdoc + * @returns {ReactElement|null} + */ + render() { + return null; + } +} diff --git a/react/features/overlay/components/AbstractUserMediaPermissionsOverlay.js b/react/features/overlay/components/AbstractUserMediaPermissionsOverlay.js new file mode 100644 index 000000000..40177f57b --- /dev/null +++ b/react/features/overlay/components/AbstractUserMediaPermissionsOverlay.js @@ -0,0 +1,72 @@ +import PropTypes from 'prop-types'; +import { Component } from 'react'; + + +/** + * Implements a React Component for overlay with guidance how to proceed with + * gUM prompt. + */ +export default class AbstractUserMediaPermissionsOverlay extends Component { + /** + * UserMediaPermissionsOverlay component's property types. + * + * @static + */ + static propTypes = { + /** + * The browser which is used currently. The text is different for every + * browser. + * + * @public + * @type {string} + */ + browser: PropTypes.string, + + /** + * The function to translate human-readable text. + * + * @public + * @type {Function} + */ + t: PropTypes.func + }; + + /** + * Check if this overlay needs to be rendered. This function will be called + * by the {@code OverlayContainer}. + * + * @param {Object} state - The redux state. + * @returns {boolean} - True if this overlay needs to be rendered, false + * otherwise. + */ + static needsRender(state) { + return state['features/overlay'].isMediaPermissionPromptVisible; + } + + /** + * Implements React's {@link Component#render()}. + * + * @inheritdoc + * @returns {ReactElement|null} + */ + render() { + return null; + } +} + +/** + * Maps (parts of) the redux state to the associated component's props. + * + * @param {Object} state - The redux state. + * @returns {{ + * browser: string + * }} + * @protected + */ +export function abstractMapStateToProps(state) { + const { browser } = state['features/overlay']; + + return { + browser + }; +} diff --git a/react/features/overlay/components/OverlayContainer.js b/react/features/overlay/components/OverlayContainer.js index fd48ccc9d..44729c8ed 100644 --- a/react/features/overlay/components/OverlayContainer.js +++ b/react/features/overlay/components/OverlayContainer.js @@ -14,6 +14,42 @@ import UserMediaPermissionsFilmstripOnlyOverlay from './UserMediaPermissionsFilmstripOnlyOverlay'; import UserMediaPermissionsOverlay from './UserMediaPermissionsOverlay'; +/** + * Reference to the lazily loaded list of overlays. + */ +let _overlays; + +/** + * Returns the list of overlays which can be rendered by this container. The + * list is lazily loaded the first time it's required. + * + * @returns {Array} - The list of overlay types which are available. + */ +function getOverlays() { + if (typeof _overlays === 'undefined') { + const filmstripOnly + = typeof interfaceConfig === 'object' + && interfaceConfig.filmStripOnly; + + if (filmstripOnly) { + _overlays = [ + PageReloadFilmstripOnlyOverlay, + SuspendedFilmstripOnlyOverlay, + UserMediaPermissionsFilmstripOnlyOverlay + ]; + } else { + _overlays = [ + PageReloadOverlay, + SuspendedOverlay, + UserMediaPermissionsOverlay, + CallOverlay + ]; + } + } + + return _overlays; +} + /** * Implements a React Component that will display the correct overlay when * needed. @@ -26,113 +62,11 @@ class OverlayContainer extends Component { */ static propTypes = { /** - * The browser which is used currently. - * - * NOTE: Used by UserMediaPermissionsOverlay only. - * - * @private - * @type {string} + * Type of overlay that should be rendered. */ - _browser: PropTypes.string, - - /** - * The indicator which determines whether the {@link CallOverlay} is - * displayed/visible. - * - * @private - * @type {boolean} - */ - _callOverlayVisible: PropTypes.bool, - - /** - * The indicator which determines whether the status of the - * JitsiConnection object has been "established" or not. - * - * NOTE: Used by PageReloadOverlay only. - * - * @private - * @type {boolean} - */ - _connectionEstablished: PropTypes.bool, - - /** - * The indicator which determines whether a critical error for reload - * has been received. - * - * NOTE: Used by PageReloadOverlay only. - * - * @private - * @type {boolean} - */ - _haveToReload: PropTypes.bool, - - /** - * The indicator which determines whether the GUM permissions prompt is - * displayed or not. - * - * NOTE: Used by UserMediaPermissionsOverlay only. - * - * @private - * @type {boolean} - */ - _isMediaPermissionPromptVisible: PropTypes.bool, - - /** - * The indicator which determines whether the reload was caused by - * network failure. - * - * NOTE: Used by PageReloadOverlay only. - * - * @private - * @type {boolean} - */ - _isNetworkFailure: PropTypes.bool, - - /** - * The reason for the error that will cause the reload. - * - * NOTE: Used by PageReloadOverlay only. - * - * @private - * @type {string} - */ - _reason: PropTypes.string, - - /** - * The indicator which determines whether the GUM permissions prompt is - * displayed or not. - * - * NOTE: Used by SuspendedOverlay only. - * - * @private - * @type {string} - */ - _suspendDetected: PropTypes.bool + overlay: PropTypes.element }; - /** - * Initializes a new OverlayContainer instance. - * - * @param {Object} props - The read-only properties with which the new - * instance is to be initialized. - * @public - */ - constructor(props) { - super(props); - - this.state = { - /** - * The indicator which determines whether filmstrip-only mode is - * enabled. - * - * @type {boolean} - */ - filmstripOnly: - typeof interfaceConfig === 'object' - && interfaceConfig.filmStripOnly - }; - } - /** * Implements React's {@link Component#render()}. * @@ -141,39 +75,9 @@ class OverlayContainer extends Component { * @public */ render() { - const { filmstripOnly } = this.state; - let overlayComponent, props; + const { overlay } = this.props; - if (this.props._connectionEstablished && this.props._haveToReload) { - overlayComponent - = filmstripOnly - ? PageReloadFilmstripOnlyOverlay - : PageReloadOverlay; - props = { - isNetworkFailure: this.props._isNetworkFailure, - reason: this.props._reason - }; - } else if (this.props._suspendDetected) { - overlayComponent - = filmstripOnly - ? SuspendedFilmstripOnlyOverlay - : SuspendedOverlay; - } else if (this.props._isMediaPermissionPromptVisible) { - overlayComponent - = filmstripOnly - ? UserMediaPermissionsFilmstripOnlyOverlay - : UserMediaPermissionsOverlay; - props = { - browser: this.props._browser - }; - } else if (this.props._callOverlayVisible) { - overlayComponent = CallOverlay; - } - - return ( - overlayComponent - ? React.createElement(overlayComponent, props) - : null); + return overlay ? React.createElement(overlay, {}) : null; } } @@ -182,106 +86,29 @@ class OverlayContainer extends Component { * * @param {Object} state - The redux state. * @returns {{ - * _browser: string, - * _callOverlayVisible: boolean, - * _connectionEstablished: boolean, - * _haveToReload: boolean, - * _isNetworkFailure: boolean, - * _isMediaPermissionPromptVisible: boolean, - * _reason: string, - * _suspendDetected: boolean + * overlay: ?Object * }} * @private */ function _mapStateToProps(state) { - const stateFeaturesOverlay = state['features/overlay']; + let overlay; + + for (const o of getOverlays()) { + // react-i18n / react-redux wrap components and thus we cannot access + // the wrapped component's static methods directly. + const component = o.WrappedComponent || o; + + if (component.needsRender(state)) { + overlay = o; + break; + } + } return { /** - * The browser which is used currently. - * - * NOTE: Used by {@link UserMediaPermissionsOverlay} only. - * - * @private - * @type {string} + * Type of overlay that should be rendered. */ - _browser: stateFeaturesOverlay.browser, - - /** - * The indicator which determines whether the {@link CallOverlay} is - * displayed/visible. - * - * @private - * @type {boolean} - */ - _callOverlayVisible: - Boolean(state['features/base/jwt'].callOverlayVisible), - - /** - * The indicator which determines whether the status of the - * JitsiConnection object has been "established" or not. - * - * NOTE: Used by {@link PageReloadOverlay} only. - * - * @private - * @type {boolean} - */ - _connectionEstablished: stateFeaturesOverlay.connectionEstablished, - - /** - * The indicator which determines whether a critical error for reload - * has been received. - * - * NOTE: Used by {@link PageReloadOverlay} only. - * - * @private - * @type {boolean} - */ - _haveToReload: stateFeaturesOverlay.haveToReload, - - /** - * The indicator which determines whether the GUM permissions prompt is - * displayed or not. - * - * NOTE: Used by {@link UserMediaPermissionsOverlay} only. - * - * @private - * @type {boolean} - */ - _isMediaPermissionPromptVisible: - stateFeaturesOverlay.isMediaPermissionPromptVisible, - - /** - * The indicator which determines whether the reload was caused by - * network failure. - * - * NOTE: Used by {@link PageReloadOverlay} only. - * - * @private - * @type {boolean} - */ - _isNetworkFailure: stateFeaturesOverlay.isNetworkFailure, - - /** - * The reason for the error that will cause the reload. - * - * NOTE: Used by {@link PageReloadOverlay} only. - * - * @private - * @type {string} - */ - _reason: stateFeaturesOverlay.reason, - - /** - * The indicator which determines whether the GUM permissions prompt is - * displayed or not. - * - * NOTE: Used by {@link SuspendedOverlay} only. - * - * @private - * @type {string} - */ - _suspendDetected: stateFeaturesOverlay.suspendDetected + overlay }; } diff --git a/react/features/overlay/components/PageReloadFilmstripOnlyOverlay.js b/react/features/overlay/components/PageReloadFilmstripOnlyOverlay.js index eb70fd10c..9b00d0d24 100644 --- a/react/features/overlay/components/PageReloadFilmstripOnlyOverlay.js +++ b/react/features/overlay/components/PageReloadFilmstripOnlyOverlay.js @@ -3,7 +3,8 @@ import { connect } from 'react-redux'; import { translate } from '../../base/i18n'; -import AbstractPageReloadOverlay from './AbstractPageReloadOverlay'; +import AbstractPageReloadOverlay, { abstractMapStateToProps } + from './AbstractPageReloadOverlay'; import FilmstripOnlyOverlayFrame from './FilmstripOnlyOverlayFrame'; /** @@ -39,4 +40,5 @@ class PageReloadFilmstripOnlyOverlay extends AbstractPageReloadOverlay { } } -export default translate(connect()(PageReloadFilmstripOnlyOverlay)); +export default translate( + connect(abstractMapStateToProps)(PageReloadFilmstripOnlyOverlay)); diff --git a/react/features/overlay/components/PageReloadOverlay.js b/react/features/overlay/components/PageReloadOverlay.js index 46f36b43a..cca6b70d3 100644 --- a/react/features/overlay/components/PageReloadOverlay.js +++ b/react/features/overlay/components/PageReloadOverlay.js @@ -3,7 +3,8 @@ import { connect } from 'react-redux'; import { translate } from '../../base/i18n'; -import AbstractPageReloadOverlay from './AbstractPageReloadOverlay'; +import AbstractPageReloadOverlay, { abstractMapStateToProps } + from './AbstractPageReloadOverlay'; import OverlayFrame from './OverlayFrame'; /** @@ -40,4 +41,4 @@ class PageReloadOverlay extends AbstractPageReloadOverlay { } } -export default translate(connect()(PageReloadOverlay)); +export default translate(connect(abstractMapStateToProps)(PageReloadOverlay)); diff --git a/react/features/overlay/components/SuspendedFilmstripOnlyOverlay.js b/react/features/overlay/components/SuspendedFilmstripOnlyOverlay.js index 18c971c8d..0601e4d77 100644 --- a/react/features/overlay/components/SuspendedFilmstripOnlyOverlay.js +++ b/react/features/overlay/components/SuspendedFilmstripOnlyOverlay.js @@ -1,8 +1,8 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; +import React from 'react'; import { translate, translateToHTML } from '../../base/i18n'; +import AbstractSuspendedOverlay from './AbstractSuspendedOverlay'; import FilmstripOnlyOverlayFrame from './FilmstripOnlyOverlayFrame'; import ReloadButton from './ReloadButton'; @@ -10,26 +10,12 @@ import ReloadButton from './ReloadButton'; * Implements a React Component for suspended overlay for filmstrip only mode. * Shown when suspended is detected. */ -class SuspendedFilmstripOnlyOverlay extends Component { - /** - * SuspendedFilmstripOnlyOverlay component's property types. - * - * @static - */ - static propTypes = { - /** - * The function to translate human-readable text. - * - * @public - * @type {Function} - */ - t: PropTypes.func - }; - +class SuspendedFilmstripOnlyOverlay extends AbstractSuspendedOverlay { /** * Implements React's {@link Component#render()}. * * @inheritdoc + * @override * @returns {ReactElement|null} */ render() { diff --git a/react/features/overlay/components/SuspendedOverlay.js b/react/features/overlay/components/SuspendedOverlay.js index 4e72d5c4d..05dcf4422 100644 --- a/react/features/overlay/components/SuspendedOverlay.js +++ b/react/features/overlay/components/SuspendedOverlay.js @@ -1,8 +1,8 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; +import React from 'react'; import { translate, translateToHTML } from '../../base/i18n'; +import AbstractSuspendedOverlay from './AbstractSuspendedOverlay'; import OverlayFrame from './OverlayFrame'; import ReloadButton from './ReloadButton'; @@ -10,26 +10,12 @@ import ReloadButton from './ReloadButton'; * Implements a React Component for suspended overlay. Shown when a suspend is * detected. */ -class SuspendedOverlay extends Component { - /** - * SuspendedOverlay component's property types. - * - * @static - */ - static propTypes = { - /** - * The function to translate human-readable text. - * - * @public - * @type {Function} - */ - t: PropTypes.func - }; - +class SuspendedOverlay extends AbstractSuspendedOverlay { /** * Implements React's {@link Component#render()}. * * @inheritdoc + * @override * @returns {ReactElement|null} */ render() { diff --git a/react/features/overlay/components/UserMediaPermissionsFilmstripOnlyOverlay.js b/react/features/overlay/components/UserMediaPermissionsFilmstripOnlyOverlay.js index 3c5e4491d..26f5d28b9 100644 --- a/react/features/overlay/components/UserMediaPermissionsFilmstripOnlyOverlay.js +++ b/react/features/overlay/components/UserMediaPermissionsFilmstripOnlyOverlay.js @@ -1,43 +1,23 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; +import React from 'react'; +import { connect } from 'react-redux'; import { translate, translateToHTML } from '../../base/i18n'; +import AbstractUserMediaPermissionsOverlay, { abstractMapStateToProps } + from './AbstractUserMediaPermissionsOverlay'; import FilmstripOnlyOverlayFrame from './FilmstripOnlyOverlayFrame'; /** * Implements a React Component for overlay with guidance how to proceed with * gUM prompt. This component will be displayed only for filmstrip only mode. */ -class UserMediaPermissionsFilmstripOnlyOverlay extends Component { - /** - * UserMediaPermissionsFilmstripOnlyOverlay component's property types. - * - * @static - */ - static propTypes = { - /** - * The browser which is used currently. The text is different for every - * browser. - * - * @public - * @type {string} - */ - browser: PropTypes.string, - - /** - * The function to translate human-readable text. - * - * @public - * @type {Function} - */ - t: PropTypes.func - }; - +class UserMediaPermissionsFilmstripOnlyOverlay + extends AbstractUserMediaPermissionsOverlay { /** * Implements React's {@link Component#render()}. * * @inheritdoc + * @override * @returns {ReactElement|null} */ render() { @@ -66,4 +46,5 @@ class UserMediaPermissionsFilmstripOnlyOverlay extends Component { } } -export default translate(UserMediaPermissionsFilmstripOnlyOverlay); +export default translate( + connect(abstractMapStateToProps)(UserMediaPermissionsFilmstripOnlyOverlay)); diff --git a/react/features/overlay/components/UserMediaPermissionsOverlay.js b/react/features/overlay/components/UserMediaPermissionsOverlay.js index edf477c67..a0d3fc5a0 100644 --- a/react/features/overlay/components/UserMediaPermissionsOverlay.js +++ b/react/features/overlay/components/UserMediaPermissionsOverlay.js @@ -1,43 +1,21 @@ /* global interfaceConfig */ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; +import React from 'react'; +import { connect } from 'react-redux'; import { translate, translateToHTML } from '../../base/i18n'; +import AbstractUserMediaPermissionsOverlay, { abstractMapStateToProps } + from './AbstractUserMediaPermissionsOverlay'; import OverlayFrame from './OverlayFrame'; /** * Implements a React Component for overlay with guidance how to proceed with * gUM prompt. */ -class UserMediaPermissionsOverlay extends Component { +class UserMediaPermissionsOverlay extends AbstractUserMediaPermissionsOverlay { /** - * UserMediaPermissionsOverlay component's property types. - * - * @static - */ - static propTypes = { - /** - * The browser which is used currently. The text is different for every - * browser. - * - * @public - * @type {string} - */ - browser: PropTypes.string, - - /** - * The function to translate human-readable text. - * - * @public - * @type {Function} - */ - t: PropTypes.func - }; - - /** - * Initializes a new SuspendedOverlay instance. + * Initializes a new UserMediaPermissionsOverlay instance. * * @param {Object} props - The read-only properties with which the new * instance is to be initialized. @@ -60,6 +38,7 @@ class UserMediaPermissionsOverlay extends Component { * Implements React's {@link Component#render()}. * * @inheritdoc + * @override * @returns {ReactElement|null} */ render() { @@ -116,4 +95,5 @@ class UserMediaPermissionsOverlay extends Component { } } -export default translate(UserMediaPermissionsOverlay); +export default translate( + connect(abstractMapStateToProps)(UserMediaPermissionsOverlay)); diff --git a/react/features/overlay/reducer.js b/react/features/overlay/reducer.js index dc0a46230..634ca34c3 100644 --- a/react/features/overlay/reducer.js +++ b/react/features/overlay/reducer.js @@ -1,16 +1,5 @@ // @flow -import { CONFERENCE_FAILED } from '../base/conference'; -import { - CONNECTION_ESTABLISHED, - CONNECTION_FAILED, - CONNECTION_WILL_CONNECT -} from '../base/connection'; -import { - isFatalJitsiConnectionError, - JitsiConferenceErrors, - JitsiConnectionErrors -} from '../base/lib-jitsi-meet'; import { assign, ReducerRegistry, set } from '../base/redux'; import { @@ -18,25 +7,13 @@ import { SUSPEND_DETECTED } from './actionTypes'; -const logger = require('jitsi-meet-logger').getLogger(__filename); - /** * Reduces the redux actions of the feature overlay. + * + * FIXME: these pieces of state should probably be in a different place. */ ReducerRegistry.register('features/overlay', (state = {}, action) => { switch (action.type) { - case CONFERENCE_FAILED: - return _conferenceFailed(state, action); - - case CONNECTION_ESTABLISHED: - return _connectionEstablished(state); - - case CONNECTION_FAILED: - return _connectionFailed(state, action); - - case CONNECTION_WILL_CONNECT: - return _connectionWillConnect(state, action); - case MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED: return _mediaPermissionPromptVisibilityChanged(state, action); @@ -47,99 +24,6 @@ ReducerRegistry.register('features/overlay', (state = {}, action) => { return state; }); -/** - * Reduces a specific redux action CONFERENCE_FAILED of the feature overlay. - * - * @param {Object} state - The redux state of the feature overlay. - * @param {Action} action - The redux action CONFERENCE_FAILED to reduce. - * @private - * @returns {Object} The new state of the feature overlay after the reduction of - * the specified action. - */ -function _conferenceFailed(state, { error: { message, name } }) { - if (name === JitsiConferenceErrors.FOCUS_LEFT - || name === JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE) { - return assign(state, { - haveToReload: true, - isNetworkFailure: false, - - // FIXME There is no message associated with CONFERENCE_FAILED at - // the time of this writing. In jitsi-meet the action creator - // conferenceFailed neither accepts an argument message nor defines - // a property message on the error. In lib-jitsi-meet - // CONFERENCE_FAILED emissions mostly do not provide a message with - // the exception of at least one which provides an Error, not a - // string. - reason: message - }); - } - - return state; -} - -/** - * Reduces a specific redux action CONNECTION_ESTABLISHED 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 _connectionEstablished(state) { - return set(state, 'connectionEstablished', true); -} - -/** - * Reduces a specific redux action CONNECTION_FAILED of the feature overlay. - * - * @param {Object} state - The redux state of the feature overlay. - * @param {Action} action - The redux action CONNECTION_FAILED to reduce. - * @private - * @returns {Object} The new state of the feature overlay after the reduction of - * the specified action. - */ -function _connectionFailed(state, { error }) { - if (isFatalJitsiConnectionError(error)) { - const { message } = error; - - logger.error(`FATAL XMPP connection error: ${message}`); - - return assign(state, { - haveToReload: true, - - // From all of the cases above only CONNECTION_DROPPED_ERROR is - // considered a network type of failure. - isNetworkFailure: - error.name === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR, - reason: `xmpp-conn-dropped: ${message}` - }); - } - - return state; -} - -/** - * Reduces a specific redux action CONNECTION_WILL_CONNECT in the feature - * overlay. Clears the redux state related to the XMPP connection's status. - * - * @param {Object} state - The redux state of the feature overlay. - * @param {Action} action - The redux action to reduce. - * @private - * @returns {Object} The new state of the feature overlay after reducing the - * specified {@code action} in the feature overlay. - */ -function _connectionWillConnect( - state, - action) { // eslint-disable-line no-unused-vars - return assign(state, { - connectionEstablished: undefined, - haveToReload: undefined, - isNetworkFailure: undefined, - reason: undefined - }); -} - /** * Reduces a specific redux action MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED of * the feature overlay.