/* global interfaceConfig */ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { connect } from 'react-redux'; import Button from '@atlaskit/button'; import DropdownMenu from '@atlaskit/dropdown-menu'; import { translate } from '../../base/i18n'; import { getLocalParticipant, PARTICIPANT_ROLE } from '../../base/participants'; import { openDialog } from '../../base/dialog'; import { AddPeopleDialog } from '.'; import { DialOutDialog } from '../../dial-out'; import { isInviteOptionEnabled } from '../functions'; const DIAL_OUT_OPTION = 'dialout'; const ADD_TO_CALL_OPTION = 'addtocall'; /** * The button that provides different invite options. */ class InviteButton extends Component { /** * {@code InviteButton}'s property types. * * @static */ static propTypes = { /** * Indicates if the "Add to call" feature is available. */ _isAddToCallAvailable: PropTypes.bool, /** * Indicates if the "Dial out" feature is available. */ _isDialOutAvailable: PropTypes.bool, /** * The function opening the dialog. */ openDialog: PropTypes.func, /** * Invoked to obtain translated strings. */ t: PropTypes.func }; /** * Initializes a new {@code InviteButton} instance. * * @param {Object} props - The read-only properties with which the new * instance is to be initialized. */ constructor(props) { super(props); this._onInviteOptionSelected = this._onInviteOptionSelected.bind(this); this._updateInviteItems = this._updateInviteItems.bind(this); this._updateInviteItems(this.props); } /** * Implements React's {@link Component#componentWillReceiveProps()}. * * @inheritdoc * @param {Object} nextProps - The read-only props which this Component will * receive. * @returns {void} */ componentWillReceiveProps(nextProps) { if (this.props._isDialOutAvailable !== nextProps._isDialOutAvailable || this.props._isAddToCallAvailable !== nextProps._isAddToCallAvailable) { this._updateInviteItems(nextProps); } } /** * Renders the content of this component. * * @returns {ReactElement} */ render() { // HACK ALERT: Normally children should not be controlling their own // visibility; parents should control that. However, this component is // in a transitionary state while the Invite Dialog is being redone. // This hack will go away when the Invite Dialog is back. if (!this.state.buttonOption) { return null; } const { VERTICAL_FILMSTRIP } = interfaceConfig; return (
{ this.state.inviteOptions[0].items.length ? : null }
); } /** * Handles selection of the invite options. * * @param { Object } option - The invite option that has been selected from * the dropdown menu. * @private * @returns {void} */ _onInviteOptionSelected(option) { this.state.inviteOptions[0].items.forEach(item => { if (item.content === option.item.content) { item.action(); } }); } /** * Updates the invite items list depending on the availability of the * features. * * @param {Object} props - The read-only properties of the component. * @private * @returns {void} */ _updateInviteItems(props) { const { INVITE_OPTIONS = [] } = interfaceConfig; const validOptions = INVITE_OPTIONS.filter(option => (option === DIAL_OUT_OPTION && props._isDialOutAvailable) || (option === ADD_TO_CALL_OPTION && props._isAddToCallAvailable)); /* eslint-disable array-callback-return */ const inviteItems = validOptions.map(option => { switch (option) { case DIAL_OUT_OPTION: return { content: this.props.t('dialOut.dialOut'), action: () => this.props.openDialog(DialOutDialog) }; case ADD_TO_CALL_OPTION: return { content: interfaceConfig.ADD_PEOPLE_APP_NAME, action: () => this.props.openDialog(AddPeopleDialog) }; } }); /* eslint-enable array-callback-return */ const buttonOption = inviteItems[0]; const dropdownOptions = inviteItems.splice(1, inviteItems.length); const nextState = { /** * The configuration for how the invite button should display and * behave on click. */ buttonOption, /** * The list of invite options in the dropdown. */ inviteOptions: [ { items: dropdownOptions } ] }; if (this.state) { this.setState(nextState); } else { // eslint-disable-next-line react/no-direct-mutation-state this.state = nextState; } } } /** * Maps (parts of) the Redux state to the associated {@code InviteButton}'s * props. * * @param {Object} state - The Redux state. * @private * @returns {{ * _isAddToCallAvailable: boolean, * _isDialOutAvailable: boolean * }} */ function _mapStateToProps(state) { const { conference } = state['features/base/conference']; const { enableUserRolesBasedOnToken } = state['features/base/config']; const { isGuest } = state['features/base/jwt']; return { _isAddToCallAvailable: !isGuest && isInviteOptionEnabled(ADD_TO_CALL_OPTION), _isDialOutAvailable: getLocalParticipant(state).role === PARTICIPANT_ROLE.MODERATOR && conference && conference.isSIPCallingSupported() && isInviteOptionEnabled(DIAL_OUT_OPTION) && (!enableUserRolesBasedOnToken || !isGuest) }; } export default translate(connect(_mapStateToProps, { openDialog })( InviteButton));