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

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