mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-05-15 21:57:48 +00:00
Do the selection in mapStateToProps so the container itself doesn't need to receive all the props that each overlay needs. Each overlay is responsible for fetching their own props and for providing a "needsDisplay" static method wich will be called with the full redux state and should return true if the overlay needs displaying. Also eliminate duplicated state keeping: the connection and conference error states can be fetched from their respective base features.
261 lines
6.7 KiB
JavaScript
261 lines
6.7 KiB
JavaScript
/* @flow */
|
|
|
|
import PropTypes from 'prop-types';
|
|
import React, { Component } from 'react';
|
|
|
|
import {
|
|
isFatalJitsiConferenceError,
|
|
isFatalJitsiConnectionError
|
|
} from '../../base/lib-jitsi-meet';
|
|
import { randomInt } from '../../base/util';
|
|
|
|
import { _reloadNow } from '../actions';
|
|
import ReloadButton from './ReloadButton';
|
|
|
|
declare var APP: Object;
|
|
|
|
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|
|
|
/**
|
|
* Implements abstract React Component for the page reload overlays.
|
|
*/
|
|
export default class AbstractPageReloadOverlay extends Component<*, *> {
|
|
/**
|
|
* AbstractPageReloadOverlay component's property types.
|
|
*
|
|
* @static
|
|
*/
|
|
static propTypes = {
|
|
dispatch: PropTypes.func,
|
|
|
|
/**
|
|
* The indicator which determines whether the reload was caused by
|
|
* network failure.
|
|
*
|
|
* @public
|
|
* @type {boolean}
|
|
*/
|
|
isNetworkFailure: PropTypes.bool,
|
|
|
|
/**
|
|
* The reason for the error that will cause the reload.
|
|
* NOTE: Used by PageReloadOverlay only.
|
|
*
|
|
* @public
|
|
* @type {string}
|
|
*/
|
|
reason: PropTypes.string,
|
|
|
|
/**
|
|
* The function to translate human-readable text.
|
|
*
|
|
* @public
|
|
* @type {Function}
|
|
*/
|
|
t: PropTypes.func
|
|
};
|
|
|
|
_interval: ?number
|
|
|
|
state: {
|
|
|
|
/**
|
|
* The translation key for the title of the overlay.
|
|
*
|
|
* @type {string}
|
|
*/
|
|
message: string,
|
|
|
|
/**
|
|
* Current value(time) of the timer.
|
|
*
|
|
* @type {number}
|
|
*/
|
|
timeLeft: number,
|
|
|
|
/**
|
|
* How long the overlay dialog will be displayed before the
|
|
* conference will be reloaded.
|
|
*
|
|
* @type {number}
|
|
*/
|
|
timeoutSeconds: number,
|
|
|
|
/**
|
|
* The translation key for the title of the overlay.
|
|
*
|
|
* @type {string}
|
|
*/
|
|
title: string
|
|
}
|
|
|
|
/**
|
|
* Check if this overlay needs to be rendered. This function will be called
|
|
* by the {@code OverlayContainer}.
|
|
*
|
|
* @param {Object} state - The redux state.
|
|
* @returns {boolean} - True if this overlay needs to be rendered, false
|
|
* otherwise.
|
|
*/
|
|
static needsRender(state) {
|
|
const conferenceError = state['features/base/conference'].error;
|
|
const connectionError = state['features/base/connection'].error;
|
|
|
|
return (
|
|
(connectionError && isFatalJitsiConnectionError(connectionError))
|
|
|| (conferenceError
|
|
&& isFatalJitsiConferenceError(conferenceError))
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Initializes a new AbstractPageReloadOverlay instance.
|
|
*
|
|
* @param {Object} props - The read-only properties with which the new
|
|
* instance is to be initialized.
|
|
* @public
|
|
*/
|
|
constructor(props: Object) {
|
|
super(props);
|
|
|
|
/**
|
|
* How long the overlay dialog will be displayed, before the conference
|
|
* will be reloaded.
|
|
*
|
|
* @type {number}
|
|
*/
|
|
const timeoutSeconds = 10 + randomInt(0, 20);
|
|
|
|
let message, title;
|
|
|
|
if (this.props.isNetworkFailure) {
|
|
title = 'dialog.conferenceDisconnectTitle';
|
|
message = 'dialog.conferenceDisconnectMsg';
|
|
} else {
|
|
title = 'dialog.conferenceReloadTitle';
|
|
message = 'dialog.conferenceReloadMsg';
|
|
}
|
|
|
|
this.state = {
|
|
message,
|
|
timeLeft: timeoutSeconds,
|
|
timeoutSeconds,
|
|
title
|
|
};
|
|
}
|
|
|
|
/**
|
|
* React Component method that executes once component is mounted.
|
|
*
|
|
* @inheritdoc
|
|
* @returns {void}
|
|
*/
|
|
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.`);
|
|
|
|
this._interval
|
|
= setInterval(
|
|
() => {
|
|
if (this.state.timeLeft === 0) {
|
|
if (this._interval) {
|
|
clearInterval(this._interval);
|
|
this._interval = undefined;
|
|
}
|
|
|
|
this.props.dispatch(_reloadNow());
|
|
} else {
|
|
this.setState(prevState => {
|
|
return {
|
|
timeLeft: prevState.timeLeft - 1
|
|
};
|
|
});
|
|
}
|
|
},
|
|
1000);
|
|
}
|
|
|
|
/**
|
|
* Clears the timer interval.
|
|
*
|
|
* @inheritdoc
|
|
* @returns {void}
|
|
*/
|
|
componentWillUnmount() {
|
|
if (this._interval) {
|
|
clearInterval(this._interval);
|
|
this._interval = undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders the button for relaod the page if necessary.
|
|
*
|
|
* @protected
|
|
* @returns {ReactElement|null}
|
|
*/
|
|
_renderButton() {
|
|
if (this.props.isNetworkFailure) {
|
|
return (
|
|
<ReloadButton textKey = 'dialog.rejoinNow' />
|
|
);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Renders the progress bar.
|
|
*
|
|
* @protected
|
|
* @returns {ReactElement}
|
|
*/
|
|
_renderProgressBar() {
|
|
const { timeoutSeconds, timeLeft } = this.state;
|
|
const timeRemaining = timeoutSeconds - timeLeft;
|
|
const percentageComplete = Math.floor(
|
|
(timeRemaining / timeoutSeconds) * 100);
|
|
|
|
return (
|
|
<div
|
|
className = 'progress-indicator'
|
|
id = 'reloadProgressBar'>
|
|
<div
|
|
className = 'progress-indicator-fill'
|
|
style = {{
|
|
width: `${percentageComplete}%`
|
|
}} />
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Maps (parts of) the redux state to the associated component's props.
|
|
*
|
|
* @param {Object} state - The redux state.
|
|
* @returns {{
|
|
* isNetworkFailure: boolean,
|
|
* reason: string
|
|
* }}
|
|
* @protected
|
|
*/
|
|
export function abstractMapStateToProps(state: Object) {
|
|
const conferenceError = state['features/base/conference'].error;
|
|
const connectionError = state['features/base/connection'].error;
|
|
|
|
return {
|
|
isNetworkFailure: Boolean(connectionError),
|
|
reason: (connectionError || conferenceError).message
|
|
};
|
|
}
|