您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Toolbox.web.js 5.3KB

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