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.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. conferenceID = { conferenceID }
  117. key = 'numbers'
  118. numbers = { this.state.numbers } />
  119. ];
  120. }
  121. return (
  122. <div className = { `${this.props.className} ${className}` }>
  123. { contents }
  124. </div>
  125. );
  126. }
  127. /**
  128. * Creates an AJAX request for the conference ID.
  129. *
  130. * @private
  131. * @returns {Promise}
  132. */
  133. _getConferenceID() {
  134. const { room } = this.props;
  135. const { dialInConfCodeUrl, hosts } = config;
  136. const mucURL = hosts && hosts.muc;
  137. if (!dialInConfCodeUrl || !mucURL || !room) {
  138. return Promise.resolve();
  139. }
  140. const conferenceIDURL
  141. = `${dialInConfCodeUrl}?conference=${room}@${mucURL}`;
  142. return fetch(conferenceIDURL)
  143. .then(response => response.json())
  144. .catch(() => Promise.reject(this.props.t('info.genericError')));
  145. }
  146. /**
  147. * Creates an AJAX request for dial-in numbers.
  148. *
  149. * @private
  150. * @returns {Promise}
  151. */
  152. _getNumbers() {
  153. const { dialInNumbersUrl } = config;
  154. if (!dialInNumbersUrl) {
  155. return Promise.reject(this.props.t('info.dialInNotSupported'));
  156. }
  157. return fetch(dialInNumbersUrl)
  158. .then(response => response.json())
  159. .catch(() => Promise.reject(this.props.t('info.genericError')));
  160. }
  161. /**
  162. * Callback invoked when fetching the conference ID succeeds.
  163. *
  164. * @param {Object} response - The response from fetching the conference ID.
  165. * @private
  166. * @returns {void}
  167. */
  168. _onGetConferenceIDSuccess(response = {}) {
  169. const { conference, id } = response;
  170. if (!conference || !id) {
  171. return;
  172. }
  173. this.setState({ conferenceID: id });
  174. }
  175. /**
  176. * Callback invoked when fetching dial-in numbers succeeds. Sets the
  177. * internal to show the numbers.
  178. *
  179. * @param {Object} response - The response from fetching dial-in numbers.
  180. * @param {Array|Object} response.numbers - The dial-in numbers.
  181. * @param {boolean} reponse.numbersEnabled - Whether or not dial-in is
  182. * enabled.
  183. * @private
  184. * @returns {void}
  185. */
  186. _onGetNumbersSuccess({ numbers, numbersEnabled }) {
  187. this.setState({
  188. numbersEnabled,
  189. numbers
  190. });
  191. }
  192. /**
  193. * Sets an error message to display on the page instead of content.
  194. *
  195. * @param {string} error - The error message to display.
  196. * @private
  197. * @returns {void}
  198. */
  199. _setErrorMessage(error) {
  200. this.setState({
  201. error
  202. });
  203. }
  204. }
  205. export default translate(DialInSummary);