Comply w/ coding style
This commit is contained in:
parent
92d0589a37
commit
538af01bf5
|
@ -21,6 +21,9 @@ import analytics from './modules/analytics/analytics';
|
||||||
import EventEmitter from "events";
|
import EventEmitter from "events";
|
||||||
|
|
||||||
import { conferenceFailed } from './react/features/base/conference';
|
import { conferenceFailed } from './react/features/base/conference';
|
||||||
|
import {
|
||||||
|
isFatalJitsiConnectionError
|
||||||
|
} from './react/features/base/lib-jitsi-meet';
|
||||||
import {
|
import {
|
||||||
mediaPermissionPromptVisibilityChanged,
|
mediaPermissionPromptVisibilityChanged,
|
||||||
suspendDetected
|
suspendDetected
|
||||||
|
@ -475,21 +478,18 @@ function disconnect() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
|
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
|
||||||
* @param {JitsiMeetJS.connection.error} error the error reported.
|
*
|
||||||
|
* @param {JitsiMeetJS.connection.error} error - The reported error.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _connectionFailedHandler (error) {
|
function _connectionFailedHandler(error) {
|
||||||
switch (error) {
|
if (isFatalJitsiConnectionError(error)) {
|
||||||
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
|
APP.connection.removeEventListener(
|
||||||
case ConnectionErrors.OTHER_ERROR:
|
ConnectionEvents.CONNECTION_FAILED,
|
||||||
case ConnectionErrors.SERVER_ERROR: {
|
|
||||||
APP.connection.removeEventListener( ConnectionEvents.CONNECTION_FAILED,
|
|
||||||
_connectionFailedHandler);
|
_connectionFailedHandler);
|
||||||
if (room)
|
if (room)
|
||||||
room.leave();
|
room.leave();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ import {
|
||||||
connectionEstablished,
|
connectionEstablished,
|
||||||
connectionFailed
|
connectionFailed
|
||||||
} from './react/features/base/connection';
|
} from './react/features/base/connection';
|
||||||
|
import {
|
||||||
|
isFatalJitsiConnectionError
|
||||||
|
} from './react/features/base/lib-jitsi-meet';
|
||||||
|
|
||||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||||
|
@ -75,18 +78,13 @@ function connect(id, password, roomName) {
|
||||||
connection.addEventListener(
|
connection.addEventListener(
|
||||||
ConnectionEvents.CONNECTION_FAILED, connectionFailedHandler);
|
ConnectionEvents.CONNECTION_FAILED, connectionFailedHandler);
|
||||||
|
|
||||||
function connectionFailedHandler (error, errMsg) {
|
function connectionFailedHandler(error, errMsg) {
|
||||||
APP.store.dispatch(connectionFailed(connection, error, errMsg));
|
APP.store.dispatch(connectionFailed(connection, error, errMsg));
|
||||||
|
|
||||||
switch (error) {
|
if (isFatalJitsiConnectionError(error)) {
|
||||||
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
|
|
||||||
case ConnectionErrors.OTHER_ERROR:
|
|
||||||
case ConnectionErrors.SERVER_ERROR: {
|
|
||||||
connection.removeEventListener(
|
connection.removeEventListener(
|
||||||
ConnectionEvents.CONNECTION_FAILED,
|
ConnectionEvents.CONNECTION_FAILED,
|
||||||
connectionFailedHandler);
|
connectionFailedHandler);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* global APP, JitsiMeetJS, loggingConfig */
|
/* global APP, loggingConfig */
|
||||||
|
|
||||||
import { isRoomValid } from '../base/conference';
|
import { isRoomValid } from '../base/conference';
|
||||||
|
import JitsiMeetJS from '../base/lib-jitsi-meet';
|
||||||
import { RouteRegistry } from '../base/react';
|
import { RouteRegistry } from '../base/react';
|
||||||
import { interceptComponent } from '../base/util';
|
import { interceptComponent } from '../base/util';
|
||||||
import { Conference } from '../conference';
|
import { Conference } from '../conference';
|
||||||
|
|
|
@ -1,5 +1,31 @@
|
||||||
import { loadScript } from '../../base/util';
|
import { loadScript } from '../../base/util';
|
||||||
|
|
||||||
|
import JitsiMeetJS from './_';
|
||||||
|
|
||||||
|
declare var APP: Object;
|
||||||
|
|
||||||
|
const JitsiConnectionErrors = JitsiMeetJS.errors.connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether a specific JitsiConnectionErrors instance indicates a
|
||||||
|
* fatal JitsiConnection error.
|
||||||
|
*
|
||||||
|
* FIXME Figure out the category of errors defined by the fucntion 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 {string} error - The JitsiConnectionErrors instance to
|
||||||
|
* categorize/classify.
|
||||||
|
* @returns {boolean} True if the specified JitsiConnectionErrors instance
|
||||||
|
* indicates a fatal JitsiConnection error; otherwise, false.
|
||||||
|
*/
|
||||||
|
export function isFatalJitsiConnectionError(error: string) {
|
||||||
|
return (
|
||||||
|
error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR
|
||||||
|
|| error === JitsiConnectionErrors.OTHER_ERROR
|
||||||
|
|| error === JitsiConnectionErrors.SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads config.js file from remote server.
|
* Loads config.js file from remote server.
|
||||||
*
|
*
|
||||||
|
@ -7,7 +33,7 @@ import { loadScript } from '../../base/util';
|
||||||
* @param {string} path='/config.js' - Relative pah to config.js file.
|
* @param {string} path='/config.js' - Relative pah to config.js file.
|
||||||
* @returns {Promise<Object>}
|
* @returns {Promise<Object>}
|
||||||
*/
|
*/
|
||||||
export function loadConfig(host, path = '/config.js') {
|
export function loadConfig(host: string, path: string = '/config.js') {
|
||||||
// Returns config.js file from global scope. We can't use the version that's
|
// Returns config.js file from global scope. We can't use the version that's
|
||||||
// being used for the React Native app because the old/current Web app uses
|
// being used for the React Native app because the old/current Web app uses
|
||||||
// config from the global scope.
|
// config from the global scope.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
export * from './interceptComponent';
|
export * from './interceptComponent';
|
||||||
export * from './loadScript';
|
export * from './loadScript';
|
||||||
|
export * from './randomUtil';
|
||||||
export * from './roomnameGenerator';
|
export * from './roomnameGenerator';
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { connect as reactReduxConnect } from 'react-redux';
|
||||||
import { connect, disconnect } from '../../base/connection';
|
import { connect, disconnect } from '../../base/connection';
|
||||||
import { Watermarks } from '../../base/react';
|
import { Watermarks } from '../../base/react';
|
||||||
import { FeedbackButton } from '../../feedback';
|
import { FeedbackButton } from '../../feedback';
|
||||||
|
|
||||||
import { OverlayContainer } from '../../overlay';
|
import { OverlayContainer } from '../../overlay';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,6 +163,7 @@ class Conference extends Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<OverlayContainer />
|
<OverlayContainer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
import { Symbol } from '../base/react';
|
import { Symbol } from '../base/react';
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the Redux action which signals that a suspend was detected.
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* type: SUSPEND_DETECTED
|
|
||||||
* }
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export const SUSPEND_DETECTED = Symbol('SUSPEND_DETECTED');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the Redux action which signals that the prompt for media
|
* The type of the Redux action which signals that the prompt for media
|
||||||
* permission is visible or not.
|
* permission is visible or not.
|
||||||
|
@ -23,3 +13,13 @@ export const SUSPEND_DETECTED = Symbol('SUSPEND_DETECTED');
|
||||||
*/
|
*/
|
||||||
export const MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
export const MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
||||||
= Symbol('MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED');
|
= Symbol('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 = Symbol('SUSPEND_DETECTED');
|
||||||
|
|
|
@ -1,8 +1,28 @@
|
||||||
import {
|
import {
|
||||||
SUSPEND_DETECTED,
|
MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
||||||
MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
SUSPEND_DETECTED
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
import './reducer';
|
|
||||||
|
/**
|
||||||
|
* Signals that the prompt for media permission is visible or not.
|
||||||
|
*
|
||||||
|
* @param {boolean} isVisible - If the value is true - the prompt for media
|
||||||
|
* permission is visible otherwise the value is false/undefined.
|
||||||
|
* @param {string} browser - The name of the current browser.
|
||||||
|
* @returns {{
|
||||||
|
* type: MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
||||||
|
* browser: {string},
|
||||||
|
* isVisible: {boolean}
|
||||||
|
* }}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export function mediaPermissionPromptVisibilityChanged(isVisible, browser) {
|
||||||
|
return {
|
||||||
|
type: MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
||||||
|
browser,
|
||||||
|
isVisible
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that suspend was detected.
|
* Signals that suspend was detected.
|
||||||
|
@ -17,24 +37,3 @@ export function suspendDetected() {
|
||||||
type: SUSPEND_DETECTED
|
type: SUSPEND_DETECTED
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Signals that the prompt for media permission is visible or not.
|
|
||||||
*
|
|
||||||
* @param {boolean} isVisible - If the value is true - the prompt for media
|
|
||||||
* permission is visible otherwise the value is false/undefined.
|
|
||||||
* @param {string} browser - The name of the current browser.
|
|
||||||
* @returns {{
|
|
||||||
* type: MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
|
||||||
* isVisible: {boolean},
|
|
||||||
* browser: {string}
|
|
||||||
* }}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export function mediaPermissionPromptVisibilityChanged(isVisible, browser) {
|
|
||||||
return {
|
|
||||||
type: MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
|
||||||
isVisible,
|
|
||||||
browser
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements an abstract React Component for overlay - the components which
|
* Implements an abstract React Component for overlay - the components which are
|
||||||
* are displayed on top of the application covering the whole screen.
|
* displayed on top of the application covering the whole screen.
|
||||||
*
|
*
|
||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
|
@ -21,25 +21,15 @@ export default class AbstractOverlay extends Component {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
/**
|
/**
|
||||||
* Indicates the css style of the overlay. if true - lighter and
|
* Indicates the CSS style of the overlay. If true, then ighter;
|
||||||
* darker otherwise.
|
* darker, otherwise.
|
||||||
|
*
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
isLightOverlay: false
|
isLightOverlay: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract method which should be used by subclasses to provide the overlay
|
|
||||||
* content.
|
|
||||||
*
|
|
||||||
* @returns {ReactElement|null}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
_renderOverlayContent() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is executed when comonent is mounted.
|
* This method is executed when comonent is mounted.
|
||||||
*
|
*
|
||||||
|
@ -51,6 +41,31 @@ export default class AbstractOverlay extends Component {
|
||||||
APP.translation.translateElement($('#overlay'));
|
APP.translation.translateElement($('#overlay'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements React's {@link Component#render()}.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {ReactElement|null}
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const containerClass
|
||||||
|
= this.state.isLightOverlay
|
||||||
|
? 'overlay__container-light'
|
||||||
|
: 'overlay__container';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className = { containerClass }
|
||||||
|
id = 'overlay'>
|
||||||
|
<div className = 'overlay__content'>
|
||||||
|
{
|
||||||
|
this._renderOverlayContent()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads the page.
|
* Reloads the page.
|
||||||
*
|
*
|
||||||
|
@ -64,23 +79,13 @@ export default class AbstractOverlay extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements React's {@link Component#render()}.
|
* Abstract method which should be used by subclasses to provide the overlay
|
||||||
|
* content.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement|null}
|
* @returns {ReactElement|null}
|
||||||
|
* @protected
|
||||||
*/
|
*/
|
||||||
render() {
|
_renderOverlayContent() {
|
||||||
const containerClass = this.state.isLightOverlay
|
return null;
|
||||||
? 'overlay__container-light' : 'overlay__container';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className = { containerClass }
|
|
||||||
id = 'overlay'>
|
|
||||||
<div className = 'overlay__content'>
|
|
||||||
{ this._renderOverlayContent() }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,16 +20,20 @@ class OverlayContainer extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
/**
|
/**
|
||||||
* The browser which is used currently.
|
* The browser which is used currently.
|
||||||
|
*
|
||||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
_browser: React.PropTypes.string,
|
_browser: React.PropTypes.string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the status of
|
* The indicator which determines whether the status of the
|
||||||
* JitsiConnection object has been "established" or not.
|
* JitsiConnection object has been "established" or not.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
@ -38,7 +42,9 @@ class OverlayContainer extends Component {
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether a critical error for reload
|
* The indicator which determines whether a critical error for reload
|
||||||
* has been received.
|
* has been received.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
@ -47,16 +53,20 @@ class OverlayContainer extends Component {
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the reload was caused by
|
* The indicator which determines whether the reload was caused by
|
||||||
* network failure.
|
* network failure.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
_isNetworkFailure: React.PropTypes.bool,
|
_isNetworkFailure: React.PropTypes.bool,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the GUM permissions prompt
|
* The indicator which determines whether the GUM permissions prompt is
|
||||||
* is displayed or not.
|
* displayed or not.
|
||||||
|
*
|
||||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
@ -64,16 +74,20 @@ class OverlayContainer extends Component {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The reason for the error that will cause the reload.
|
* The reason for the error that will cause the reload.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
_reason: React.PropTypes.string,
|
_reason: React.PropTypes.string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the GUM permissions prompt
|
* The indicator which determines whether the GUM permissions prompt is
|
||||||
* is displayed or not.
|
* displayed or not.
|
||||||
|
*
|
||||||
* NOTE: Used by SuspendedOverlay only.
|
* NOTE: Used by SuspendedOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
|
@ -91,8 +105,8 @@ class OverlayContainer extends Component {
|
||||||
// FIXME: Temporary workaround until everything is moved to react.
|
// FIXME: Temporary workaround until everything is moved to react.
|
||||||
APP.UI.overlayVisible
|
APP.UI.overlayVisible
|
||||||
= (this.props._connectionEstablished && this.props._haveToReload)
|
= (this.props._connectionEstablished && this.props._haveToReload)
|
||||||
|| this.props._suspendDetected
|
|| this.props._suspendDetected
|
||||||
|| this.props._mediaPermissionPromptVisible;
|
|| this.props._mediaPermissionPromptVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,80 +147,95 @@ class OverlayContainer extends Component {
|
||||||
*
|
*
|
||||||
* @param {Object} state - The Redux state.
|
* @param {Object} state - The Redux state.
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* _browser: string,
|
* _browser: string,
|
||||||
* _connectionEstablished: bool,
|
* _connectionEstablished: bool,
|
||||||
* _haveToReload: bool,
|
* _haveToReload: bool,
|
||||||
* _isNetworkFailure: bool,
|
* _isNetworkFailure: bool,
|
||||||
* _mediaPermissionPromptVisible: bool,
|
* _mediaPermissionPromptVisible: bool,
|
||||||
* _reason: string,
|
* _reason: string,
|
||||||
* _suspendDetected: bool
|
* _suspendDetected: bool
|
||||||
* }}
|
* }}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state) {
|
function _mapStateToProps(state) {
|
||||||
|
const stateFeaturesOverlay = state['features/overlay'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* The browser which is used currently.
|
* The browser which is used currently.
|
||||||
|
*
|
||||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
_browser: state['features/overlay'].browser,
|
_browser: stateFeaturesOverlay.browser,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the status of
|
* The indicator which determines whether the status of the
|
||||||
* JitsiConnection object has been "established" or not.
|
* JitsiConnection object has been "established" or not.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
_connectionEstablished:
|
_connectionEstablished: stateFeaturesOverlay.connectionEstablished,
|
||||||
state['features/overlay'].connectionEstablished,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether a critical error for reload
|
* The indicator which determines whether a critical error for reload
|
||||||
* has been received.
|
* has been received.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
_haveToReload: state['features/overlay'].haveToReload,
|
_haveToReload: stateFeaturesOverlay.haveToReload,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the reload was caused by
|
* The indicator which determines whether the reload was caused by
|
||||||
* network failure.
|
* network failure.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
_isNetworkFailure: state['features/overlay'].isNetworkFailure,
|
_isNetworkFailure: stateFeaturesOverlay.isNetworkFailure,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the GUM permissions prompt
|
* The indicator which determines whether the GUM permissions prompt is
|
||||||
* is displayed or not.
|
* displayed or not.
|
||||||
|
*
|
||||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
_mediaPermissionPromptVisible:
|
_mediaPermissionPromptVisible:
|
||||||
state['features/overlay'].mediaPermissionPromptVisible,
|
stateFeaturesOverlay.mediaPermissionPromptVisible,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The reason for the error that will cause the reload.
|
* The reason for the error that will cause the reload.
|
||||||
|
*
|
||||||
* NOTE: Used by PageReloadOverlay only.
|
* NOTE: Used by PageReloadOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
_reason: state['features/overlay'].reason,
|
_reason: stateFeaturesOverlay.reason,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indicator which determines whether the GUM permissions prompt
|
* The indicator which determines whether the GUM permissions prompt is
|
||||||
* is displayed or not.
|
* displayed or not.
|
||||||
|
*
|
||||||
* NOTE: Used by SuspendedOverlay only.
|
* NOTE: Used by SuspendedOverlay only.
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
_suspendDetected: state['features/overlay'].suspendDetected
|
_suspendDetected: stateFeaturesOverlay.suspendDetected
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,141 +1,18 @@
|
||||||
/* global APP, AJS */
|
import React from 'react';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import { randomInt } from '../../base/util';
|
||||||
|
|
||||||
import { randomInt } from '../../base/util/randomUtil';
|
|
||||||
|
|
||||||
import AbstractOverlay from './AbstractOverlay';
|
import AbstractOverlay from './AbstractOverlay';
|
||||||
|
import ReloadTimer from './ReloadTimer';
|
||||||
|
|
||||||
|
declare var APP: Object;
|
||||||
|
|
||||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a React Component for the reload timer. Starts counter from
|
* Implements a React Component for page reload overlay. Shown before the
|
||||||
* props.start, adds props.step to the current value on every props.interval
|
* conference is reloaded. Shows a warning message and counts down towards the
|
||||||
* seconds until the current value reaches props.end. Also displays progress
|
* reload.
|
||||||
* bar.
|
|
||||||
*/
|
|
||||||
class ReloadTimer extends Component {
|
|
||||||
/**
|
|
||||||
* ReloadTimer component's property types.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
static propTypes = {
|
|
||||||
/**
|
|
||||||
* The end of the timer. When this.state.current reaches this
|
|
||||||
* value the timer will stop and call onFinish function.
|
|
||||||
* @public
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
end: React.PropTypes.number,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The interval in sec for adding this.state.step to this.state.current
|
|
||||||
* @public
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
interval: React.PropTypes.number,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The function that will be executed when timer finish (when
|
|
||||||
* this.state.current === this.props.end)
|
|
||||||
*/
|
|
||||||
onFinish: React.PropTypes.func,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The start of the timer. The initial value for this.state.current.
|
|
||||||
* @public
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
start: React.PropTypes.number,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value which will be added to this.state.current on every step.
|
|
||||||
* @public
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
step: React.PropTypes.number
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes a new ReloadTimer instance.
|
|
||||||
*
|
|
||||||
* @param {Object} props - The read-only properties with which the new
|
|
||||||
* instance is to be initialized.
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
current: this.props.start,
|
|
||||||
time: Math.abs(this.props.end - this.props.start)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Component method that executes once component is mounted.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {void}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
componentDidMount() {
|
|
||||||
AJS.progressBars.update('#reloadProgressBar', 0);
|
|
||||||
const intervalId = setInterval(() => {
|
|
||||||
if (this.state.current === this.props.end) {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
this.props.onFinish();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState((prevState, props) => {
|
|
||||||
return { current: prevState.current + props.step };
|
|
||||||
});
|
|
||||||
}, Math.abs(this.props.interval) * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Component method that executes once component is updated.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {void}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
componentDidUpdate() {
|
|
||||||
AJS.progressBars.update('#reloadProgressBar',
|
|
||||||
Math.abs(this.state.current - this.props.start) / this.state.time);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement|null}
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
className = 'aui-progress-indicator'
|
|
||||||
id = 'reloadProgressBar'>
|
|
||||||
<span className = 'aui-progress-indicator-value' />
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
className = 'reload_overlay_text'
|
|
||||||
id = 'reloadSeconds'>
|
|
||||||
{ this.state.current }
|
|
||||||
<span data-i18n = 'dialog.conferenceReloadTimeLeft' />
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements a React Component for page reload overlay. Shown before
|
|
||||||
* the conference is reloaded. Shows a warning message and counts down towards
|
|
||||||
* the reload.
|
|
||||||
*/
|
*/
|
||||||
export default class PageReloadOverlay extends AbstractOverlay {
|
export default class PageReloadOverlay extends AbstractOverlay {
|
||||||
/**
|
/**
|
||||||
|
@ -172,8 +49,8 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How long the overlay dialog will be
|
* How long the overlay dialog will be displayed, before the conference
|
||||||
* displayed, before the conference will be reloaded.
|
* will be reloaded.
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
const timeoutSeconds = 10 + randomInt(0, 20);
|
const timeoutSeconds = 10 + randomInt(0, 20);
|
||||||
|
@ -194,33 +71,59 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
||||||
...this.state,
|
...this.state,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates the css style of the overlay. if true - lighter and
|
* Indicates the css style of the overlay. If true, then lighter;
|
||||||
* darker otherwise.
|
* darker, otherwise.
|
||||||
|
*
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
isLightOverlay,
|
isLightOverlay,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The translation key for the title of the overlay
|
* The translation key for the title of the overlay.
|
||||||
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
message,
|
message,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How long the overlay dialog will be
|
* How long the overlay dialog will be displayed before the
|
||||||
* displayed, before the conference will be reloaded.
|
* conference will be reloaded.
|
||||||
|
*
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
timeoutSeconds,
|
timeoutSeconds,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The translation key for the title of the overlay
|
* The translation key for the title of the overlay.
|
||||||
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
title
|
title
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is executed when comonent is mounted.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
super.componentDidMount();
|
||||||
|
|
||||||
|
// FIXME (CallStats - issue) This event will not make it to CallStats
|
||||||
|
// because the log queue is not flushed before "fabric terminated" is
|
||||||
|
// sent to the backed.
|
||||||
|
// FIXME: We should dispatch action for this.
|
||||||
|
APP.conference.logEvent(
|
||||||
|
'page.reload',
|
||||||
|
/* value */ undefined,
|
||||||
|
/* label */ this.props.reason);
|
||||||
|
logger.info(
|
||||||
|
'The conference will be reloaded after '
|
||||||
|
+ `${this.state.timeoutSeconds} seconds.`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the button for relaod the page if necessary.
|
* Renders the button for relaod the page if necessary.
|
||||||
*
|
*
|
||||||
|
@ -229,18 +132,21 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
||||||
*/
|
*/
|
||||||
_renderButton() {
|
_renderButton() {
|
||||||
if (this.props.isNetworkFailure) {
|
if (this.props.isNetworkFailure) {
|
||||||
const cName = 'button-control button-control_primary '
|
const className
|
||||||
+ 'button-control_center';
|
= 'button-control button-control_primary button-control_center';
|
||||||
|
|
||||||
/* eslint-disable react/jsx-handler-names */
|
/* eslint-disable react/jsx-handler-names */
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className = { cName }
|
className = { className }
|
||||||
data-i18n = 'dialog.reconnectNow'
|
data-i18n = 'dialog.reconnectNow'
|
||||||
id = 'reconnectNow'
|
id = 'reconnectNow'
|
||||||
onClick = { this._reconnectNow } />
|
onClick = { this._reconnectNow } />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* eslint-enable react/jsx-handler-names */
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -275,24 +181,7 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
||||||
{ this._renderButton() }
|
{ this._renderButton() }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/* eslint-enable react/jsx-handler-names */
|
||||||
* This method is executed when comonent is mounted.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
componentDidMount() {
|
|
||||||
super.componentDidMount();
|
|
||||||
|
|
||||||
// FIXME (CallStats - issue) this event will not make it to
|
|
||||||
// the CallStats, because the log queue is not flushed, before
|
|
||||||
// "fabric terminated" is sent to the backed
|
|
||||||
// FIXME: We should dispatch action for this
|
|
||||||
APP.conference.logEvent('page.reload', undefined /* value */,
|
|
||||||
this.props.reason /* label */);
|
|
||||||
logger.info(`The conference will be reloaded after
|
|
||||||
${this.state.timeoutSeconds} seconds.`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
declare var AJS: Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a React Component for the reload timer. Starts counter from
|
||||||
|
* props.start, adds props.step to the current value on every props.interval
|
||||||
|
* seconds until the current value reaches props.end. Also displays progress
|
||||||
|
* bar.
|
||||||
|
*/
|
||||||
|
export default class ReloadTimer extends Component {
|
||||||
|
/**
|
||||||
|
* ReloadTimer component's property types.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
static propTypes = {
|
||||||
|
/**
|
||||||
|
* The end of the timer. When this.state.current reaches this value the
|
||||||
|
* timer will stop and call onFinish function.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
end: React.PropTypes.number,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interval in sec for adding this.state.step to this.state.current.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
interval: React.PropTypes.number,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function that will be executed when timer finish (when
|
||||||
|
* this.state.current === this.props.end)
|
||||||
|
*/
|
||||||
|
onFinish: React.PropTypes.func,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start of the timer. The initial value for this.state.current.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
start: React.PropTypes.number,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value which will be added to this.state.current on every step.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
step: React.PropTypes.number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new ReloadTimer instance.
|
||||||
|
*
|
||||||
|
* @param {Object} props - The read-only properties with which the new
|
||||||
|
* instance is to be initialized.
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
current: this.props.start,
|
||||||
|
time: Math.abs(this.props.end - this.props.start)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Component method that executes once component is mounted.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {void}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
componentDidMount() {
|
||||||
|
AJS.progressBars.update('#reloadProgressBar', 0);
|
||||||
|
|
||||||
|
const intervalId
|
||||||
|
= setInterval(
|
||||||
|
() => {
|
||||||
|
if (this.state.current === this.props.end) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
this.props.onFinish();
|
||||||
|
} else {
|
||||||
|
this.setState((prevState, props) => {
|
||||||
|
return {
|
||||||
|
current: prevState.current + props.step
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Math.abs(this.props.interval) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Component method that executes once component is updated.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {void}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
componentDidUpdate() {
|
||||||
|
AJS.progressBars.update(
|
||||||
|
'#reloadProgressBar',
|
||||||
|
Math.abs(this.state.current - this.props.start)
|
||||||
|
/ this.state.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements React's {@link Component#render()}.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
* @returns {ReactElement|null}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className = 'aui-progress-indicator'
|
||||||
|
id = 'reloadProgressBar'>
|
||||||
|
<span className = 'aui-progress-indicator-value' />
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
className = 'reload_overlay_text'
|
||||||
|
id = 'reloadSeconds'>
|
||||||
|
{
|
||||||
|
this.state.current
|
||||||
|
}
|
||||||
|
<span data-i18n = 'dialog.conferenceReloadTimeLeft' />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,8 @@ import React from 'react';
|
||||||
import AbstractOverlay from './AbstractOverlay';
|
import AbstractOverlay from './AbstractOverlay';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a React Component for suspended overlay. Shown when suspended
|
* Implements a React Component for suspended overlay. Shown when a suspend is
|
||||||
* is detected.
|
* detected.
|
||||||
*/
|
*/
|
||||||
export default class SuspendedOverlay extends AbstractOverlay {
|
export default class SuspendedOverlay extends AbstractOverlay {
|
||||||
/**
|
/**
|
||||||
|
@ -33,5 +33,7 @@ export default class SuspendedOverlay extends AbstractOverlay {
|
||||||
onClick = { this._reconnectNow } />
|
onClick = { this._reconnectNow } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* eslint-enable react/jsx-handler-names */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ export default class UserMediaPermissionsOverlay extends AbstractOverlay {
|
||||||
/**
|
/**
|
||||||
* The browser which is used currently. The text is different for every
|
* The browser which is used currently. The text is different for every
|
||||||
* browser.
|
* browser.
|
||||||
|
*
|
||||||
* @public
|
* @public
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
|
@ -37,6 +38,7 @@ export default class UserMediaPermissionsOverlay extends AbstractOverlay {
|
||||||
this.state = {
|
this.state = {
|
||||||
/**
|
/**
|
||||||
* The src value of the image for the policy logo.
|
* The src value of the image for the policy logo.
|
||||||
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
policyLogoSrc: interfaceConfig.POLICY_LOGO
|
policyLogoSrc: interfaceConfig.POLICY_LOGO
|
||||||
|
@ -72,7 +74,9 @@ export default class UserMediaPermissionsOverlay extends AbstractOverlay {
|
||||||
<p
|
<p
|
||||||
className = 'policy__text'
|
className = 'policy__text'
|
||||||
data-i18n = '[html]startupoverlay.policyText' />
|
data-i18n = '[html]startupoverlay.policyText' />
|
||||||
{ this._renderPolicyLogo() }
|
{
|
||||||
|
this._renderPolicyLogo()
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -85,10 +89,12 @@ export default class UserMediaPermissionsOverlay extends AbstractOverlay {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_renderPolicyLogo() {
|
_renderPolicyLogo() {
|
||||||
if (this.state.policyLogoSrc) {
|
const { policyLogoSrc } = this.state;
|
||||||
|
|
||||||
|
if (policyLogoSrc) {
|
||||||
return (
|
return (
|
||||||
<div className = 'policy__logo'>
|
<div className = 'policy__logo'>
|
||||||
<img src = { this.state.policyLogoSrc } />
|
<img src = { policyLogoSrc } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
export * from './components';
|
|
||||||
export * from './actions';
|
export * from './actions';
|
||||||
|
export * from './components';
|
||||||
|
|
||||||
|
import './reducer';
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
/* global JitsiMeetJS */
|
|
||||||
|
|
||||||
import { CONFERENCE_FAILED } from '../base/conference';
|
import { CONFERENCE_FAILED } from '../base/conference';
|
||||||
import {
|
import {
|
||||||
CONNECTION_ESTABLISHED,
|
CONNECTION_ESTABLISHED,
|
||||||
CONNECTION_FAILED
|
CONNECTION_FAILED
|
||||||
} from '../base/connection';
|
} from '../base/connection';
|
||||||
|
import JitsiMeetJS, {
|
||||||
|
isFatalJitsiConnectionError
|
||||||
|
} from '../base/lib-jitsi-meet';
|
||||||
import {
|
import {
|
||||||
ReducerRegistry,
|
ReducerRegistry,
|
||||||
setStateProperty,
|
setStateProperties,
|
||||||
setStateProperties
|
setStateProperty
|
||||||
} from '../base/redux';
|
} from '../base/redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -16,6 +17,8 @@ import {
|
||||||
SUSPEND_DETECTED
|
SUSPEND_DETECTED
|
||||||
} from './actionTypes';
|
} from './actionTypes';
|
||||||
|
|
||||||
|
const JitsiConferenceErrors = JitsiMeetJS.errors.conference;
|
||||||
|
const JitsiConnectionErrors = JitsiMeetJS.errors.connection;
|
||||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,20 +46,19 @@ ReducerRegistry.register('features/overlay', (state = {}, action) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces a specific Redux action CONFERENCE_FAILED of the feature
|
* Reduces a specific Redux action CONFERENCE_FAILED of the feature overlay.
|
||||||
* overlay.
|
|
||||||
*
|
*
|
||||||
* @param {Object} state - The Redux state of the feature overlay.
|
* @param {Object} state - The Redux state of the feature overlay.
|
||||||
* @param {Action} action - The Redux action CONFERENCE_FAILED to reduce.
|
* @param {Action} action - The Redux action CONFERENCE_FAILED to reduce.
|
||||||
* @returns {Object} The new state of the feature base/connection after the
|
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||||
* reduction of the specified action.
|
* the specified action.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _conferenceFailed(state, action) {
|
function _conferenceFailed(state, action) {
|
||||||
const ConferenceErrors = JitsiMeetJS.errors.conference;
|
const error = action.error;
|
||||||
|
|
||||||
if (action.error === ConferenceErrors.FOCUS_LEFT
|
if (error === JitsiConferenceErrors.FOCUS_LEFT
|
||||||
|| action.error === ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE) {
|
|| error === JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE) {
|
||||||
return setStateProperties(state, {
|
return setStateProperties(state, {
|
||||||
haveToReload: true,
|
haveToReload: true,
|
||||||
isNetworkFailure: false,
|
isNetworkFailure: false,
|
||||||
|
@ -72,8 +74,8 @@ function _conferenceFailed(state, action) {
|
||||||
* overlay.
|
* overlay.
|
||||||
*
|
*
|
||||||
* @param {Object} state - The Redux state of the feature overlay.
|
* @param {Object} state - The Redux state of the feature overlay.
|
||||||
* @returns {Object} The new state of the feature overlay after the
|
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||||
* reduction of the specified action.
|
* the specified action.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _connectionEstablished(state) {
|
function _connectionEstablished(state) {
|
||||||
|
@ -81,63 +83,60 @@ function _connectionEstablished(state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces a specific Redux action CONNECTION_FAILED of the feature
|
* Reduces a specific Redux action CONNECTION_FAILED of the feature overlay.
|
||||||
* overlay.
|
|
||||||
*
|
*
|
||||||
* @param {Object} state - The Redux state of the feature overlay.
|
* @param {Object} state - The Redux state of the feature overlay.
|
||||||
* @param {Action} action - The Redux action CONNECTION_FAILED to reduce.
|
* @param {Action} action - The Redux action CONNECTION_FAILED to reduce.
|
||||||
* @returns {Object} The new state of the feature overlay after the
|
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||||
* reduction of the specified action.
|
* the specified action.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _connectionFailed(state, action) {
|
function _connectionFailed(state, action) {
|
||||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
const error = action.error;
|
||||||
|
|
||||||
switch (action.error) {
|
if (isFatalJitsiConnectionError(error)) {
|
||||||
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
|
const errorMessage = action.errorMessage;
|
||||||
case ConnectionErrors.OTHER_ERROR:
|
|
||||||
case ConnectionErrors.SERVER_ERROR: {
|
logger.error(`XMPP connection error: ${errorMessage}`);
|
||||||
logger.error(`XMPP connection error: ${action.errorMessage}`);
|
|
||||||
|
|
||||||
// From all of the cases above only CONNECTION_DROPPED_ERROR
|
|
||||||
// is considered a network type of failure
|
|
||||||
return setStateProperties(state, {
|
return setStateProperties(state, {
|
||||||
haveToReload: true,
|
haveToReload: true,
|
||||||
|
|
||||||
|
|
||||||
|
// From all of the cases above only CONNECTION_DROPPED_ERROR is
|
||||||
|
// considered a network type of failure.
|
||||||
isNetworkFailure:
|
isNetworkFailure:
|
||||||
action.error === ConnectionErrors.CONNECTION_DROPPED_ERROR,
|
error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR,
|
||||||
reason: `xmpp-conn-dropped: ${action.errorMessage}`
|
reason: `xmpp-conn-dropped: ${errorMessage}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces a specific Redux action MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
* Reduces a specific Redux action MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED of
|
||||||
* of the feature overlay.
|
* the feature overlay.
|
||||||
*
|
*
|
||||||
* @param {Object} state - The Redux state of the feature overlay.
|
* @param {Object} state - The Redux state of the feature overlay.
|
||||||
* @param {Action} action - The Redux action to reduce.
|
* @param {Action} action - The Redux action to reduce.
|
||||||
* @returns {Object} The new state of the feature overlay after the
|
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||||
* reduction of the specified action.
|
* the specified action.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _mediaPermissionPromptVisibilityChanged(state, action) {
|
function _mediaPermissionPromptVisibilityChanged(state, action) {
|
||||||
return setStateProperties(state, {
|
return setStateProperties(state, {
|
||||||
mediaPermissionPromptVisible: action.isVisible,
|
browser: action.browser,
|
||||||
browser: action.browser
|
mediaPermissionPromptVisible: action.isVisible
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces a specific Redux action SUSPEND_DETECTED of the feature
|
* Reduces a specific Redux action SUSPEND_DETECTED of the feature overlay.
|
||||||
* overlay.
|
|
||||||
*
|
*
|
||||||
* @param {Object} state - The Redux state of the feature overlay.
|
* @param {Object} state - The Redux state of the feature overlay.
|
||||||
* @returns {Object} The new state of the feature overlay after the
|
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||||
* reduction of the specified action.
|
* the specified action.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _suspendDetected(state) {
|
function _suspendDetected(state) {
|
||||||
|
|
Loading…
Reference in New Issue