You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DialInSummary.web.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /* global config */
  2. import PropTypes from 'prop-types';
  3. import React, { Component } from 'react';
  4. import { translate } from '../../../base/i18n';
  5. import ConferenceID from './ConferenceID';
  6. import NumbersList from './NumbersList';
  7. /**
  8. * Displays a page listing numbers for dialing into a conference and pin to
  9. * the a specific conference.
  10. *
  11. * @extends Component
  12. */
  13. class DialInSummary extends Component {
  14. /**
  15. * {@code DialInSummary} component's property types.
  16. *
  17. * @static
  18. */
  19. static propTypes = {
  20. /**
  21. * Additional CSS classnames to append to the root of the component.
  22. */
  23. className: PropTypes.string,
  24. /**
  25. * Whether or not numbers should include links with the telephone
  26. * protocol.
  27. */
  28. clickableNumbers: PropTypes.bool,
  29. /**
  30. * The name of the conference to show a conferenceID for.
  31. */
  32. room: PropTypes.string,
  33. /**
  34. * Invoked to obtain translated strings.
  35. */
  36. t: PropTypes.func
  37. };
  38. /**
  39. * {@code DialInSummary} component's local state.
  40. *
  41. * @type {Object}
  42. * @property {number} conferenceID - The numeric ID of the conference, used
  43. * as a pin when dialing in.
  44. * @property {string} error - An error message to display.
  45. * @property {boolean} loading - Whether or not the app is fetching data.
  46. * @property {Array|Object} numbers - The dial-in numbers.
  47. * entered by the local participant.
  48. * @property {boolean} numbersEnabled - Whether or not dial-in is allowed.
  49. */
  50. state = {
  51. conferenceID: null,
  52. error: '',
  53. loading: true,
  54. numbers: null,
  55. numbersEnabled: null
  56. };
  57. /**
  58. * Initializes a new {@code DialInSummary} instance.
  59. *
  60. * @param {Object} props - The read-only properties with which the new
  61. * instance is to be initialized.
  62. */
  63. constructor(props) {
  64. super(props);
  65. // Bind event handlers so they are only bound once for every instance.
  66. this._onGetNumbersSuccess = this._onGetNumbersSuccess.bind(this);
  67. this._onGetConferenceIDSuccess
  68. = this._onGetConferenceIDSuccess.bind(this);
  69. this._setErrorMessage = this._setErrorMessage.bind(this);
  70. }
  71. /**
  72. * Implements {@link Component#componentDidMount()}. Invoked immediately
  73. * after this component is mounted.
  74. *
  75. * @inheritdoc
  76. * @returns {void}
  77. */
  78. componentDidMount() {
  79. const getNumbers = this._getNumbers()
  80. .then(this._onGetNumbersSuccess)
  81. .catch(this._setErrorMessage);
  82. const getID = this._getConferenceID()
  83. .then(this._onGetConferenceIDSuccess)
  84. .catch(this._setErrorMessage);
  85. Promise.all([ getNumbers, getID ])
  86. .then(() => {
  87. this.setState({ loading: false });
  88. });
  89. }
  90. /**
  91. * Implements React's {@link Component#render()}.
  92. *
  93. * @inheritdoc
  94. * @returns {ReactElement}
  95. */
  96. render() {
  97. let className = '';
  98. let contents;
  99. const { conferenceID, error, loading, numbersEnabled } = this.state;
  100. if (loading) {
  101. contents = '';
  102. } else if (numbersEnabled === false) {
  103. contents = this.props.t('info.dialInNotSupported');
  104. } else if (error) {
  105. contents = error;
  106. } else {
  107. className = 'has-numbers';
  108. contents = [
  109. conferenceID
  110. ? <ConferenceID
  111. conferenceID = { conferenceID }
  112. key = 'conferenceID' />
  113. : null,
  114. <NumbersList
  115. clickableNumbers = { this.props.clickableNumbers }
  116. key = 'numbers'
  117. numbers = { this.state.numbers } />
  118. ];
  119. }
  120. return (
  121. <div className = { `${this.props.className} ${className}` }>
  122. { contents }
  123. </div>
  124. );
  125. }
  126. /**
  127. * Creates an AJAX request for the conference ID.
  128. *
  129. * @private
  130. * @returns {Promise}
  131. */
  132. _getConferenceID() {
  133. const { room } = this.props;
  134. const { dialInConfCodeUrl, hosts } = config;
  135. const mucURL = hosts && hosts.muc;
  136. if (!dialInConfCodeUrl || !mucURL || !room) {
  137. return Promise.resolve();
  138. }
  139. const conferenceIDURL
  140. = `${dialInConfCodeUrl}?conference=${room}@${mucURL}`;
  141. return fetch(conferenceIDURL)
  142. .then(response => response.json())
  143. .catch(() => Promise.reject(this.props.t('info.genericError')));
  144. }
  145. /**
  146. * Creates an AJAX request for dial-in numbers.
  147. *
  148. * @private
  149. * @returns {Promise}
  150. */
  151. _getNumbers() {
  152. const { dialInNumbersUrl } = config;
  153. if (!dialInNumbersUrl) {
  154. return Promise.reject(this.props.t('info.dialInNotSupported'));
  155. }
  156. return fetch(dialInNumbersUrl)
  157. .then(response => response.json())
  158. .catch(() => Promise.reject(this.props.t('info.genericError')));
  159. }
  160. /**
  161. * Callback invoked when fetching the conference ID succeeds.
  162. *
  163. * @param {Object} response - The response from fetching the conference ID.
  164. * @private
  165. * @returns {void}
  166. */
  167. _onGetConferenceIDSuccess(response = {}) {
  168. const { conference, id } = response;
  169. if (!conference || !id) {
  170. return;
  171. }
  172. this.setState({ conferenceID: id });
  173. }
  174. /**
  175. * Callback invoked when fetching dial-in numbers succeeds. Sets the
  176. * internal to show the numbers.
  177. *
  178. * @param {Object} response - The response from fetching dial-in numbers.
  179. * @param {Array|Object} response.numbers - The dial-in numbers.
  180. * @param {boolean} reponse.numbersEnabled - Whether or not dial-in is
  181. * enabled.
  182. * @private
  183. * @returns {void}
  184. */
  185. _onGetNumbersSuccess({ numbers, numbersEnabled }) {
  186. this.setState({
  187. numbersEnabled,
  188. numbers
  189. });
  190. }
  191. /**
  192. * Sets an error message to display on the page instead of content.
  193. *
  194. * @param {string} error - The error message to display.
  195. * @private
  196. * @returns {void}
  197. */
  198. _setErrorMessage(error) {
  199. this.setState({
  200. error
  201. });
  202. }
  203. }
  204. export default translate(DialInSummary);