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 { conferenceFailed } from './react/features/base/conference';
|
||||
import {
|
||||
isFatalJitsiConnectionError
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import {
|
||||
mediaPermissionPromptVisibilityChanged,
|
||||
suspendDetected
|
||||
|
@ -475,21 +478,18 @@ function disconnect() {
|
|||
|
||||
/**
|
||||
* 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}
|
||||
* @private
|
||||
*/
|
||||
function _connectionFailedHandler (error) {
|
||||
switch (error) {
|
||||
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
|
||||
case ConnectionErrors.OTHER_ERROR:
|
||||
case ConnectionErrors.SERVER_ERROR: {
|
||||
APP.connection.removeEventListener( ConnectionEvents.CONNECTION_FAILED,
|
||||
function _connectionFailedHandler(error) {
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
APP.connection.removeEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED,
|
||||
_connectionFailedHandler);
|
||||
if (room)
|
||||
room.leave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ import {
|
|||
connectionEstablished,
|
||||
connectionFailed
|
||||
} from './react/features/base/connection';
|
||||
import {
|
||||
isFatalJitsiConnectionError
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
|
||||
const ConnectionEvents = JitsiMeetJS.events.connection;
|
||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
|
@ -75,18 +78,13 @@ function connect(id, password, roomName) {
|
|||
connection.addEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED, connectionFailedHandler);
|
||||
|
||||
function connectionFailedHandler (error, errMsg) {
|
||||
function connectionFailedHandler(error, errMsg) {
|
||||
APP.store.dispatch(connectionFailed(connection, error, errMsg));
|
||||
|
||||
switch (error) {
|
||||
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
|
||||
case ConnectionErrors.OTHER_ERROR:
|
||||
case ConnectionErrors.SERVER_ERROR: {
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
connection.removeEventListener(
|
||||
ConnectionEvents.CONNECTION_FAILED,
|
||||
connectionFailedHandler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* global APP, JitsiMeetJS, loggingConfig */
|
||||
/* global APP, loggingConfig */
|
||||
|
||||
import { isRoomValid } from '../base/conference';
|
||||
import JitsiMeetJS from '../base/lib-jitsi-meet';
|
||||
import { RouteRegistry } from '../base/react';
|
||||
import { interceptComponent } from '../base/util';
|
||||
import { Conference } from '../conference';
|
||||
|
|
|
@ -1,5 +1,31 @@
|
|||
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.
|
||||
*
|
||||
|
@ -7,7 +33,7 @@ import { loadScript } from '../../base/util';
|
|||
* @param {string} path='/config.js' - Relative pah to config.js file.
|
||||
* @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
|
||||
// being used for the React Native app because the old/current Web app uses
|
||||
// config from the global scope.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './interceptComponent';
|
||||
export * from './loadScript';
|
||||
export * from './randomUtil';
|
||||
export * from './roomnameGenerator';
|
||||
|
|
|
@ -6,7 +6,6 @@ import { connect as reactReduxConnect } from 'react-redux';
|
|||
import { connect, disconnect } from '../../base/connection';
|
||||
import { Watermarks } from '../../base/react';
|
||||
import { FeedbackButton } from '../../feedback';
|
||||
|
||||
import { OverlayContainer } from '../../overlay';
|
||||
|
||||
/**
|
||||
|
@ -164,6 +163,7 @@ class Conference extends Component {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<OverlayContainer />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
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
|
||||
* permission is visible or not.
|
||||
|
@ -23,3 +13,13 @@ export const SUSPEND_DETECTED = Symbol('SUSPEND_DETECTED');
|
|||
*/
|
||||
export const 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 {
|
||||
SUSPEND_DETECTED,
|
||||
MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
||||
MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED,
|
||||
SUSPEND_DETECTED
|
||||
} 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.
|
||||
|
@ -17,24 +37,3 @@ export function suspendDetected() {
|
|||
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';
|
||||
|
||||
/**
|
||||
* Implements an abstract React Component for overlay - the components which
|
||||
* are displayed on top of the application covering the whole screen.
|
||||
* Implements an abstract React Component for overlay - the components which are
|
||||
* displayed on top of the application covering the whole screen.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
|
@ -21,25 +21,15 @@ export default class AbstractOverlay extends Component {
|
|||
|
||||
this.state = {
|
||||
/**
|
||||
* Indicates the css style of the overlay. if true - lighter and
|
||||
* darker otherwise.
|
||||
* Indicates the CSS style of the overlay. If true, then ighter;
|
||||
* darker, otherwise.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -51,6 +41,31 @@ export default class AbstractOverlay extends Component {
|
|||
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.
|
||||
*
|
||||
|
@ -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}
|
||||
* @protected
|
||||
*/
|
||||
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>
|
||||
);
|
||||
_renderOverlayContent() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,20 @@ class OverlayContainer extends Component {
|
|||
static propTypes = {
|
||||
/**
|
||||
* The browser which is used currently.
|
||||
*
|
||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {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.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
|
@ -38,7 +42,9 @@ class OverlayContainer extends Component {
|
|||
/**
|
||||
* The indicator which determines whether a critical error for reload
|
||||
* has been received.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
|
@ -47,16 +53,20 @@ class OverlayContainer extends Component {
|
|||
/**
|
||||
* The indicator which determines whether the reload was caused by
|
||||
* network failure.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
_isNetworkFailure: React.PropTypes.bool,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the GUM permissions prompt
|
||||
* is displayed or not.
|
||||
* The indicator which determines whether the GUM permissions prompt is
|
||||
* displayed or not.
|
||||
*
|
||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
|
@ -64,16 +74,20 @@ class OverlayContainer extends Component {
|
|||
|
||||
/**
|
||||
* The reason for the error that will cause the reload.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
_reason: React.PropTypes.string,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the GUM permissions prompt
|
||||
* is displayed or not.
|
||||
* The indicator which determines whether the GUM permissions prompt is
|
||||
* displayed or not.
|
||||
*
|
||||
* NOTE: Used by SuspendedOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
|
@ -91,8 +105,8 @@ class OverlayContainer extends Component {
|
|||
// FIXME: Temporary workaround until everything is moved to react.
|
||||
APP.UI.overlayVisible
|
||||
= (this.props._connectionEstablished && this.props._haveToReload)
|
||||
|| this.props._suspendDetected
|
||||
|| this.props._mediaPermissionPromptVisible;
|
||||
|| this.props._suspendDetected
|
||||
|| this.props._mediaPermissionPromptVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,80 +147,95 @@ class OverlayContainer extends Component {
|
|||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _browser: string,
|
||||
* _connectionEstablished: bool,
|
||||
* _haveToReload: bool,
|
||||
* _isNetworkFailure: bool,
|
||||
* _mediaPermissionPromptVisible: bool,
|
||||
* _reason: string,
|
||||
* _suspendDetected: bool
|
||||
* _browser: string,
|
||||
* _connectionEstablished: bool,
|
||||
* _haveToReload: bool,
|
||||
* _isNetworkFailure: bool,
|
||||
* _mediaPermissionPromptVisible: bool,
|
||||
* _reason: string,
|
||||
* _suspendDetected: bool
|
||||
* }}
|
||||
* @private
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
const stateFeaturesOverlay = state['features/overlay'];
|
||||
|
||||
return {
|
||||
/**
|
||||
* The browser which is used currently.
|
||||
*
|
||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @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.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
_connectionEstablished:
|
||||
state['features/overlay'].connectionEstablished,
|
||||
_connectionEstablished: stateFeaturesOverlay.connectionEstablished,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether a critical error for reload
|
||||
* has been received.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
_haveToReload: state['features/overlay'].haveToReload,
|
||||
_haveToReload: stateFeaturesOverlay.haveToReload,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the reload was caused by
|
||||
* network failure.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
_isNetworkFailure: state['features/overlay'].isNetworkFailure,
|
||||
_isNetworkFailure: stateFeaturesOverlay.isNetworkFailure,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the GUM permissions prompt
|
||||
* is displayed or not.
|
||||
* The indicator which determines whether the GUM permissions prompt is
|
||||
* displayed or not.
|
||||
*
|
||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
_mediaPermissionPromptVisible:
|
||||
state['features/overlay'].mediaPermissionPromptVisible,
|
||||
stateFeaturesOverlay.mediaPermissionPromptVisible,
|
||||
|
||||
/**
|
||||
* The reason for the error that will cause the reload.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
_reason: state['features/overlay'].reason,
|
||||
_reason: stateFeaturesOverlay.reason,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the GUM permissions prompt
|
||||
* is displayed or not.
|
||||
* The indicator which determines whether the GUM permissions prompt is
|
||||
* displayed or not.
|
||||
*
|
||||
* NOTE: Used by SuspendedOverlay only.
|
||||
*
|
||||
* @private
|
||||
* @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/randomUtil';
|
||||
import { randomInt } from '../../base/util';
|
||||
|
||||
import AbstractOverlay from './AbstractOverlay';
|
||||
import ReloadTimer from './ReloadTimer';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
* 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 {
|
||||
/**
|
||||
|
@ -172,8 +49,8 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
|||
super(props);
|
||||
|
||||
/**
|
||||
* How long the overlay dialog will be
|
||||
* displayed, before the conference will be reloaded.
|
||||
* How long the overlay dialog will be displayed, before the conference
|
||||
* will be reloaded.
|
||||
* @type {number}
|
||||
*/
|
||||
const timeoutSeconds = 10 + randomInt(0, 20);
|
||||
|
@ -194,33 +71,59 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
|||
...this.state,
|
||||
|
||||
/**
|
||||
* Indicates the css style of the overlay. if true - lighter and
|
||||
* darker otherwise.
|
||||
* Indicates the css style of the overlay. If true, then lighter;
|
||||
* darker, otherwise.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
isLightOverlay,
|
||||
|
||||
/**
|
||||
* The translation key for the title of the overlay
|
||||
* The translation key for the title of the overlay.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
message,
|
||||
|
||||
/**
|
||||
* How long the overlay dialog will be
|
||||
* displayed, before the conference will be reloaded.
|
||||
* How long the overlay dialog will be displayed before the
|
||||
* conference will be reloaded.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
timeoutSeconds,
|
||||
|
||||
/**
|
||||
* The translation key for the title of the overlay
|
||||
* The translation key for the title of the overlay.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -229,18 +132,21 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
|||
*/
|
||||
_renderButton() {
|
||||
if (this.props.isNetworkFailure) {
|
||||
const cName = 'button-control button-control_primary '
|
||||
+ 'button-control_center';
|
||||
const className
|
||||
= 'button-control button-control_primary button-control_center';
|
||||
|
||||
/* eslint-disable react/jsx-handler-names */
|
||||
|
||||
return (
|
||||
<button
|
||||
className = { cName }
|
||||
className = { className }
|
||||
data-i18n = 'dialog.reconnectNow'
|
||||
id = 'reconnectNow'
|
||||
onClick = { this._reconnectNow } />
|
||||
);
|
||||
|
||||
|
||||
/* eslint-enable react/jsx-handler-names */
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -275,24 +181,7 @@ export default class PageReloadOverlay extends AbstractOverlay {
|
|||
{ this._renderButton() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.`);
|
||||
/* eslint-enable react/jsx-handler-names */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
||||
/**
|
||||
* Implements a React Component for suspended overlay. Shown when suspended
|
||||
* is detected.
|
||||
* Implements a React Component for suspended overlay. Shown when a suspend is
|
||||
* detected.
|
||||
*/
|
||||
export default class SuspendedOverlay extends AbstractOverlay {
|
||||
/**
|
||||
|
@ -33,5 +33,7 @@ export default class SuspendedOverlay extends AbstractOverlay {
|
|||
onClick = { this._reconnectNow } />
|
||||
</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
|
||||
* browser.
|
||||
*
|
||||
* @public
|
||||
* @type {string}
|
||||
*/
|
||||
|
@ -37,6 +38,7 @@ export default class UserMediaPermissionsOverlay extends AbstractOverlay {
|
|||
this.state = {
|
||||
/**
|
||||
* The src value of the image for the policy logo.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
policyLogoSrc: interfaceConfig.POLICY_LOGO
|
||||
|
@ -72,7 +74,9 @@ export default class UserMediaPermissionsOverlay extends AbstractOverlay {
|
|||
<p
|
||||
className = 'policy__text'
|
||||
data-i18n = '[html]startupoverlay.policyText' />
|
||||
{ this._renderPolicyLogo() }
|
||||
{
|
||||
this._renderPolicyLogo()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -85,10 +89,12 @@ export default class UserMediaPermissionsOverlay extends AbstractOverlay {
|
|||
* @private
|
||||
*/
|
||||
_renderPolicyLogo() {
|
||||
if (this.state.policyLogoSrc) {
|
||||
const { policyLogoSrc } = this.state;
|
||||
|
||||
if (policyLogoSrc) {
|
||||
return (
|
||||
<div className = 'policy__logo'>
|
||||
<img src = { this.state.policyLogoSrc } />
|
||||
<img src = { policyLogoSrc } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
export * from './components';
|
||||
export * from './actions';
|
||||
export * from './components';
|
||||
|
||||
import './reducer';
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
/* global JitsiMeetJS */
|
||||
|
||||
import { CONFERENCE_FAILED } from '../base/conference';
|
||||
import {
|
||||
CONNECTION_ESTABLISHED,
|
||||
CONNECTION_FAILED
|
||||
} from '../base/connection';
|
||||
import JitsiMeetJS, {
|
||||
isFatalJitsiConnectionError
|
||||
} from '../base/lib-jitsi-meet';
|
||||
import {
|
||||
ReducerRegistry,
|
||||
setStateProperty,
|
||||
setStateProperties
|
||||
setStateProperties,
|
||||
setStateProperty
|
||||
} from '../base/redux';
|
||||
|
||||
import {
|
||||
|
@ -16,6 +17,8 @@ import {
|
|||
SUSPEND_DETECTED
|
||||
} from './actionTypes';
|
||||
|
||||
const JitsiConferenceErrors = JitsiMeetJS.errors.conference;
|
||||
const JitsiConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
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
|
||||
* overlay.
|
||||
* 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.
|
||||
* @returns {Object} The new state of the feature base/connection after the
|
||||
* reduction of the specified action.
|
||||
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||
* the specified action.
|
||||
* @private
|
||||
*/
|
||||
function _conferenceFailed(state, action) {
|
||||
const ConferenceErrors = JitsiMeetJS.errors.conference;
|
||||
const error = action.error;
|
||||
|
||||
if (action.error === ConferenceErrors.FOCUS_LEFT
|
||||
|| action.error === ConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE) {
|
||||
if (error === JitsiConferenceErrors.FOCUS_LEFT
|
||||
|| error === JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE) {
|
||||
return setStateProperties(state, {
|
||||
haveToReload: true,
|
||||
isNetworkFailure: false,
|
||||
|
@ -72,8 +74,8 @@ function _conferenceFailed(state, action) {
|
|||
* overlay.
|
||||
*
|
||||
* @param {Object} state - The Redux state of the feature overlay.
|
||||
* @returns {Object} The new state of the feature overlay after the
|
||||
* reduction of the specified action.
|
||||
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||
* the specified action.
|
||||
* @private
|
||||
*/
|
||||
function _connectionEstablished(state) {
|
||||
|
@ -81,63 +83,60 @@ function _connectionEstablished(state) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Reduces a specific Redux action CONNECTION_FAILED of the feature
|
||||
* overlay.
|
||||
* 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.
|
||||
* @returns {Object} The new state of the feature overlay after the
|
||||
* reduction of the specified action.
|
||||
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||
* the specified action.
|
||||
* @private
|
||||
*/
|
||||
function _connectionFailed(state, action) {
|
||||
const ConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
const error = action.error;
|
||||
|
||||
switch (action.error) {
|
||||
case ConnectionErrors.CONNECTION_DROPPED_ERROR:
|
||||
case ConnectionErrors.OTHER_ERROR:
|
||||
case ConnectionErrors.SERVER_ERROR: {
|
||||
logger.error(`XMPP connection error: ${action.errorMessage}`);
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
const errorMessage = action.errorMessage;
|
||||
|
||||
logger.error(`XMPP connection error: ${errorMessage}`);
|
||||
|
||||
// From all of the cases above only CONNECTION_DROPPED_ERROR
|
||||
// is considered a network type of failure
|
||||
return setStateProperties(state, {
|
||||
haveToReload: true,
|
||||
|
||||
|
||||
// From all of the cases above only CONNECTION_DROPPED_ERROR is
|
||||
// considered a network type of failure.
|
||||
isNetworkFailure:
|
||||
action.error === ConnectionErrors.CONNECTION_DROPPED_ERROR,
|
||||
reason: `xmpp-conn-dropped: ${action.errorMessage}`
|
||||
error === JitsiConnectionErrors.CONNECTION_DROPPED_ERROR,
|
||||
reason: `xmpp-conn-dropped: ${errorMessage}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reduces a specific Redux action MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED
|
||||
* of the feature overlay.
|
||||
* Reduces a specific Redux action MEDIA_PERMISSION_PROMPT_VISIBILITY_CHANGED of
|
||||
* the feature overlay.
|
||||
*
|
||||
* @param {Object} state - The Redux state of the feature overlay.
|
||||
* @param {Action} action - The Redux action to reduce.
|
||||
* @returns {Object} The new state of the feature overlay after the
|
||||
* reduction of the specified action.
|
||||
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||
* the specified action.
|
||||
* @private
|
||||
*/
|
||||
function _mediaPermissionPromptVisibilityChanged(state, action) {
|
||||
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
|
||||
* overlay.
|
||||
* Reduces a specific Redux action SUSPEND_DETECTED 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
|
||||
* reduction of the specified action.
|
||||
* @returns {Object} The new state of the feature overlay after the reduction of
|
||||
* the specified action.
|
||||
* @private
|
||||
*/
|
||||
function _suspendDetected(state) {
|
||||
|
|
Loading…
Reference in New Issue