// @flow import React, { Component } from 'react'; import { translate } from '../../../../base/i18n'; import { doGetJSON } from '../../../../base/util'; import ConferenceID from './ConferenceID'; import NumbersList from './NumbersList'; declare var config: Object; /** * The type of the React {@code Component} props of {@link DialInSummary}. */ type Props = { /** * Additional CSS classnames to append to the root of the component. */ className: string, /** * Whether or not numbers should include links with the telephone protocol. */ 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, /** * The dial-in numbers to be displayed. */ numbers: ?Array | ?Object, /** * 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 { state = { conferenceID: null, error: '', loading: true, numbers: null, numbersEnabled: null }; /** * Initializes a new {@code DialInSummary} instance. * * @param {Object} props - The read-only properties with which the new * instance is to be initialized. */ constructor(props: Props) { 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() { let className = ''; let contents; const { conferenceID, error, loading, numbersEnabled } = this.state; if (loading) { contents = ''; } else if (numbersEnabled === false) { contents = this.props.t('info.dialInNotSupported'); } else if (error) { contents = error; } else { className = 'has-numbers'; contents = [ conferenceID ? : null, ]; } return (
{ contents }
); } /** * 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(); } return doGetJSON(`${dialInConfCodeUrl}?conference=${room}@${mucURL}`, true) .catch(() => Promise.reject(this.props.t('info.genericError'))); } /** * Creates an AJAX request for dial-in numbers. * * @private * @returns {Promise} */ _getNumbers() { const { room } = this.props; const { dialInNumbersUrl, hosts } = config; const mucURL = hosts && hosts.muc; let URLSuffix = ''; if (!dialInNumbersUrl) { return Promise.reject(this.props.t('info.dialInNotSupported')); } // when room and mucURL are available // provide conference when looking up dial in numbers if (room && mucURL) { URLSuffix = `?conference=${room}@${mucURL}`; } return doGetJSON(`${dialInNumbersUrl}${URLSuffix}`, true) .catch(() => Promise.reject(this.props.t('info.genericError'))); } _onGetConferenceIDSuccess: (Object) => void; /** * 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 }); } _onGetNumbersSuccess: (Object) => void; /** * Callback invoked when fetching dial-in numbers succeeds. Sets the * internal to show the numbers. * * @param {Array|Object} response - The response from fetching * dial-in numbers. * @param {Array|Object} response.numbers - The dial-in numbers. * @param {boolean} response.numbersEnabled - Whether or not dial-in is * enabled, old syntax that is deprecated. * @private * @returns {void} */ _onGetNumbersSuccess( response: Array | { numbersEnabled?: boolean }) { this.setState({ numbersEnabled: Array.isArray(response) ? response.length > 0 : response.numbersEnabled, numbers: response }); } _setErrorMessage: (string) => void; /** * 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 }); } } export default translate(DialInSummary);