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

SecondaryToolbar.web.js 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* @flow */
  2. import React, { Component } from 'react';
  3. import { connect } from 'react-redux';
  4. import { FeedbackButton } from '../../feedback';
  5. import UIEvents from '../../../../service/UI/UIEvents';
  6. import {
  7. changeLocalRaiseHand,
  8. setProfileButtonUnclickable,
  9. showRecordingButton,
  10. toggleSideToolbarContainer
  11. } from '../actions';
  12. import Toolbar from './Toolbar';
  13. import { getToolbarClassNames } from '../functions';
  14. declare var APP: Object;
  15. declare var config: Object;
  16. /**
  17. * Implementation of secondary toolbar React component.
  18. *
  19. * @class SecondaryToolbar
  20. * @extends Component
  21. */
  22. class SecondaryToolbar extends Component {
  23. state: Object;
  24. /**
  25. * Secondary toolbar property types.
  26. *
  27. * @static
  28. */
  29. static propTypes = {
  30. /**
  31. * Handler dispatching local "Raise hand".
  32. */
  33. _onLocalRaiseHandChanged: React.PropTypes.func,
  34. /**
  35. * Handler setting profile button unclickable.
  36. */
  37. _onSetProfileButtonUnclickable: React.PropTypes.func,
  38. /**
  39. * Handler for showing recording button.
  40. */
  41. _onShowRecordingButton: React.PropTypes.func,
  42. /**
  43. * Handler dispatching toggle toolbar container.
  44. */
  45. _onSideToolbarContainerToggled: React.PropTypes.func,
  46. /**
  47. * Contains map of secondary toolbar buttons.
  48. */
  49. _secondaryToolbarButtons: React.PropTypes.instanceOf(Map),
  50. /**
  51. * Shows whether toolbox is visible.
  52. */
  53. _visible: React.PropTypes.bool
  54. };
  55. /**
  56. * Constructs instance of SecondaryToolbar component.
  57. *
  58. * @param {Object} props - React component properties.
  59. */
  60. constructor(props) {
  61. super(props);
  62. const buttonHandlers = {
  63. /**
  64. * Mount handler for profile button.
  65. *
  66. * @type {Object}
  67. */
  68. profile: {
  69. onMount: () => {
  70. APP.tokenData.isGuest
  71. || this.props._onSetProfileButtonUnclickable(true);
  72. }
  73. },
  74. /**
  75. * Mount/Unmount handlers for raisehand button.
  76. *
  77. * @type {button}
  78. */
  79. raisehand: {
  80. onMount: () => {
  81. APP.UI.addListener(UIEvents.LOCAL_RAISE_HAND_CHANGED,
  82. this.props._onLocalRaiseHandChanged);
  83. },
  84. onUnmount: () => {
  85. APP.UI.removeListener(UIEvents.LOCAL_RAISE_HAND_CHANGED,
  86. this.props._onLocalRaiseHandChanged);
  87. }
  88. },
  89. /**
  90. * Mount handler for recording button.
  91. *
  92. * @type {Object}
  93. */
  94. recording: {
  95. onMount: () => {
  96. if (config.enableRecording) {
  97. this.props._onShowRecordingButton();
  98. }
  99. }
  100. }
  101. };
  102. this.state = {
  103. /**
  104. * Object containing on mount/unmount handlers for toolbar buttons.
  105. *
  106. * @type {Object}
  107. */
  108. buttonHandlers
  109. };
  110. }
  111. /**
  112. * Register legacy UI listener.
  113. *
  114. * @returns {void}
  115. */
  116. componentDidMount(): void {
  117. APP.UI.addListener(UIEvents.SIDE_TOOLBAR_CONTAINER_TOGGLED,
  118. this.props._onSideToolbarContainerToggled);
  119. }
  120. /**
  121. * Unregisters legacy UI listener.
  122. *
  123. * @returns {void}
  124. */
  125. componentWillUnmount(): void {
  126. APP.UI.removeListener(UIEvents.SIDE_TOOLBAR_CONTAINER_TOGGLED,
  127. this.props._onSideToolbarContainerToggled);
  128. }
  129. /**
  130. * Renders secondary toolbar component.
  131. *
  132. * @returns {ReactElement}
  133. */
  134. render(): ReactElement<*> | null {
  135. const { _secondaryToolbarButtons } = this.props;
  136. // The number of buttons to show in the toolbar isn't fixed, it depends
  137. // on availability of features and configuration parameters, so if we
  138. // don't have anything to render we exit here.
  139. if (_secondaryToolbarButtons.size === 0) {
  140. return null;
  141. }
  142. const { buttonHandlers } = this.state;
  143. const { secondaryToolbarClassName } = getToolbarClassNames(this.props);
  144. return (
  145. <Toolbar
  146. buttonHandlers = { buttonHandlers }
  147. className = { secondaryToolbarClassName }
  148. toolbarButtons = { _secondaryToolbarButtons }>
  149. <FeedbackButton />
  150. </Toolbar>
  151. );
  152. }
  153. }
  154. /**
  155. * Maps some of Redux actions to component's props.
  156. *
  157. * @param {Function} dispatch - Redux action dispatcher.
  158. * @returns {{
  159. * _onLocalRaiseHandChanged: Function,
  160. * _onSetProfileButtonUnclickable: Function,
  161. * _onShowRecordingButton: Function,
  162. * _onSideToolbarContainerToggled
  163. * }}
  164. * @private
  165. */
  166. function _mapDispatchToProps(dispatch: Function): Object {
  167. return {
  168. /**
  169. * Dispatches an action that 'hand' is raised.
  170. *
  171. * @param {boolean} isRaisedHand - Show whether hand is raised.
  172. * @returns {Object} Dispatched action.
  173. */
  174. _onLocalRaiseHandChanged(isRaisedHand: boolean) {
  175. return dispatch(changeLocalRaiseHand(isRaisedHand));
  176. },
  177. /**
  178. * Dispatches an action signalling to set profile button unclickable.
  179. *
  180. * @param {boolean} unclickable - Flag showing whether unclickable
  181. * property is true.
  182. * @returns {Object} Dispatched action.
  183. */
  184. _onSetProfileButtonUnclickable(unclickable: boolean) {
  185. return dispatch(setProfileButtonUnclickable(unclickable));
  186. },
  187. /**
  188. * Dispatches an action signalling that recording button should be
  189. * shown.
  190. *
  191. * @returns {Object} Dispatched action.
  192. */
  193. _onShowRecordingButton() {
  194. return dispatch(showRecordingButton());
  195. },
  196. /**
  197. * Dispatches an action signalling that side toolbar container is
  198. * toggled.
  199. *
  200. * @param {string} containerId - Id of side toolbar container.
  201. * @returns {Object} Dispatched action.
  202. */
  203. _onSideToolbarContainerToggled(containerId: string) {
  204. return dispatch(toggleSideToolbarContainer(containerId));
  205. }
  206. };
  207. }
  208. /**
  209. * Maps part of Redux state to component's props.
  210. *
  211. * @param {Object} state - Snapshot of Redux store.
  212. * @returns {{
  213. * _secondaryToolbarButtons: Map,
  214. * _visible: boolean
  215. * }}
  216. * @private
  217. */
  218. function _mapStateToProps(state: Object): Object {
  219. const {
  220. secondaryToolbarButtons,
  221. visible
  222. } = state['features/toolbox'];
  223. return {
  224. /**
  225. * Default toolbar buttons for secondary toolbar.
  226. *
  227. * @protected
  228. * @type {Map}
  229. */
  230. _secondaryToolbarButtons: secondaryToolbarButtons,
  231. /**
  232. * Shows whether toolbar is visible.
  233. *
  234. * @protected
  235. * @type {boolean}
  236. */
  237. _visible: visible
  238. };
  239. }
  240. export default connect(_mapStateToProps, _mapDispatchToProps)(SecondaryToolbar);