123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /* @flow */
-
- import PropTypes from 'prop-types';
- import React, { Component } from 'react';
- import { connect } from 'react-redux';
-
- import {
- setDefaultToolboxButtons,
- setToolboxAlwaysVisible
- } from '../actions';
- import {
- abstractMapStateToProps
- } from '../functions';
- import Notice from './Notice';
- import PrimaryToolbar from './PrimaryToolbar';
- import SecondaryToolbar from './SecondaryToolbar';
-
- declare var APP: Object;
- declare var config: Object;
- declare var interfaceConfig: Object;
-
- /**
- * Implements the conference toolbox on React/Web.
- */
- class Toolbox extends Component<*> {
- /**
- * App component's property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * Indicates if the toolbox should always be visible.
- */
- _alwaysVisible: PropTypes.bool,
-
- /**
- * Handler dispatching setting default buttons action.
- */
- _setDefaultToolboxButtons: PropTypes.func,
-
- /**
- * Handler dispatching reset always visible toolbox action.
- */
- _setToolboxAlwaysVisible: PropTypes.func,
-
- /**
- * Represents conference subject.
- */
- _subject: PropTypes.string,
-
- /**
- * Flag showing whether to set subject slide in animation.
- */
- _subjectSlideIn: PropTypes.bool,
-
- /**
- * Property containing toolbox timeout id.
- */
- _timeoutID: PropTypes.number
- };
-
- /**
- * Invokes reset always visible toolbox after mounting the component and
- * registers legacy UI listeners.
- *
- * @returns {void}
- */
- componentDidMount(): void {
- this.props._setToolboxAlwaysVisible();
-
- // FIXME The redux action SET_DEFAULT_TOOLBOX_BUTTONS and related source
- // code such as the redux action creator setDefaultToolboxButtons and
- // _setDefaultToolboxButtons were introduced to solve the following bug
- // in the implementation of features/toolbar at the time of this
- // writing: getDefaultToolboxButtons uses interfaceConfig which is not
- // in the redux store at the time of this writing yet interfaceConfig is
- // modified after getDefaultToolboxButtons is called.
- // SET_DEFAULT_TOOLBOX_BUTTONS represents/implements an explicit delay
- // of the invocation of getDefaultToolboxButtons until, heuristically,
- // all existing changes to interfaceConfig have been applied already in
- // our known execution paths.
- this.props._setDefaultToolboxButtons();
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render(): React$Element<*> {
- return (
- <div className = 'toolbox'>
- {
- this._renderSubject()
- }
- {
- this._renderToolbars()
- }
- <div id = 'sideToolbarContainer' />
- </div>
- );
- }
-
- /**
- * Returns React element representing toolbox subject.
- *
- * @returns {ReactElement}
- * @private
- */
- _renderSubject(): React$Element<*> | null {
- const { _subjectSlideIn, _subject } = this.props;
- const classNames = [ 'subject' ];
-
- if (!_subject) {
- return null;
- }
-
- if (_subjectSlideIn) {
- classNames.push('subject_slide-in');
- } else {
- classNames.push('subject_slide-out');
- }
-
- // XXX: Since chat is now not reactified we have to dangerously set
- // inner HTML into the component. This has to be refactored while
- // reactification of the Chat.js
- const innerHtml = {
- __html: _subject
- };
-
- return (
- <div
- className = { classNames.join(' ') }
-
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML = { innerHtml }
- id = 'subject' />
- );
- }
-
- /**
- * Renders primary and secondary toolbars.
- *
- * @returns {ReactElement}
- * @private
- */
- _renderToolbars(): React$Element<*> | null {
- // In case we're not in alwaysVisible mode the toolbox should not be
- // shown until timeoutID is initialized.
- if (!this.props._alwaysVisible && this.props._timeoutID === null) {
- return null;
- }
-
- return (
- <div className = 'toolbox-toolbars'>
- <Notice />
- <PrimaryToolbar />
- <SecondaryToolbar />
- </div>
- );
- }
- }
-
- /**
- * Maps parts of Redux actions to component props.
- *
- * @param {Function} dispatch - Redux action dispatcher.
- * @returns {{
- * _setDefaultToolboxButtons: Function,
- * _setToolboxAlwaysVisible: Function
- * }}
- * @private
- */
- function _mapDispatchToProps(dispatch: Function): Object {
- return {
- /**
- * Dispatches a (redux) action to set the default toolbar buttons.
- *
- * @returns {Object} Dispatched action.
- */
- _setDefaultToolboxButtons() {
- dispatch(setDefaultToolboxButtons());
- },
-
- /**
- * Dispatches a (redux) action to reset the permanent visibility of
- * the Toolbox.
- *
- * @returns {Object} Dispatched action.
- */
- _setToolboxAlwaysVisible() {
- dispatch(setToolboxAlwaysVisible(
- config.alwaysVisibleToolbar === true
- || interfaceConfig.filmStripOnly));
- }
- };
- }
-
- /**
- * Maps parts of toolbox state to component props.
- *
- * @param {Object} state - Redux state.
- * @private
- * @returns {{
- * _alwaysVisible: boolean,
- * _audioMuted: boolean,
- * _subjectSlideIn: boolean,
- * _videoMuted: boolean
- * }}
- */
- function _mapStateToProps(state: Object): Object {
- const {
- alwaysVisible,
- subject,
- subjectSlideIn,
- timeoutID
- } = state['features/toolbox'];
-
- return {
- ...abstractMapStateToProps(state),
-
- /**
- * Indicates if the toolbox should always be visible.
- *
- * @private
- * @type {boolean}
- */
- _alwaysVisible: alwaysVisible,
-
- /**
- * Property containing conference subject.
- *
- * @private
- * @type {string}
- */
- _subject: subject,
-
- /**
- * Flag showing whether to set subject slide in animation.
- *
- * @private
- * @type {boolean}
- */
- _subjectSlideIn: subjectSlideIn,
-
- /**
- * Property containing toolbox timeout id.
- *
- * @private
- * @type {number}
- */
- _timeoutID: timeoutID
- };
- }
-
- export default connect(_mapStateToProps, _mapDispatchToProps)(Toolbox);
|