[React] Call/ring overlay
Rewrite the non-React RingOverlay into the React Component CallOverlay in a way which makes it easier to port to React Native.
This commit is contained in:
@@ -77,7 +77,6 @@ export function connect() {
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
APP.UI.hideRingOverlay();
|
||||
APP.API.notifyConferenceLeft(APP.conference.roomName);
|
||||
logger.error(error);
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import UIEvents from '../../../service/UI/UIEvents';
|
||||
/* @flow */
|
||||
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { SET_CALL_OVERLAY_VISIBLE } from '../jwt';
|
||||
|
||||
import Filmstrip from '../../../modules/UI/videolayout/Filmstrip';
|
||||
import UIEvents from '../../../service/UI/UIEvents';
|
||||
|
||||
import {
|
||||
SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
|
||||
@@ -10,19 +14,33 @@ import {
|
||||
declare var APP: Object;
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
const result = next(action);
|
||||
|
||||
MiddlewareRegistry.register(({ getState }) => next => action => {
|
||||
switch (action.type) {
|
||||
case SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY:
|
||||
case SET_FILMSTRIP_VISIBILITY: {
|
||||
if (typeof APP !== 'undefined') {
|
||||
APP.UI.emitEvent(UIEvents.UPDATED_FILMSTRIP_DISPLAY);
|
||||
case SET_CALL_OVERLAY_VISIBLE:
|
||||
if (typeof APP === 'undefined') {
|
||||
const oldValue
|
||||
= Boolean(getState()['features/jwt'].callOverlayVisible);
|
||||
const result = next(action);
|
||||
const newValue
|
||||
= Boolean(getState()['features/jwt'].callOverlayVisible);
|
||||
|
||||
oldValue === newValue
|
||||
|| Filmstrip.toggleFilmstrip(!newValue, false);
|
||||
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
||||
case SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY:
|
||||
case SET_FILMSTRIP_VISIBILITY: {
|
||||
const result = next(action);
|
||||
|
||||
typeof APP === 'undefined'
|
||||
|| APP.UI.emitEvent(UIEvents.UPDATED_FILMSTRIP_DISPLAY);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return next(action);
|
||||
});
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* The type of redux action which sets the visibility of {@code CallOverlay}.
|
||||
*
|
||||
* {
|
||||
* type: SET_CALL_OVERLAY_VISIBLE,
|
||||
* callOverlayVisible: boolean
|
||||
* }
|
||||
*/
|
||||
export const SET_CALL_OVERLAY_VISIBLE = Symbol('SET_CALL_OVERLAY_VISIBLE');
|
||||
|
||||
/**
|
||||
* The type of redux action which stores a specific JSON Web Token (JWT) into
|
||||
* the redux store.
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
/* @flow */
|
||||
|
||||
import { SET_JWT } from './actionTypes';
|
||||
import { SET_CALL_OVERLAY_VISIBLE, SET_JWT } from './actionTypes';
|
||||
|
||||
/**
|
||||
* Sets the visibility of {@code CallOverlay}.
|
||||
*
|
||||
* @param {boolean|undefined} callOverlayVisible - If {@code CallOverlay} is to
|
||||
* be displayed/visible, then {@code true}; otherwise, {@code false} or
|
||||
* {@code undefined}.
|
||||
* @returns {{
|
||||
* type: SET_CALL_OVERLAY_VISIBLE,
|
||||
* callOverlayVisible: (boolean|undefined)
|
||||
* }}
|
||||
*/
|
||||
export function setCallOverlayVisible(callOverlayVisible: boolean) {
|
||||
return (dispatch: Dispatch<*>, getState: Function) => {
|
||||
getState()['features/jwt'].callOverlayVisible === callOverlayVisible
|
||||
|| dispatch({
|
||||
type: SET_CALL_OVERLAY_VISIBLE,
|
||||
callOverlayVisible
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a specific JSON Web Token (JWT) into the redux store.
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/* @flow */
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { Audio } from '../../base/media';
|
||||
import { Avatar } from '../../base/participants';
|
||||
import { Container, Text } from '../../base/react';
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
|
||||
declare var $: Object;
|
||||
declare var APP: Object;
|
||||
declare var interfaceConfig: Object;
|
||||
|
||||
/**
|
||||
* Implements a React {@link Component} which depicts the establishment of a
|
||||
* call with a specific remote callee.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
class CallOverlay extends Component {
|
||||
/**
|
||||
* The (reference to the) {@link Audio} which plays/renders the audio
|
||||
* depicting the ringing phase of the call establishment represented by this
|
||||
* {@code CallOverlay}.
|
||||
*/
|
||||
_audio: ?Audio
|
||||
|
||||
_onLargeVideoAvatarVisible: Function
|
||||
|
||||
_playAudioInterval: ?number
|
||||
|
||||
_ringingTimeout: ?number
|
||||
|
||||
_setAudio: Function
|
||||
|
||||
state: {
|
||||
|
||||
/**
|
||||
* The CSS class (name), if any, to add to this {@code CallOverlay}.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
className: ?string,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether this {@code CallOverlay}
|
||||
* should play/render audio to indicate the ringing phase of the
|
||||
* call establishment between the local participant and the
|
||||
* associated remote callee.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
renderAudio: boolean,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether this {@code CallOverlay}
|
||||
* is depicting the ringing phase of the call establishment between
|
||||
* the local participant and the associated remote callee or the
|
||||
* phase afterwards when the callee has not answered the call for a
|
||||
* period of time and, consequently, is considered unavailable.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
ringing: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code CallOverlay} component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
_callee: React.PropTypes.object
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new {@code CallOverlay} instance.
|
||||
*
|
||||
* @param {Object} props - The read-only React {@link Component} props with
|
||||
* which the new instance is to be initialized.
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
className: undefined,
|
||||
renderAudio:
|
||||
typeof interfaceConfig !== 'object'
|
||||
|| !interfaceConfig.DISABLE_RINGING,
|
||||
ringing: true
|
||||
};
|
||||
|
||||
this._onLargeVideoAvatarVisible
|
||||
= this._onLargeVideoAvatarVisible.bind(this);
|
||||
this._setAudio = this._setAudio.bind(this);
|
||||
|
||||
if (typeof APP === 'object') {
|
||||
APP.UI.addListener(
|
||||
UIEvents.LARGE_VIDEO_AVATAR_VISIBLE,
|
||||
this._onLargeVideoAvatarVisible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up timeouts such as the timeout to end the ringing phase of the call
|
||||
* establishment depicted by this {@code CallOverlay}.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
componentDidMount() {
|
||||
// Set up the timeout to end the ringing phase of the call establishment
|
||||
// depicted by this CallOverlay.
|
||||
if (this.state.ringing && !this._ringingTimeout) {
|
||||
this._ringingTimeout
|
||||
= setTimeout(
|
||||
() => {
|
||||
this._pauseAudio();
|
||||
|
||||
this._ringingTimeout = undefined;
|
||||
this.setState({
|
||||
ringing: false
|
||||
});
|
||||
},
|
||||
30000);
|
||||
}
|
||||
|
||||
this._playAudio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up before this {@code Calleverlay} is unmounted and destroyed.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
componentWillUnmount() {
|
||||
this._pauseAudio();
|
||||
|
||||
if (this._ringingTimeout) {
|
||||
clearTimeout(this._ringingTimeout);
|
||||
this._ringingTimeout = undefined;
|
||||
}
|
||||
|
||||
if (typeof APP === 'object') {
|
||||
APP.UI.removeListener(
|
||||
UIEvents.LARGE_VIDEO_AVATAR_VISIBLE,
|
||||
this._onLargeVideoAvatarVisible);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { className, ringing } = this.state;
|
||||
const { avatarUrl, name } = this.props._callee;
|
||||
|
||||
return (
|
||||
<Container
|
||||
className = { `ringing ${className || ''}` }
|
||||
id = 'ringOverlay'>
|
||||
<Container className = 'ringing__content'>
|
||||
{ ringing ? <Text>Calling...</Text> : null }
|
||||
<Avatar
|
||||
className = 'ringing__avatar'
|
||||
uri = { avatarUrl } />
|
||||
<Container className = 'ringing__caller-info'>
|
||||
<Text>
|
||||
{ name }
|
||||
{ ringing ? null : ' isn\'t available' }
|
||||
</Text>
|
||||
</Container>
|
||||
</Container>
|
||||
{ this._renderAudio() }
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this {@code CallOverlay} that the visibility of the
|
||||
* participant's avatar in the large video has changed.
|
||||
*
|
||||
* @param {boolean} largeVideoAvatarVisible - If the avatar in the large
|
||||
* video (i.e. of the participant on the stage) is visible, then
|
||||
* {@code true}; otherwise, {@code false}.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onLargeVideoAvatarVisible(largeVideoAvatarVisible: boolean) {
|
||||
this.setState({
|
||||
className: largeVideoAvatarVisible ? 'solidBG' : undefined
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the playback of the audio which represents the ringing phase of the
|
||||
* call establishment depicted by this {@code CallOverlay}.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_pauseAudio() {
|
||||
const audio = this._audio;
|
||||
|
||||
if (audio) {
|
||||
audio.pause();
|
||||
}
|
||||
if (this._playAudioInterval) {
|
||||
clearInterval(this._playAudioInterval);
|
||||
this._playAudioInterval = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the playback of the audio which represents the ringing phase of
|
||||
* the call establishment depicted by this {@code CallOverlay}.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_playAudio() {
|
||||
if (this._audio) {
|
||||
this._audio.play();
|
||||
if (!this._playAudioInterval) {
|
||||
this._playAudioInterval
|
||||
= setInterval(() => this._playAudio(), 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an audio element to represent the ringing phase of the call
|
||||
* establishment represented by this {@code CallOverlay}.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderAudio() {
|
||||
if (this.state.renderAudio && this.state.ringing) {
|
||||
return (
|
||||
<Audio
|
||||
ref = { this._setAudio }
|
||||
src = './sounds/ring.ogg' />
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the (reference to the) {@link Audio} which renders the ringing phase
|
||||
* of the call establishment represented by this {@code CallOverlay}.
|
||||
*
|
||||
* @param {Audio} audio - The (reference to the) {@code Audio} which
|
||||
* plays/renders the audio depicting the ringing phase of the call
|
||||
* establishment represented by this {@code CallOverlay}.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_setAudio(audio) {
|
||||
this._audio = audio;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps (parts of) the redux state to {@code CallOverlay}'s props.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _callee: Object
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @private
|
||||
* @type {Object}
|
||||
*/
|
||||
_callee: state['features/jwt'].callee
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps)(CallOverlay);
|
||||
@@ -0,0 +1 @@
|
||||
export { default as CallOverlay } from './CallOverlay';
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './actions';
|
||||
export * from './components';
|
||||
export * from './functions';
|
||||
|
||||
import './middleware';
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
import jwtDecode from 'jwt-decode';
|
||||
|
||||
import {
|
||||
CONFERENCE_FAILED,
|
||||
CONFERENCE_LEFT,
|
||||
CONFERENCE_WILL_LEAVE,
|
||||
SET_ROOM
|
||||
} from '../base/conference';
|
||||
import { SET_CONFIG } from '../base/config';
|
||||
import { SET_LOCATION_URL } from '../base/connection';
|
||||
import { LIB_INIT_ERROR } from '../base/lib-jitsi-meet';
|
||||
import { PARTICIPANT_JOINED } from '../base/participants';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
import { setJWT } from './actions';
|
||||
import { setCallOverlayVisible, setJWT } from './actions';
|
||||
import { SET_JWT } from './actionTypes';
|
||||
import { parseJWTFromURLParams } from './functions';
|
||||
|
||||
/**
|
||||
* Middleware to parse token data upon setting a new room URL.
|
||||
*
|
||||
* @param {Store} store - The Redux store.
|
||||
* @param {Store} store - The redux store.
|
||||
* @private
|
||||
* @returns {Function}
|
||||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case CONFERENCE_FAILED:
|
||||
case CONFERENCE_LEFT:
|
||||
case CONFERENCE_WILL_LEAVE:
|
||||
case LIB_INIT_ERROR:
|
||||
case PARTICIPANT_JOINED:
|
||||
case SET_ROOM:
|
||||
return _maybeSetCallOverlayVisible(store, next, action);
|
||||
|
||||
case SET_CONFIG:
|
||||
case SET_LOCATION_URL:
|
||||
// XXX The JSON Web Token (JWT) is not the only piece of state that we
|
||||
@@ -33,16 +49,87 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
return next(action);
|
||||
});
|
||||
|
||||
/**
|
||||
* Notifies the feature jwt that a specific {@code action} is being dispatched
|
||||
* within a specific redux {@code store} which may have an effect on the
|
||||
* visiblity of (the) {@code CallOverlay}.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified {@code action}
|
||||
* is being dispatched.
|
||||
* @param {Dispatch} next - The redux dispatch function to dispatch the
|
||||
* specified {@code action} to the specified {@code store}.
|
||||
* @param {Action} action - The redux action which is being dispatched in the
|
||||
* specified {@code store}.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _maybeSetCallOverlayVisible({ dispatch, getState }, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
const state = getState();
|
||||
const stateFeaturesJWT = state['features/jwt'];
|
||||
let callOverlayVisible;
|
||||
|
||||
if (stateFeaturesJWT.callee) {
|
||||
const { conference, leaving, room } = state['features/base/conference'];
|
||||
|
||||
// XXX The CallOverlay is to be displayed/visible as soon as
|
||||
// possible including even before the conference is joined.
|
||||
if (room && (!conference || conference !== leaving)) {
|
||||
switch (action.type) {
|
||||
case CONFERENCE_FAILED:
|
||||
case CONFERENCE_LEFT:
|
||||
case CONFERENCE_WILL_LEAVE:
|
||||
case LIB_INIT_ERROR:
|
||||
// Because the CallOverlay is to be displayed/visible as soon as
|
||||
// possible even before the connection is established and/or the
|
||||
// conference is joined, it is very complicated to figure out
|
||||
// based on the current state alone. In order to reduce the
|
||||
// risks of displaying the CallOverly at inappropirate times, do
|
||||
// not even attempt to figure out based on the current state.
|
||||
// The (redux) actions listed above are also the equivalents of
|
||||
// the execution ponints at which APP.UI.hideRingOverlay() used
|
||||
// to be invoked.
|
||||
break;
|
||||
|
||||
default: {
|
||||
// The CallOverlay it to no longer be displayed/visible as soon
|
||||
// as another participant joins.
|
||||
const participants = state['features/base/participants'];
|
||||
|
||||
callOverlayVisible
|
||||
= Boolean(
|
||||
participants
|
||||
&& participants.length === 1
|
||||
&& participants[0].local);
|
||||
|
||||
// However, the CallDialog is not to be displayed/visible again
|
||||
// after all remote participants leave.
|
||||
if (callOverlayVisible
|
||||
&& stateFeaturesJWT.callOverlayVisible === false) {
|
||||
callOverlayVisible = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch(setCallOverlayVisible(callOverlayVisible));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the feature jwt that the action {@link SET_CONFIG} or
|
||||
* {@link SET_LOCATION_URL} is being dispatched within a specific Redux
|
||||
* {@link SET_LOCATION_URL} is being dispatched within a specific redux
|
||||
* {@code store}.
|
||||
*
|
||||
* @param {Store} store - The Redux store in which the specified {@code action}
|
||||
* @param {Store} store - The redux store in which the specified {@code action}
|
||||
* is being dispatched.
|
||||
* @param {Dispatch} next - The Redux dispatch function to dispatch the
|
||||
* @param {Dispatch} next - The redux dispatch function to dispatch the
|
||||
* specified {@code action} to the specified {@code store}.
|
||||
* @param {Action} action - The Redux action {@code SET_CONFIG} or
|
||||
* @param {Action} action - The redux action {@code SET_CONFIG} or
|
||||
* {@code SET_LOCATION_URL} which is being dispatched in the specified
|
||||
* {@code store}.
|
||||
* @private
|
||||
@@ -65,26 +152,26 @@ function _setConfigOrLocationURL({ dispatch, getState }, next, action) {
|
||||
|
||||
/**
|
||||
* Notifies the feature jwt that the action {@link SET_JWT} is being dispatched
|
||||
* within a specific Redux {@code store}.
|
||||
* within a specific redux {@code store}.
|
||||
*
|
||||
* @param {Store} store - The Redux store in which the specified {@code action}
|
||||
* @param {Store} store - The redux store in which the specified {@code action}
|
||||
* is being dispatched.
|
||||
* @param {Dispatch} next - The Redux dispatch function to dispatch the
|
||||
* @param {Dispatch} next - The redux dispatch function to dispatch the
|
||||
* specified {@code action} to the specified {@code store}.
|
||||
* @param {Action} action - The Redux action {@code SET_JWT} which is being
|
||||
* @param {Action} action - The redux action {@code SET_JWT} which is being
|
||||
* dispatched in the specified {@code store}.
|
||||
* @private
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _setJWT({ getState }, next, action) {
|
||||
function _setJWT(store, next, action) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { jwt, type, ...actionPayload } = action;
|
||||
|
||||
if (jwt && !Object.keys(actionPayload).length) {
|
||||
const {
|
||||
enableUserRolesBasedOnToken
|
||||
} = getState()['features/base/config'];
|
||||
} = store.getState()['features/base/config'];
|
||||
|
||||
action.isGuest = !enableUserRolesBasedOnToken;
|
||||
|
||||
@@ -103,5 +190,5 @@ function _setJWT({ getState }, next, action) {
|
||||
}
|
||||
}
|
||||
|
||||
return next(action);
|
||||
return _maybeSetCallOverlayVisible(store, next, action);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { equals, ReducerRegistry } from '../base/redux';
|
||||
import { equals, set, ReducerRegistry } from '../base/redux';
|
||||
|
||||
import { SET_JWT } from './actionTypes';
|
||||
import { SET_CALL_OVERLAY_VISIBLE, SET_JWT } from './actionTypes';
|
||||
|
||||
/**
|
||||
* The initial redux state of the feature jwt.
|
||||
@@ -11,6 +11,14 @@ import { SET_JWT } from './actionTypes';
|
||||
* }}
|
||||
*/
|
||||
const _INITIAL_STATE = {
|
||||
/**
|
||||
* The indicator which determines whether (the) {@code CallOverlay} is
|
||||
* visible.
|
||||
*
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
callOverlayVisible: undefined,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the local participant is a guest
|
||||
* in the conference.
|
||||
@@ -31,6 +39,9 @@ const _INITIAL_STATE = {
|
||||
*/
|
||||
ReducerRegistry.register('features/jwt', (state = _INITIAL_STATE, action) => {
|
||||
switch (action.type) {
|
||||
case SET_CALL_OVERLAY_VISIBLE:
|
||||
return set(state, 'callOverlayVisible', action.callOverlayVisible);
|
||||
|
||||
case SET_JWT: {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { type, ...payload } = action;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { CallOverlay } from '../../jwt';
|
||||
|
||||
import PageReloadFilmstripOnlyOverlay from './PageReloadFilmstripOnlyOverlay';
|
||||
import PageReloadOverlay from './PageReloadOverlay';
|
||||
import SuspendedFilmstripOnlyOverlay from './SuspendedFilmstripOnlyOverlay';
|
||||
@@ -33,6 +35,15 @@ class OverlayContainer extends Component {
|
||||
*/
|
||||
_browser: React.PropTypes.string,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the {@link CallOverlay} is
|
||||
* displayed/visible.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
_callOverlayVisible: React.PropTypes.bool,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the status of the
|
||||
* JitsiConnection object has been "established" or not.
|
||||
@@ -172,6 +183,8 @@ class OverlayContainer extends Component {
|
||||
props = {
|
||||
browser: this.props._browser
|
||||
};
|
||||
} else if (this.props._callOverlayVisible) {
|
||||
overlayComponent = CallOverlay;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -182,17 +195,18 @@ class OverlayContainer extends Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps (parts of) the Redux state to the associated OverlayContainer's props.
|
||||
* Maps (parts of) the redux state to the associated OverlayContainer's props.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {{
|
||||
* _browser: string,
|
||||
* _connectionEstablished: bool,
|
||||
* _haveToReload: bool,
|
||||
* _isNetworkFailure: bool,
|
||||
* _isMediaPermissionPromptVisible: bool,
|
||||
* _callOverlayVisible: boolean,
|
||||
* _connectionEstablished: boolean,
|
||||
* _haveToReload: boolean,
|
||||
* _isNetworkFailure: boolean,
|
||||
* _isMediaPermissionPromptVisible: boolean,
|
||||
* _reason: string,
|
||||
* _suspendDetected: bool
|
||||
* _suspendDetected: boolean
|
||||
* }}
|
||||
* @private
|
||||
*/
|
||||
@@ -203,18 +217,27 @@ function _mapStateToProps(state) {
|
||||
/**
|
||||
* The browser which is used currently.
|
||||
*
|
||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||
* NOTE: Used by {@link UserMediaPermissionsOverlay} only.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
_browser: stateFeaturesOverlay.browser,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the {@link CallOverlay} is
|
||||
* displayed/visible.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
_callOverlayVisible: Boolean(state['features/jwt'].callOverlayVisible),
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the status of the
|
||||
* JitsiConnection object has been "established" or not.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
* NOTE: Used by {@link PageReloadOverlay} only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
@@ -225,7 +248,7 @@ function _mapStateToProps(state) {
|
||||
* The indicator which determines whether a critical error for reload
|
||||
* has been received.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
* NOTE: Used by {@link PageReloadOverlay} only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
@@ -236,7 +259,7 @@ function _mapStateToProps(state) {
|
||||
* The indicator which determines whether the GUM permissions prompt is
|
||||
* displayed or not.
|
||||
*
|
||||
* NOTE: Used by UserMediaPermissionsOverlay only.
|
||||
* NOTE: Used by {@link UserMediaPermissionsOverlay} only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
@@ -248,7 +271,7 @@ function _mapStateToProps(state) {
|
||||
* The indicator which determines whether the reload was caused by
|
||||
* network failure.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
* NOTE: Used by {@link PageReloadOverlay} only.
|
||||
*
|
||||
* @private
|
||||
* @type {boolean}
|
||||
@@ -258,7 +281,7 @@ function _mapStateToProps(state) {
|
||||
/**
|
||||
* The reason for the error that will cause the reload.
|
||||
*
|
||||
* NOTE: Used by PageReloadOverlay only.
|
||||
* NOTE: Used by {@link PageReloadOverlay} only.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
@@ -269,7 +292,7 @@ function _mapStateToProps(state) {
|
||||
* The indicator which determines whether the GUM permissions prompt is
|
||||
* displayed or not.
|
||||
*
|
||||
* NOTE: Used by SuspendedOverlay only.
|
||||
* NOTE: Used by {@link SuspendedOverlay} only.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
|
||||
@@ -178,7 +178,7 @@ export function hideToolbox(force: boolean = false): Function {
|
||||
|
||||
if (!force
|
||||
&& (hovered
|
||||
|| APP.UI.isRingOverlayVisible()
|
||||
|| state['features/jwt'].callOverlayVisible
|
||||
|| SideContainerToggler.isVisible())) {
|
||||
dispatch(
|
||||
setToolboxTimeout(
|
||||
|
||||
Reference in New Issue
Block a user