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.

Toolbox.web.js 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* @flow */
  2. import PropTypes from 'prop-types';
  3. import React, { Component } from 'react';
  4. import { connect } from 'react-redux';
  5. import {
  6. setDefaultToolboxButtons
  7. } from '../actions';
  8. import {
  9. abstractMapStateToProps
  10. } from '../functions';
  11. import Notice from './Notice';
  12. import PrimaryToolbar from './PrimaryToolbar';
  13. import SecondaryToolbar from './SecondaryToolbar';
  14. declare var APP: Object;
  15. declare var config: Object;
  16. declare var interfaceConfig: Object;
  17. /**
  18. * Implements the conference toolbox on React/Web.
  19. */
  20. class Toolbox extends Component<*> {
  21. /**
  22. * App component's property types.
  23. *
  24. * @static
  25. */
  26. static propTypes = {
  27. /**
  28. * Indicates if the toolbox should always be visible.
  29. */
  30. _alwaysVisible: PropTypes.bool,
  31. /**
  32. * Handler dispatching setting default buttons action.
  33. */
  34. _setDefaultToolboxButtons: PropTypes.func,
  35. /**
  36. * Represents conference subject.
  37. */
  38. _subject: PropTypes.string,
  39. /**
  40. * Flag showing whether to set subject slide in animation.
  41. */
  42. _subjectSlideIn: PropTypes.bool,
  43. /**
  44. * Property containing toolbox timeout id.
  45. */
  46. _timeoutID: PropTypes.number
  47. };
  48. /**
  49. * Invokes reset always visible toolbox after mounting the component and
  50. * registers legacy UI listeners.
  51. *
  52. * @returns {void}
  53. */
  54. componentDidMount(): void {
  55. // FIXME The redux action SET_DEFAULT_TOOLBOX_BUTTONS and related source
  56. // code such as the redux action creator setDefaultToolboxButtons and
  57. // _setDefaultToolboxButtons were introduced to solve the following bug
  58. // in the implementation of features/toolbar at the time of this
  59. // writing: getDefaultToolboxButtons uses interfaceConfig which is not
  60. // in the redux store at the time of this writing yet interfaceConfig is
  61. // modified after getDefaultToolboxButtons is called.
  62. // SET_DEFAULT_TOOLBOX_BUTTONS represents/implements an explicit delay
  63. // of the invocation of getDefaultToolboxButtons until, heuristically,
  64. // all existing changes to interfaceConfig have been applied already in
  65. // our known execution paths.
  66. this.props._setDefaultToolboxButtons();
  67. }
  68. /**
  69. * Implements React's {@link Component#render()}.
  70. *
  71. * @inheritdoc
  72. * @returns {ReactElement}
  73. */
  74. render(): React$Element<*> {
  75. return (
  76. <div className = 'toolbox'>
  77. {
  78. this._renderSubject()
  79. }
  80. {
  81. this._renderToolbars()
  82. }
  83. <div id = 'sideToolbarContainer' />
  84. </div>
  85. );
  86. }
  87. /**
  88. * Returns React element representing toolbox subject.
  89. *
  90. * @returns {ReactElement}
  91. * @private
  92. */
  93. _renderSubject(): React$Element<*> | null {
  94. const { _subjectSlideIn, _subject } = this.props;
  95. const classNames = [ 'subject' ];
  96. if (!_subject) {
  97. return null;
  98. }
  99. if (_subjectSlideIn) {
  100. classNames.push('subject_slide-in');
  101. } else {
  102. classNames.push('subject_slide-out');
  103. }
  104. // XXX: Since chat is now not reactified we have to dangerously set
  105. // inner HTML into the component. This has to be refactored while
  106. // reactification of the Chat.js
  107. const innerHtml = {
  108. __html: _subject
  109. };
  110. return (
  111. <div
  112. className = { classNames.join(' ') }
  113. // eslint-disable-next-line react/no-danger
  114. dangerouslySetInnerHTML = { innerHtml }
  115. id = 'subject' />
  116. );
  117. }
  118. /**
  119. * Renders primary and secondary toolbars.
  120. *
  121. * @returns {ReactElement}
  122. * @private
  123. */
  124. _renderToolbars(): React$Element<*> | null {
  125. // In case we're not in alwaysVisible mode the toolbox should not be
  126. // shown until timeoutID is initialized.
  127. if (!this.props._alwaysVisible && this.props._timeoutID === null) {
  128. return null;
  129. }
  130. return (
  131. <div className = 'toolbox-toolbars'>
  132. <Notice />
  133. <PrimaryToolbar />
  134. <SecondaryToolbar />
  135. </div>
  136. );
  137. }
  138. }
  139. /**
  140. * Maps parts of Redux actions to component props.
  141. *
  142. * @param {Function} dispatch - Redux action dispatcher.
  143. * @returns {{
  144. * _setDefaultToolboxButtons: Function
  145. * }}
  146. * @private
  147. */
  148. function _mapDispatchToProps(dispatch: Function): Object {
  149. return {
  150. /**
  151. * Dispatches a (redux) action to set the default toolbar buttons.
  152. *
  153. * @returns {Object} Dispatched action.
  154. */
  155. _setDefaultToolboxButtons() {
  156. dispatch(setDefaultToolboxButtons());
  157. }
  158. };
  159. }
  160. /**
  161. * Maps parts of toolbox state to component props.
  162. *
  163. * @param {Object} state - Redux state.
  164. * @private
  165. * @returns {{
  166. * _alwaysVisible: boolean,
  167. * _audioMuted: boolean,
  168. * _subjectSlideIn: boolean,
  169. * _videoMuted: boolean
  170. * }}
  171. */
  172. function _mapStateToProps(state: Object): Object {
  173. const {
  174. alwaysVisible,
  175. subject,
  176. subjectSlideIn,
  177. timeoutID
  178. } = state['features/toolbox'];
  179. return {
  180. ...abstractMapStateToProps(state),
  181. /**
  182. * Indicates if the toolbox should always be visible.
  183. *
  184. * @private
  185. * @type {boolean}
  186. */
  187. _alwaysVisible: alwaysVisible,
  188. /**
  189. * Property containing conference subject.
  190. *
  191. * @private
  192. * @type {string}
  193. */
  194. _subject: subject,
  195. /**
  196. * Flag showing whether to set subject slide in animation.
  197. *
  198. * @private
  199. * @type {boolean}
  200. */
  201. _subjectSlideIn: subjectSlideIn,
  202. /**
  203. * Property containing toolbox timeout id.
  204. *
  205. * @private
  206. * @type {number}
  207. */
  208. _timeoutID: timeoutID
  209. };
  210. }
  211. export default connect(_mapStateToProps, _mapDispatchToProps)(Toolbox);