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.

InviteByEmailSection.js 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // @flow
  2. import React, { useState } from 'react';
  3. import { isIosMobileBrowser } from '../../../../base/environment/utils';
  4. import { translate } from '../../../../base/i18n';
  5. import {
  6. Icon,
  7. IconArrowDownSmall,
  8. IconCopy,
  9. IconEmail,
  10. IconGoogle,
  11. IconOutlook,
  12. IconYahoo
  13. } from '../../../../base/icons';
  14. import { Tooltip } from '../../../../base/tooltip';
  15. import { copyText } from '../../../../base/util';
  16. type Props = {
  17. /**
  18. * The encoded invitation subject.
  19. */
  20. inviteSubject: string,
  21. /**
  22. * The encoded invitation text to be sent.
  23. */
  24. inviteText: string,
  25. /**
  26. * The encoded no new-lines iOS invitation text to be sent on default mail.
  27. */
  28. inviteTextiOS: string,
  29. /**
  30. * Invoked to obtain translated strings.
  31. */
  32. t: Function,
  33. };
  34. /**
  35. * Component that renders email invite options.
  36. *
  37. * @returns {React$Element<any>}
  38. */
  39. function InviteByEmailSection({ inviteSubject, inviteText, inviteTextiOS, t }: Props) {
  40. const [ isActive, setIsActive ] = useState(false);
  41. const encodedInviteSubject = encodeURIComponent(inviteSubject);
  42. const encodedInviteText = encodeURIComponent(inviteText);
  43. const encodedInviteTextiOS = encodeURIComponent(inviteTextiOS);
  44. const encodedDefaultEmailText = isIosMobileBrowser() ? encodedInviteTextiOS : encodedInviteText;
  45. /**
  46. * Copies the conference invitation to the clipboard.
  47. *
  48. * @returns {void}
  49. */
  50. function _onCopyText() {
  51. copyText(inviteText);
  52. }
  53. /**
  54. * Copies the conference invitation to the clipboard.
  55. *
  56. * @param {Object} e - The key event to handle.
  57. *
  58. * @returns {void}
  59. */
  60. function _onCopyTextKeyPress(e) {
  61. if (e.key === ' ' || e.key === 'Enter') {
  62. e.preventDefault();
  63. copyText(inviteText);
  64. }
  65. }
  66. /**
  67. * Toggles the email invite drawer.
  68. *
  69. * @returns {void}
  70. */
  71. function _onToggleActiveState() {
  72. setIsActive(!isActive);
  73. }
  74. /**
  75. * Toggles the email invite drawer.
  76. *
  77. * @param {Object} e - The key event to handle.
  78. *
  79. * @returns {void}
  80. */
  81. function _onToggleActiveStateKeyPress(e) {
  82. if (e.key === ' ' || e.key === 'Enter') {
  83. e.preventDefault();
  84. setIsActive(!isActive);
  85. }
  86. }
  87. /**
  88. * Renders clickable elements that each open an email client
  89. * containing a conference invite.
  90. *
  91. * @returns {React$Element<any>}
  92. */
  93. function renderEmailIcons() {
  94. const PROVIDER_MAPPING = [
  95. {
  96. icon: IconEmail,
  97. tooltipKey: 'addPeople.defaultEmail',
  98. url: `mailto:?subject=${encodedInviteSubject}&body=${encodedDefaultEmailText}`
  99. },
  100. {
  101. icon: IconGoogle,
  102. tooltipKey: 'addPeople.googleEmail',
  103. url: `https://mail.google.com/mail/?view=cm&fs=1&su=${encodedInviteSubject}&body=${encodedInviteText}`
  104. },
  105. {
  106. icon: IconOutlook,
  107. tooltipKey: 'addPeople.outlookEmail',
  108. // eslint-disable-next-line max-len
  109. url: `https://outlook.office.com/mail/deeplink/compose?subject=${encodedInviteSubject}&body=${encodedInviteText}`
  110. },
  111. {
  112. icon: IconYahoo,
  113. tooltipKey: 'addPeople.yahooEmail',
  114. url: `https://compose.mail.yahoo.com/?To=&Subj=${encodedInviteSubject}&Body=${encodedInviteText}`
  115. }
  116. ];
  117. return (
  118. <>
  119. {
  120. PROVIDER_MAPPING.map(({ icon, tooltipKey, url }, idx) => (
  121. <Tooltip
  122. content = { t(tooltipKey) }
  123. key = { idx }
  124. position = 'top'>
  125. <a
  126. aria-label = { t(tooltipKey) }
  127. className = 'provider-icon'
  128. href = { url }
  129. rel = 'noopener noreferrer'
  130. target = '_blank'>
  131. <Icon src = { icon } />
  132. </a>
  133. </Tooltip>
  134. ))
  135. }
  136. </>
  137. );
  138. }
  139. return (
  140. <>
  141. <div>
  142. <div
  143. aria-expanded = { isActive }
  144. aria-label = { t('addPeople.shareInvite') }
  145. className = { `invite-more-dialog email-container${isActive ? ' active' : ''}` }
  146. onClick = { _onToggleActiveState }
  147. onKeyPress = { _onToggleActiveStateKeyPress }
  148. role = 'button'
  149. tabIndex = { 0 }>
  150. <span>{t('addPeople.shareInvite')}</span>
  151. <Icon src = { IconArrowDownSmall } />
  152. </div>
  153. <div className = { `invite-more-dialog icon-container${isActive ? ' active' : ''}` }>
  154. <Tooltip
  155. content = { t('addPeople.copyInvite') }
  156. position = 'top'>
  157. <div
  158. aria-label = { t('addPeople.copyInvite') }
  159. className = 'copy-invite-icon'
  160. onClick = { _onCopyText }
  161. onKeyPress = { _onCopyTextKeyPress }
  162. role = 'button'
  163. tabIndex = { 0 }>
  164. <Icon src = { IconCopy } />
  165. </div>
  166. </Tooltip>
  167. {renderEmailIcons()}
  168. </div>
  169. </div>
  170. </>
  171. );
  172. }
  173. export default translate(InviteByEmailSection);