| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 | 
							- // @flow
 - 
 - import React, { Component } from 'react';
 - import { View } from 'react-native';
 - import { connect } from 'react-redux';
 - 
 - import { Container } from '../../../base/react';
 - import { InviteButton } from '../../../invite';
 - 
 - import AudioMuteButton from '../AudioMuteButton';
 - import HangupButton from '../HangupButton';
 - import OverflowMenuButton from './OverflowMenuButton';
 - import styles, {
 -     hangupButtonStyles,
 -     toolbarButtonStyles,
 -     toolbarToggledButtonStyles
 - } from './styles';
 - import VideoMuteButton from '../VideoMuteButton';
 - 
 - /**
 -  * The number of buttons other than {@link HangupButton} to render in
 -  * {@link Toolbox}.
 -  *
 -  * @private
 -  * @type number
 -  */
 - const _BUTTON_COUNT = 4;
 - 
 - /**
 -  * Factor relating the hangup button and other toolbar buttons.
 -  *
 -  * @private
 -  * @type number
 -  */
 - const _BUTTON_SIZE_FACTOR = 0.85;
 - 
 - /**
 -  * The type of {@link Toolbox}'s React {@code Component} props.
 -  */
 - type Props = {
 - 
 -     /**
 -      * The indicator which determines whether the toolbox is visible.
 -      */
 -     _visible: boolean,
 - 
 -     /**
 -      * The redux {@code dispatch} function.
 -      */
 -     dispatch: Function
 - };
 - 
 - /**
 -  * The type of {@link Toolbox}'s React {@code Component} state.
 -  */
 - type State = {
 - 
 -     /**
 -      * The detected width for this component.
 -      */
 -     width: number
 - };
 - 
 - /**
 -  * Implements the conference toolbox on React Native.
 -  */
 - class Toolbox extends Component<Props, State> {
 -     state = {
 -         width: 0
 -     };
 - 
 -     /**
 -      *  Initializes a new {@code Toolbox} instance.
 -      *
 -      * @inheritdoc
 -      */
 -     constructor(props: Props) {
 -         super(props);
 - 
 -         // Bind event handlers so they are only bound once per instance.
 -         this._onLayout = this._onLayout.bind(this);
 -     }
 - 
 -     /**
 -      * Implements React's {@link Component#render()}.
 -      *
 -      * @inheritdoc
 -      * @returns {ReactElement}
 -      */
 -     render() {
 -         return (
 -             <Container
 -                 onLayout = { this._onLayout }
 -                 style = { styles.toolbox }
 -                 visible = { this.props._visible }>
 -                 { this._renderToolbar() }
 -             </Container>
 -         );
 -     }
 - 
 -     /**
 -      * Calculates how large our toolbar buttons can be, given the available
 -      * width. In the future we might want to have a size threshold, and once
 -      * it's passed a completely different style could be used, akin to the web.
 -      *
 -      * @private
 -      * @returns {number}
 -      */
 -     _calculateButtonSize() {
 -         const { width } = this.state;
 - 
 -         if (width <= 0) {
 -             // We don't know how much space is allocated to the toolbar yet.
 -             return width;
 -         }
 - 
 -         const hangupButtonSize = styles.hangupButton.width;
 -         const { style } = toolbarButtonStyles;
 -         let buttonSize
 -             = (width
 - 
 -                     // Account for HangupButton without its margin which is not
 -                     // included in _BUTTON_COUNT:
 -                     - hangupButtonSize
 - 
 -                     // Account for the horizontal margins of all buttons:
 -                     - ((_BUTTON_COUNT + 1) * style.marginHorizontal * 2))
 -                 / _BUTTON_COUNT;
 - 
 -         // Well, don't return a non-positive button size.
 -         if (buttonSize <= 0) {
 -             buttonSize = style.width;
 -         }
 - 
 -         // The button should be at most _BUTTON_SIZE_FACTOR of the hangup
 -         // button's size.
 -         buttonSize
 -             = Math.min(buttonSize, hangupButtonSize * _BUTTON_SIZE_FACTOR);
 - 
 -         // Make sure it's an even number.
 -         return 2 * Math.round(buttonSize / 2);
 -     }
 - 
 -     _onLayout: (Object) => void;
 - 
 -     /**
 -      * Handles the "on layout" View's event and stores the width as state.
 -      *
 -      * @param {Object} event - The "on layout" event object/structure passed
 -      * by react-native.
 -      * @private
 -      * @returns {void}
 -      */
 -     _onLayout({ nativeEvent: { layout: { width } } }) {
 -         this.setState({ width });
 -     }
 - 
 -     /**
 -      * Renders the toolbar. In order to avoid a weird visual effect in which the
 -      * toolbar is (visually) rendered and then visibly changes its size, it is
 -      * rendered only after we've figured out the width available to the toolbar.
 -      *
 -      * @returns {React$Node}
 -      */
 -     _renderToolbar() {
 -         const buttonSize = this._calculateButtonSize();
 -         let buttonStyles = toolbarButtonStyles;
 -         let toggledButtonStyles = toolbarToggledButtonStyles;
 - 
 -         if (buttonSize > 0) {
 -             const extraButtonStyle = {
 -                 borderRadius: buttonSize / 2,
 -                 height: buttonSize,
 -                 width: buttonSize
 -             };
 - 
 -             // XXX The following width equality checks attempt to minimize
 -             // unnecessary objects and possibly re-renders.
 -             if (buttonStyles.style.width !== extraButtonStyle.width) {
 -                 buttonStyles = {
 -                     ...buttonStyles,
 -                     style: [ buttonStyles.style, extraButtonStyle ]
 -                 };
 -             }
 -             if (toggledButtonStyles.style.width !== extraButtonStyle.width) {
 -                 toggledButtonStyles = {
 -                     ...toggledButtonStyles,
 -                     style: [ toggledButtonStyles.style, extraButtonStyle ]
 -                 };
 -             }
 -         } else {
 -             // XXX In order to avoid a weird visual effect in which the toolbar
 -             // is (visually) rendered and then visibly changes its size, it is
 -             // rendered only after we've figured out the width available to the
 -             // toolbar.
 -             return null;
 -         }
 - 
 -         return (
 -             <View
 -                 pointerEvents = 'box-none'
 -                 style = { styles.toolbar }>
 -                 <InviteButton styles = { buttonStyles } />
 -                 <AudioMuteButton
 -                     styles = { buttonStyles }
 -                     toggledStyles = { toggledButtonStyles } />
 -                 <HangupButton styles = { hangupButtonStyles } />
 -                 <VideoMuteButton
 -                     styles = { buttonStyles }
 -                     toggledStyles = { toggledButtonStyles } />
 -                 <OverflowMenuButton
 -                     styles = { buttonStyles }
 -                     toggledStyles = { toggledButtonStyles } />
 -             </View>
 -         );
 -     }
 - }
 - 
 - /**
 -  * Maps parts of the redux state to {@link Toolbox} (React {@code Component})
 -  * props.
 -  *
 -  * @param {Object} state - The redux state of which parts are to be mapped to
 -  * {@code Toolbox} props.
 -  * @private
 -  * @returns {{
 -  *     _visible: boolean
 -  * }}
 -  */
 - function _mapStateToProps(state: Object): Object {
 -     const { alwaysVisible, enabled, visible } = state['features/toolbox'];
 - 
 -     return {
 -         _visible: enabled && (alwaysVisible || visible)
 -     };
 - }
 - 
 - export default connect(_mapStateToProps)(Toolbox);
 
 
  |