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.

AbstractPageReloadOverlay.js 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* @flow */
  2. import PropTypes from 'prop-types';
  3. import React, { Component } from 'react';
  4. import { randomInt } from '../../base/util';
  5. import { _reloadNow } from '../actions';
  6. import ReloadButton from './ReloadButton';
  7. declare var AJS: Object;
  8. declare var APP: Object;
  9. const logger = require('jitsi-meet-logger').getLogger(__filename);
  10. /**
  11. * Implements abstract React Component for the page reload overlays.
  12. */
  13. export default class AbstractPageReloadOverlay extends Component<*, *> {
  14. /**
  15. * AbstractPageReloadOverlay component's property types.
  16. *
  17. * @static
  18. */
  19. static propTypes = {
  20. dispatch: PropTypes.func,
  21. /**
  22. * The indicator which determines whether the reload was caused by
  23. * network failure.
  24. *
  25. * @public
  26. * @type {boolean}
  27. */
  28. isNetworkFailure: PropTypes.bool,
  29. /**
  30. * The reason for the error that will cause the reload.
  31. * NOTE: Used by PageReloadOverlay only.
  32. *
  33. * @public
  34. * @type {string}
  35. */
  36. reason: PropTypes.string,
  37. /**
  38. * The function to translate human-readable text.
  39. *
  40. * @public
  41. * @type {Function}
  42. */
  43. t: PropTypes.func
  44. };
  45. _interval: ?number
  46. state: {
  47. /**
  48. * The translation key for the title of the overlay.
  49. *
  50. * @type {string}
  51. */
  52. message: string,
  53. /**
  54. * Current value(time) of the timer.
  55. *
  56. * @type {number}
  57. */
  58. timeLeft: number,
  59. /**
  60. * How long the overlay dialog will be displayed before the
  61. * conference will be reloaded.
  62. *
  63. * @type {number}
  64. */
  65. timeoutSeconds: number,
  66. /**
  67. * The translation key for the title of the overlay.
  68. *
  69. * @type {string}
  70. */
  71. title: string
  72. }
  73. /**
  74. * Initializes a new AbstractPageReloadOverlay instance.
  75. *
  76. * @param {Object} props - The read-only properties with which the new
  77. * instance is to be initialized.
  78. * @public
  79. */
  80. constructor(props: Object) {
  81. super(props);
  82. /**
  83. * How long the overlay dialog will be displayed, before the conference
  84. * will be reloaded.
  85. *
  86. * @type {number}
  87. */
  88. const timeoutSeconds = 10 + randomInt(0, 20);
  89. let message, title;
  90. if (this.props.isNetworkFailure) {
  91. title = 'dialog.conferenceDisconnectTitle';
  92. message = 'dialog.conferenceDisconnectMsg';
  93. } else {
  94. title = 'dialog.conferenceReloadTitle';
  95. message = 'dialog.conferenceReloadMsg';
  96. }
  97. this.state = {
  98. message,
  99. timeLeft: timeoutSeconds,
  100. timeoutSeconds,
  101. title
  102. };
  103. }
  104. /**
  105. * React Component method that executes once component is mounted.
  106. *
  107. * @inheritdoc
  108. * @returns {void}
  109. */
  110. componentDidMount() {
  111. // FIXME (CallStats - issue) This event will not make it to CallStats
  112. // because the log queue is not flushed before "fabric terminated" is
  113. // sent to the backed.
  114. // FIXME: We should dispatch action for this.
  115. APP.conference.logEvent(
  116. 'page.reload',
  117. /* value */ undefined,
  118. /* label */ this.props.reason);
  119. logger.info(
  120. `The conference will be reloaded after ${
  121. this.state.timeoutSeconds} seconds.`);
  122. AJS.progressBars.update('#reloadProgressBar', 0);
  123. this._interval
  124. = setInterval(
  125. () => {
  126. if (this.state.timeLeft === 0) {
  127. if (this._interval) {
  128. clearInterval(this._interval);
  129. this._interval = undefined;
  130. }
  131. this.props.dispatch(_reloadNow());
  132. } else {
  133. this.setState(prevState => {
  134. return {
  135. timeLeft: prevState.timeLeft - 1
  136. };
  137. });
  138. }
  139. },
  140. 1000);
  141. }
  142. /**
  143. * React Component method that executes once component is updated.
  144. *
  145. * @inheritdoc
  146. * @returns {void}
  147. */
  148. componentDidUpdate() {
  149. const { timeLeft, timeoutSeconds } = this.state;
  150. AJS.progressBars.update(
  151. '#reloadProgressBar',
  152. (timeoutSeconds - timeLeft) / timeoutSeconds);
  153. }
  154. /**
  155. * Clears the timer interval.
  156. *
  157. * @inheritdoc
  158. * @returns {void}
  159. */
  160. componentWillUnmount() {
  161. if (this._interval) {
  162. clearInterval(this._interval);
  163. this._interval = undefined;
  164. }
  165. }
  166. /**
  167. * Renders the button for relaod the page if necessary.
  168. *
  169. * @protected
  170. * @returns {ReactElement|null}
  171. */
  172. _renderButton() {
  173. if (this.props.isNetworkFailure) {
  174. return (
  175. <ReloadButton textKey = 'dialog.rejoinNow' />
  176. );
  177. }
  178. return null;
  179. }
  180. /**
  181. * Renders the progress bar.
  182. *
  183. * @protected
  184. * @returns {ReactElement}
  185. */
  186. _renderProgressBar() {
  187. return (
  188. <div
  189. className = 'aui-progress-indicator'
  190. id = 'reloadProgressBar'>
  191. <span className = 'aui-progress-indicator-value' />
  192. </div>
  193. );
  194. }
  195. }