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.tsx 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import React, { useEffect } from 'react';
  2. import { WithTranslation } from 'react-i18next';
  3. import { connect } from 'react-redux';
  4. import { createInviteDialogEvent } from '../../../../analytics/AnalyticsEvents';
  5. import { sendAnalytics } from '../../../../analytics/functions';
  6. import { IReduxState } from '../../../../app/types';
  7. import { getInviteURL } from '../../../../base/connection/functions';
  8. import { translate } from '../../../../base/i18n/functions';
  9. import { JitsiRecordingConstants } from '../../../../base/lib-jitsi-meet';
  10. import Dialog from '../../../../base/ui/components/web/Dialog';
  11. import { StatusCode } from '../../../../base/util/uri';
  12. import { isDynamicBrandingDataLoaded } from '../../../../dynamic-branding/functions.any';
  13. import { getActiveSession } from '../../../../recording/functions';
  14. import { updateDialInNumbers } from '../../../actions';
  15. import {
  16. _getDefaultPhoneNumber,
  17. getInviteText,
  18. getInviteTextiOS,
  19. isAddPeopleEnabled,
  20. isDialOutEnabled,
  21. isSharingEnabled,
  22. sharingFeatures
  23. } from '../../../functions';
  24. import CopyMeetingLinkSection from './CopyMeetingLinkSection';
  25. import DialInLimit from './DialInLimit';
  26. import DialInSection from './DialInSection';
  27. import InviteByEmailSection from './InviteByEmailSection';
  28. import InviteContactsSection from './InviteContactsSection';
  29. import LiveStreamSection from './LiveStreamSection';
  30. interface IProps extends WithTranslation {
  31. /**
  32. * The object representing the dialIn feature.
  33. */
  34. _dialIn: any;
  35. /**
  36. * Whether or not dial in number should be visible.
  37. */
  38. _dialInVisible: boolean;
  39. /**
  40. * Whether or not email sharing features should be visible.
  41. */
  42. _emailSharingVisible: boolean;
  43. /**
  44. * The meeting invitation text.
  45. */
  46. _invitationText: string;
  47. /**
  48. * The custom no new-lines meeting invitation text for iOS default email.
  49. * Needed because of this mailto: iOS issue: https://developer.apple.com/forums/thread/681023.
  50. */
  51. _invitationTextiOS: string;
  52. /**
  53. * An alternate app name to be displayed in the email subject.
  54. */
  55. _inviteAppName?: string | null;
  56. /**
  57. * Whether or not invite contacts should be visible.
  58. */
  59. _inviteContactsVisible: boolean;
  60. /**
  61. * The current url of the conference to be copied onto the clipboard.
  62. */
  63. _inviteUrl: string;
  64. /**
  65. * Whether the dial in limit has been exceeded.
  66. */
  67. _isDialInOverLimit?: boolean;
  68. /**
  69. * The current known URL for a live stream in progress.
  70. */
  71. _liveStreamViewURL?: string;
  72. /**
  73. * The default phone number.
  74. */
  75. _phoneNumber?: string | null;
  76. /**
  77. * Whether or not url sharing button should be visible.
  78. */
  79. _urlSharingVisible: boolean;
  80. /**
  81. * Method to update the dial in numbers.
  82. */
  83. updateNumbers: Function;
  84. }
  85. /**
  86. * Invite More component.
  87. *
  88. * @returns {React$Element<any>}
  89. */
  90. function AddPeopleDialog({
  91. _dialIn,
  92. _dialInVisible,
  93. _urlSharingVisible,
  94. _emailSharingVisible,
  95. _invitationText,
  96. _invitationTextiOS,
  97. _inviteAppName,
  98. _inviteContactsVisible,
  99. _inviteUrl,
  100. _isDialInOverLimit,
  101. _liveStreamViewURL,
  102. _phoneNumber,
  103. t,
  104. updateNumbers
  105. }: IProps) {
  106. /**
  107. * Updates the dial-in numbers.
  108. */
  109. useEffect(() => {
  110. if (!_dialIn.numbers) {
  111. updateNumbers();
  112. }
  113. }, []);
  114. /**
  115. * Sends analytics events when the dialog opens/closes.
  116. *
  117. * @returns {void}
  118. */
  119. useEffect(() => {
  120. sendAnalytics(createInviteDialogEvent(
  121. 'opened', 'dialog'));
  122. return () => {
  123. sendAnalytics(createInviteDialogEvent(
  124. 'closed', 'dialog'));
  125. };
  126. }, []);
  127. const inviteSubject = t('addPeople.inviteMoreMailSubject', {
  128. appName: _inviteAppName ?? interfaceConfig.APP_NAME
  129. });
  130. return (
  131. <Dialog
  132. cancel = {{ hidden: true }}
  133. ok = {{ hidden: true }}
  134. titleKey = 'addPeople.inviteMorePrompt'>
  135. <div className = 'invite-more-dialog'>
  136. { _inviteContactsVisible && <InviteContactsSection /> }
  137. {_urlSharingVisible ? <CopyMeetingLinkSection url = { _inviteUrl } /> : null}
  138. {
  139. _emailSharingVisible
  140. ? <InviteByEmailSection
  141. inviteSubject = { inviteSubject }
  142. inviteText = { _invitationText }
  143. inviteTextiOS = { _invitationTextiOS } />
  144. : null
  145. }
  146. <div className = 'invite-more-dialog separator' />
  147. {
  148. _liveStreamViewURL
  149. && <LiveStreamSection liveStreamViewURL = { _liveStreamViewURL } />
  150. }
  151. {
  152. _phoneNumber
  153. && _dialInVisible
  154. && <DialInSection phoneNumber = { _phoneNumber } />
  155. }
  156. {
  157. !_phoneNumber && _dialInVisible && _isDialInOverLimit && <DialInLimit />
  158. }
  159. </div>
  160. </Dialog>
  161. );
  162. }
  163. /**
  164. * Maps (parts of) the Redux state to the associated props for the
  165. * {@code AddPeopleDialog} component.
  166. *
  167. * @param {Object} state - The Redux state.
  168. * @param {Object} ownProps - The properties explicitly passed to the component.
  169. * @private
  170. * @returns {IProps}
  171. */
  172. function mapStateToProps(state: IReduxState, ownProps: Partial<IProps>) {
  173. const currentLiveStreamingSession
  174. = getActiveSession(state, JitsiRecordingConstants.mode.STREAM);
  175. const { iAmRecorder, inviteAppName } = state['features/base/config'];
  176. const addPeopleEnabled = isAddPeopleEnabled(state);
  177. const dialOutEnabled = isDialOutEnabled(state);
  178. const hideInviteContacts = iAmRecorder || (!addPeopleEnabled && !dialOutEnabled);
  179. const dialIn = state['features/invite']; // @ts-ignore
  180. const phoneNumber = dialIn?.numbers ? _getDefaultPhoneNumber(dialIn.numbers) : undefined;
  181. const isDialInOverLimit = dialIn?.error?.status === StatusCode.PaymentRequired;
  182. return {
  183. _dialIn: dialIn,
  184. _dialInVisible: isSharingEnabled(sharingFeatures.dialIn),
  185. _urlSharingVisible: isDynamicBrandingDataLoaded(state) && isSharingEnabled(sharingFeatures.url),
  186. _emailSharingVisible: isSharingEnabled(sharingFeatures.email),
  187. _invitationText: getInviteText({ state,
  188. phoneNumber,
  189. t: ownProps.t }),
  190. _invitationTextiOS: getInviteTextiOS({ state,
  191. phoneNumber,
  192. t: ownProps.t }),
  193. _inviteAppName: inviteAppName,
  194. _inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts,
  195. _inviteUrl: getInviteURL(state),
  196. _isDialInOverLimit: isDialInOverLimit,
  197. _liveStreamViewURL: currentLiveStreamingSession?.liveStreamViewURL,
  198. _phoneNumber: phoneNumber
  199. };
  200. }
  201. /**
  202. * Maps dispatching of some action to React component props.
  203. *
  204. * @param {Function} dispatch - Redux action dispatcher.
  205. * @returns {IProps}
  206. */
  207. const mapDispatchToProps = {
  208. updateNumbers: () => updateDialInNumbers()
  209. };
  210. export default translate(
  211. connect(mapStateToProps, mapDispatchToProps)(AddPeopleDialog)
  212. );