You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AddPeopleDialog.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // @flow
  2. import React, { useState, useEffect } from 'react';
  3. import { createInviteDialogEvent, sendAnalytics } from '../../../../analytics';
  4. import { getRoomName } from '../../../../base/conference';
  5. import { getInviteURL } from '../../../../base/connection';
  6. import { Dialog } from '../../../../base/dialog';
  7. import { translate } from '../../../../base/i18n';
  8. import { JitsiRecordingConstants } from '../../../../base/lib-jitsi-meet';
  9. import { getLocalParticipant } from '../../../../base/participants';
  10. import { connect } from '../../../../base/redux';
  11. import EmbedMeetingTrigger from '../../../../embed-meeting/components/EmbedMeetingTrigger';
  12. import { getActiveSession } from '../../../../recording';
  13. import { updateDialInNumbers } from '../../../actions';
  14. import { _getDefaultPhoneNumber, getInviteText, isAddPeopleEnabled, isDialOutEnabled } from '../../../functions';
  15. import CopyMeetingLinkSection from './CopyMeetingLinkSection';
  16. import DialInSection from './DialInSection';
  17. import Header from './Header';
  18. import InviteByEmailSection from './InviteByEmailSection';
  19. import InviteContactsSection from './InviteContactsSection';
  20. import LiveStreamSection from './LiveStreamSection';
  21. declare var interfaceConfig: Object;
  22. type Props = {
  23. /**
  24. * The name of the current conference. Used as part of inviting users.
  25. */
  26. _conferenceName: string,
  27. /**
  28. * The object representing the dialIn feature.
  29. */
  30. _dialIn: Object,
  31. /**
  32. * Whether or not invite contacts should be visible.
  33. */
  34. _inviteContactsVisible: boolean,
  35. /**
  36. * The current url of the conference to be copied onto the clipboard.
  37. */
  38. _inviteUrl: string,
  39. /**
  40. * The current known URL for a live stream in progress.
  41. */
  42. _liveStreamViewURL: string,
  43. /**
  44. * The redux representation of the local participant.
  45. */
  46. _localParticipantName: ?string,
  47. /**
  48. * The current location url of the conference.
  49. */
  50. _locationUrl: Object,
  51. /**
  52. * Invoked to obtain translated strings.
  53. */
  54. t: Function,
  55. /**
  56. * Method to update the dial in numbers.
  57. */
  58. updateNumbers: Function
  59. };
  60. /**
  61. * Invite More component.
  62. *
  63. * @returns {React$Element<any>}
  64. */
  65. function AddPeopleDialog({
  66. _conferenceName,
  67. _dialIn,
  68. _inviteContactsVisible,
  69. _inviteUrl,
  70. _liveStreamViewURL,
  71. _localParticipantName,
  72. _locationUrl,
  73. t,
  74. updateNumbers }: Props) {
  75. const [ phoneNumber, setPhoneNumber ] = useState(undefined);
  76. /**
  77. * Updates the dial-in numbers.
  78. */
  79. useEffect(() => {
  80. if (!_dialIn.numbers) {
  81. updateNumbers();
  82. }
  83. }, []);
  84. /**
  85. * Sends analytics events when the dialog opens/closes.
  86. *
  87. * @returns {void}
  88. */
  89. useEffect(() => {
  90. sendAnalytics(createInviteDialogEvent(
  91. 'invite.dialog.opened', 'dialog'));
  92. return () => {
  93. sendAnalytics(createInviteDialogEvent(
  94. 'invite.dialog.closed', 'dialog'));
  95. };
  96. }, []);
  97. /**
  98. * Updates the phone number in the state once the dial-in numbers are fetched.
  99. *
  100. * @returns {void}
  101. */
  102. useEffect(() => {
  103. if (!phoneNumber && _dialIn && _dialIn.numbers) {
  104. setPhoneNumber(_getDefaultPhoneNumber(_dialIn.numbers));
  105. }
  106. }, [ _dialIn ]);
  107. const invite = getInviteText({
  108. _conferenceName,
  109. _localParticipantName,
  110. _inviteUrl,
  111. _locationUrl,
  112. _dialIn,
  113. _liveStreamViewURL,
  114. phoneNumber,
  115. t
  116. });
  117. const inviteSubject = t('addPeople.inviteMoreMailSubject', {
  118. appName: interfaceConfig.APP_NAME
  119. });
  120. return (
  121. <Dialog
  122. cancelKey = { 'dialog.close' }
  123. customHeader = { Header }
  124. hideCancelButton = { true }
  125. submitDisabled = { true }
  126. titleKey = 'addPeople.inviteMorePrompt'
  127. width = { 'small' }>
  128. <div className = 'invite-more-dialog'>
  129. { _inviteContactsVisible && <InviteContactsSection /> }
  130. <CopyMeetingLinkSection url = { _inviteUrl } />
  131. <InviteByEmailSection
  132. inviteSubject = { inviteSubject }
  133. inviteText = { invite } />
  134. <EmbedMeetingTrigger />
  135. <div className = 'invite-more-dialog separator' />
  136. {
  137. _liveStreamViewURL
  138. && <LiveStreamSection liveStreamViewURL = { _liveStreamViewURL } />
  139. }
  140. {
  141. _dialIn.numbers
  142. && <DialInSection
  143. conferenceName = { _conferenceName }
  144. dialIn = { _dialIn }
  145. locationUrl = { _locationUrl }
  146. phoneNumber = { phoneNumber } />
  147. }
  148. </div>
  149. </Dialog>
  150. );
  151. }
  152. /**
  153. * Maps (parts of) the Redux state to the associated props for the
  154. * {@code AddPeopleDialog} component.
  155. *
  156. * @param {Object} state - The Redux state.
  157. * @private
  158. * @returns {Props}
  159. */
  160. function mapStateToProps(state) {
  161. const localParticipant = getLocalParticipant(state);
  162. const currentLiveStreamingSession
  163. = getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
  164. const { iAmRecorder } = state['features/base/config'];
  165. const addPeopleEnabled = isAddPeopleEnabled(state);
  166. const dialOutEnabled = isDialOutEnabled(state);
  167. const hideInviteContacts = iAmRecorder || (!addPeopleEnabled && !dialOutEnabled);
  168. return {
  169. _conferenceName: getRoomName(state),
  170. _dialIn: state['features/invite'],
  171. _inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts,
  172. _inviteUrl: getInviteURL(state),
  173. _liveStreamViewURL:
  174. currentLiveStreamingSession
  175. && currentLiveStreamingSession.liveStreamViewURL,
  176. _localParticipantName: localParticipant?.name,
  177. _locationUrl: state['features/base/connection'].locationURL
  178. };
  179. }
  180. /**
  181. * Maps dispatching of some action to React component props.
  182. *
  183. * @param {Function} dispatch - Redux action dispatcher.
  184. * @returns {Props}
  185. */
  186. const mapDispatchToProps = {
  187. updateNumbers: () => updateDialInNumbers()
  188. };
  189. export default translate(
  190. connect(mapStateToProps, mapDispatchToProps)(AddPeopleDialog)
  191. );