2019-05-07 14:50:57 +00:00
|
|
|
// @flow
|
2018-02-13 19:46:47 +00:00
|
|
|
|
|
|
|
import React, { Component } from 'react';
|
|
|
|
|
2019-05-07 14:50:57 +00:00
|
|
|
import { translate } from '../../../../base/i18n';
|
2018-02-13 19:46:47 +00:00
|
|
|
|
|
|
|
import ConferenceID from './ConferenceID';
|
|
|
|
import NumbersList from './NumbersList';
|
|
|
|
|
2018-10-30 05:02:23 +00:00
|
|
|
declare var config: Object;
|
|
|
|
|
2018-02-13 19:46:47 +00:00
|
|
|
/**
|
2018-10-30 05:02:23 +00:00
|
|
|
* The type of the React {@code Component} props of {@link DialInSummary}.
|
2018-02-13 19:46:47 +00:00
|
|
|
*/
|
2018-10-30 05:02:23 +00:00
|
|
|
type Props = {
|
|
|
|
|
2018-02-13 19:46:47 +00:00
|
|
|
/**
|
2018-10-30 05:02:23 +00:00
|
|
|
* Additional CSS classnames to append to the root of the component.
|
|
|
|
*/
|
|
|
|
className: string,
|
2018-02-13 19:46:47 +00:00
|
|
|
|
|
|
|
/**
|
2018-10-30 05:02:23 +00:00
|
|
|
* Whether or not numbers should include links with the telephone protocol.
|
2018-02-13 19:46:47 +00:00
|
|
|
*/
|
2018-10-30 05:02:23 +00:00
|
|
|
clickableNumbers: boolean,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The name of the conference to show a conferenceID for.
|
|
|
|
*/
|
|
|
|
room: string,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Invoked to obtain translated strings.
|
|
|
|
*/
|
|
|
|
t: Function
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The type of the React {@code Component} state of {@link DialInSummary}.
|
|
|
|
*/
|
|
|
|
type State = {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The numeric ID of the conference, used as a pin when dialing in.
|
|
|
|
*/
|
|
|
|
conferenceID: ?string,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An error message to display.
|
|
|
|
*/
|
|
|
|
error: string,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not the app is fetching data.
|
|
|
|
*/
|
|
|
|
loading: boolean,
|
|
|
|
|
|
|
|
/**
|
2019-02-26 13:32:46 +00:00
|
|
|
* The dial-in numbers to be displayed.
|
2018-10-30 05:02:23 +00:00
|
|
|
*/
|
2019-02-26 13:32:46 +00:00
|
|
|
numbers: ?Array<Object> | ?Object,
|
2018-10-30 05:02:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not dial-in is allowed.
|
|
|
|
*/
|
|
|
|
numbersEnabled: ?boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Displays a page listing numbers for dialing into a conference and pin to
|
|
|
|
* the a specific conference.
|
|
|
|
*
|
|
|
|
* @extends Component
|
|
|
|
*/
|
|
|
|
class DialInSummary extends Component<Props, State> {
|
2018-02-13 19:46:47 +00:00
|
|
|
state = {
|
|
|
|
conferenceID: null,
|
|
|
|
error: '',
|
|
|
|
loading: true,
|
|
|
|
numbers: null,
|
|
|
|
numbersEnabled: null
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2018-02-21 01:25:22 +00:00
|
|
|
* Initializes a new {@code DialInSummary} instance.
|
2018-02-13 19:46:47 +00:00
|
|
|
*
|
|
|
|
* @param {Object} props - The read-only properties with which the new
|
|
|
|
* instance is to be initialized.
|
|
|
|
*/
|
2018-10-30 05:02:23 +00:00
|
|
|
constructor(props: Props) {
|
2018-02-13 19:46:47 +00:00
|
|
|
super(props);
|
|
|
|
|
|
|
|
// Bind event handlers so they are only bound once for every instance.
|
|
|
|
this._onGetNumbersSuccess = this._onGetNumbersSuccess.bind(this);
|
|
|
|
this._onGetConferenceIDSuccess
|
|
|
|
= this._onGetConferenceIDSuccess.bind(this);
|
|
|
|
this._setErrorMessage = this._setErrorMessage.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements {@link Component#componentDidMount()}. Invoked immediately
|
|
|
|
* after this component is mounted.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
componentDidMount() {
|
|
|
|
const getNumbers = this._getNumbers()
|
|
|
|
.then(this._onGetNumbersSuccess)
|
|
|
|
.catch(this._setErrorMessage);
|
|
|
|
|
|
|
|
const getID = this._getConferenceID()
|
|
|
|
.then(this._onGetConferenceIDSuccess)
|
|
|
|
.catch(this._setErrorMessage);
|
|
|
|
|
|
|
|
Promise.all([ getNumbers, getID ])
|
|
|
|
.then(() => {
|
|
|
|
this.setState({ loading: false });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements React's {@link Component#render()}.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {ReactElement}
|
|
|
|
*/
|
|
|
|
render() {
|
2018-02-21 01:25:22 +00:00
|
|
|
let className = '';
|
2018-02-13 19:46:47 +00:00
|
|
|
let contents;
|
|
|
|
|
|
|
|
const { conferenceID, error, loading, numbersEnabled } = this.state;
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
contents = '';
|
|
|
|
} else if (numbersEnabled === false) {
|
2018-02-17 19:53:39 +00:00
|
|
|
contents = this.props.t('info.dialInNotSupported');
|
2018-02-13 19:46:47 +00:00
|
|
|
} else if (error) {
|
|
|
|
contents = error;
|
|
|
|
} else {
|
2018-02-21 01:25:22 +00:00
|
|
|
className = 'has-numbers';
|
2018-02-13 19:46:47 +00:00
|
|
|
contents = [
|
|
|
|
conferenceID
|
|
|
|
? <ConferenceID
|
|
|
|
conferenceID = { conferenceID }
|
2019-02-26 13:32:46 +00:00
|
|
|
conferenceName = { this.props.room }
|
2018-02-13 19:46:47 +00:00
|
|
|
key = 'conferenceID' />
|
|
|
|
: null,
|
|
|
|
<NumbersList
|
2018-02-21 01:25:22 +00:00
|
|
|
clickableNumbers = { this.props.clickableNumbers }
|
2018-04-14 00:00:40 +00:00
|
|
|
conferenceID = { conferenceID }
|
2018-02-13 19:46:47 +00:00
|
|
|
key = 'numbers'
|
|
|
|
numbers = { this.state.numbers } />
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2018-02-21 01:25:22 +00:00
|
|
|
<div className = { `${this.props.className} ${className}` }>
|
2018-02-13 19:46:47 +00:00
|
|
|
{ contents }
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an AJAX request for the conference ID.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
|
|
|
_getConferenceID() {
|
|
|
|
const { room } = this.props;
|
|
|
|
const { dialInConfCodeUrl, hosts } = config;
|
|
|
|
const mucURL = hosts && hosts.muc;
|
|
|
|
|
|
|
|
if (!dialInConfCodeUrl || !mucURL || !room) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
const conferenceIDURL
|
|
|
|
= `${dialInConfCodeUrl}?conference=${room}@${mucURL}`;
|
|
|
|
|
|
|
|
return fetch(conferenceIDURL)
|
|
|
|
.then(response => response.json())
|
|
|
|
.catch(() => Promise.reject(this.props.t('info.genericError')));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an AJAX request for dial-in numbers.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @returns {Promise}
|
|
|
|
*/
|
|
|
|
_getNumbers() {
|
2019-02-02 03:10:34 +00:00
|
|
|
const { room } = this.props;
|
|
|
|
const { dialInNumbersUrl, hosts } = config;
|
|
|
|
const mucURL = hosts && hosts.muc;
|
|
|
|
let URLSuffix = '';
|
2018-02-13 19:46:47 +00:00
|
|
|
|
|
|
|
if (!dialInNumbersUrl) {
|
|
|
|
return Promise.reject(this.props.t('info.dialInNotSupported'));
|
|
|
|
}
|
|
|
|
|
2019-02-02 03:10:34 +00:00
|
|
|
// when room and mucURL are available
|
|
|
|
// provide conference when looking up dial in numbers
|
|
|
|
|
|
|
|
if (room && mucURL) {
|
|
|
|
URLSuffix = `?conference=${room}@${mucURL}`;
|
|
|
|
}
|
|
|
|
const conferenceIDURL
|
|
|
|
= `${dialInNumbersUrl}${URLSuffix}`;
|
|
|
|
|
|
|
|
return fetch(conferenceIDURL)
|
2018-02-13 19:46:47 +00:00
|
|
|
.then(response => response.json())
|
|
|
|
.catch(() => Promise.reject(this.props.t('info.genericError')));
|
|
|
|
}
|
|
|
|
|
2018-10-30 05:02:23 +00:00
|
|
|
_onGetConferenceIDSuccess: (Object) => void;
|
|
|
|
|
2018-02-13 19:46:47 +00:00
|
|
|
/**
|
|
|
|
* Callback invoked when fetching the conference ID succeeds.
|
|
|
|
*
|
|
|
|
* @param {Object} response - The response from fetching the conference ID.
|
|
|
|
* @private
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
_onGetConferenceIDSuccess(response = {}) {
|
|
|
|
const { conference, id } = response;
|
|
|
|
|
|
|
|
if (!conference || !id) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({ conferenceID: id });
|
|
|
|
}
|
|
|
|
|
2018-10-30 05:02:23 +00:00
|
|
|
_onGetNumbersSuccess: (Object) => void;
|
|
|
|
|
2018-02-13 19:46:47 +00:00
|
|
|
/**
|
|
|
|
* Callback invoked when fetching dial-in numbers succeeds. Sets the
|
|
|
|
* internal to show the numbers.
|
|
|
|
*
|
2019-02-26 13:32:46 +00:00
|
|
|
* @param {Array|Object} response - The response from fetching
|
|
|
|
* dial-in numbers.
|
2018-02-13 19:46:47 +00:00
|
|
|
* @param {Array|Object} response.numbers - The dial-in numbers.
|
2019-02-26 13:32:46 +00:00
|
|
|
* @param {boolean} response.numbersEnabled - Whether or not dial-in is
|
|
|
|
* enabled, old syntax that is deprecated.
|
2018-02-13 19:46:47 +00:00
|
|
|
* @private
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2019-02-26 13:32:46 +00:00
|
|
|
_onGetNumbersSuccess(
|
|
|
|
response: Array<Object> | { numbersEnabled?: boolean }) {
|
|
|
|
|
2018-02-13 19:46:47 +00:00
|
|
|
this.setState({
|
2019-02-26 13:32:46 +00:00
|
|
|
numbersEnabled:
|
|
|
|
Array.isArray(response)
|
|
|
|
? response.length > 0 : response.numbersEnabled,
|
|
|
|
numbers: response
|
2018-02-13 19:46:47 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-10-30 05:02:23 +00:00
|
|
|
_setErrorMessage: (string) => void;
|
|
|
|
|
2018-02-13 19:46:47 +00:00
|
|
|
/**
|
|
|
|
* Sets an error message to display on the page instead of content.
|
|
|
|
*
|
|
|
|
* @param {string} error - The error message to display.
|
|
|
|
* @private
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
_setErrorMessage(error) {
|
|
|
|
this.setState({
|
|
|
|
error
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-21 01:25:22 +00:00
|
|
|
export default translate(DialInSummary);
|