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

Toolbar.web.js 5.3KB

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