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

InviteButton.web.js 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import PropTypes from 'prop-types';
  2. import React, { Component } from 'react';
  3. import { connect } from 'react-redux';
  4. import Button from '@atlaskit/button';
  5. import DropdownMenu from '@atlaskit/dropdown-menu';
  6. import { translate } from '../../base/i18n';
  7. import { getLocalParticipant, PARTICIPANT_ROLE } from '../../base/participants';
  8. import { openDialog } from '../../base/dialog';
  9. import { AddPeopleDialog, InviteDialog } from '.';
  10. import { DialOutDialog } from '../../dial-out';
  11. import { isInviteOptionEnabled, getInviteOptionPosition } from '../functions';
  12. declare var interfaceConfig: Object;
  13. const SHARE_LINK_OPTION = 'invite';
  14. const DIAL_OUT_OPTION = 'dialout';
  15. const ADD_TO_CALL_OPTION = 'addtocall';
  16. /**
  17. * The button that provides different invite options.
  18. */
  19. class InviteButton extends Component {
  20. /**
  21. * {@code InviteButton}'s property types.
  22. *
  23. * @static
  24. */
  25. static propTypes = {
  26. /**
  27. * Indicates if the "Add to call" feature is available.
  28. */
  29. _isAddToCallAvailable: PropTypes.bool,
  30. /**
  31. * Indicates if the "Dial out" feature is available.
  32. */
  33. _isDialOutAvailable: PropTypes.bool,
  34. /**
  35. * The function opening the dialog.
  36. */
  37. openDialog: PropTypes.func,
  38. /**
  39. * Invoked to obtain translated strings.
  40. */
  41. t: PropTypes.func
  42. };
  43. /**
  44. * Initializes a new {@code InviteButton} instance.
  45. *
  46. * @param {Object} props - The read-only properties with which the new
  47. * instance is to be initialized.
  48. */
  49. constructor(props) {
  50. super(props);
  51. this._onInviteClick = this._onInviteClick.bind(this);
  52. this._onInviteOptionSelected = this._onInviteOptionSelected.bind(this);
  53. this._updateInviteItems = this._updateInviteItems.bind(this);
  54. this._updateInviteItems(this.props);
  55. }
  56. /**
  57. * Implements React's {@link Component#componentWillReceiveProps()}.
  58. *
  59. * @inheritdoc
  60. * @param {Object} nextProps - The read-only props which this Component will
  61. * receive.
  62. * @returns {void}
  63. */
  64. componentWillReceiveProps(nextProps) {
  65. if (this.props._isDialOutAvailable !== nextProps._isDialOutAvailable
  66. || this.props._isAddToCallAvailable
  67. !== nextProps._isAddToCallAvailable) {
  68. this._updateInviteItems(nextProps);
  69. }
  70. }
  71. /**
  72. * Renders the content of this component.
  73. *
  74. * @returns {ReactElement}
  75. */
  76. render() {
  77. const { t } = this.props;
  78. const { VERTICAL_FILMSTRIP } = interfaceConfig;
  79. return (
  80. <div className = 'filmstrip__invite'>
  81. <div className = 'invite-button-group'>
  82. <Button
  83. onClick = { this._onInviteClick }
  84. shouldFitContainer = { true }>
  85. { t('invite.invitePeople') }
  86. </Button>
  87. { this.props._isDialOutAvailable
  88. || this.props._isAddToCallAvailable
  89. ? <DropdownMenu
  90. items = { this.state.inviteOptions }
  91. onItemActivated = { this._onInviteOptionSelected }
  92. position = { VERTICAL_FILMSTRIP
  93. ? 'bottom right'
  94. : 'top right' }
  95. shouldFlip = { true }
  96. triggerType = 'button' />
  97. : null }
  98. </div>
  99. </div>
  100. );
  101. }
  102. /**
  103. * Handles the click of the invite button.
  104. *
  105. * @private
  106. * @returns {void}
  107. */
  108. _onInviteClick() {
  109. this.props.openDialog(InviteDialog);
  110. }
  111. /**
  112. * Handles selection of the invite options.
  113. *
  114. * @param { Object } option - The invite option that has been selected from
  115. * the dropdown menu.
  116. * @private
  117. * @returns {void}
  118. */
  119. _onInviteOptionSelected(option) {
  120. this.state.inviteOptions[0].items.forEach(item => {
  121. if (item.content === option.item.content) {
  122. item.action();
  123. }
  124. });
  125. }
  126. /**
  127. * Updates the invite items list depending on the availability of the
  128. * features.
  129. *
  130. * @param {Object} props - The read-only properties of the component.
  131. * @private
  132. * @returns {void}
  133. */
  134. _updateInviteItems(props) {
  135. const { t } = this.props;
  136. const inviteItems = [];
  137. inviteItems.splice(
  138. getInviteOptionPosition(SHARE_LINK_OPTION),
  139. 0,
  140. {
  141. content: t('toolbar.invite'),
  142. action: () => this.props.openDialog(InviteDialog)
  143. }
  144. );
  145. if (props._isDialOutAvailable) {
  146. inviteItems.splice(
  147. getInviteOptionPosition(DIAL_OUT_OPTION),
  148. 0,
  149. {
  150. content: t('dialOut.dialOut'),
  151. action: () => this.props.openDialog(DialOutDialog)
  152. }
  153. );
  154. }
  155. if (props._isAddToCallAvailable) {
  156. inviteItems.splice(
  157. getInviteOptionPosition(ADD_TO_CALL_OPTION),
  158. 0,
  159. {
  160. content: interfaceConfig.ADD_PEOPLE_APP_NAME,
  161. action: () => this.props.openDialog(AddPeopleDialog)
  162. }
  163. );
  164. }
  165. this.state = {
  166. /**
  167. * The list of invite options.
  168. */
  169. inviteOptions: [
  170. {
  171. items: inviteItems
  172. }
  173. ]
  174. };
  175. }
  176. }
  177. /**
  178. * Maps (parts of) the Redux state to the associated {@code InviteButton}'s
  179. * props.
  180. *
  181. * @param {Object} state - The Redux state.
  182. * @private
  183. * @returns {{
  184. * _isAddToCallAvailable: boolean,
  185. * _isDialOutAvailable: boolean
  186. * }}
  187. */
  188. function _mapStateToProps(state) {
  189. const { enableUserRolesBasedOnToken } = state['features/base/config'];
  190. const { conference } = state['features/base/conference'];
  191. const { isGuest } = state['features/jwt'];
  192. return {
  193. _isAddToCallAvailable: !isGuest
  194. && isInviteOptionEnabled(ADD_TO_CALL_OPTION),
  195. _isDialOutAvailable:
  196. getLocalParticipant(state).role === PARTICIPANT_ROLE.MODERATOR
  197. && conference && conference.isSIPCallingSupported()
  198. && isInviteOptionEnabled(DIAL_OUT_OPTION)
  199. && (!enableUserRolesBasedOnToken || !isGuest)
  200. };
  201. }
  202. export default translate(connect(
  203. _mapStateToProps, { openDialog })(InviteButton));