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

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