diff --git a/lang/main.json b/lang/main.json index 758ea389e..a8f4d89e0 100644 --- a/lang/main.json +++ b/lang/main.json @@ -418,6 +418,10 @@ "invitePhone": "To join by phone instead, tap this: {{number}},,{{conferenceID}}#\n", "invitePhoneAlternatives": "Looking for a different dial-in number?\nSee meeting dial-in numbers: {{url}}\n\n\nIf also dialing-in through a room phone, join without connecting to audio: {{silentUrl}}", "inviteSipEndpoint": "To join using the SIP address, enter this: {{sipUri}}", + "inviteTextiOSPersonal": "{{name}} is inviting you to a meeting.", + "inviteTextiOSJoinSilent": "If you are dialing-in through a room phone, use this link to join without connecting to audio: {{silentUrl}}.", + "inviteTextiOSInviteUrl": "Click the following link to join: {{inviteUrl}}.", + "inviteTextiOSPhone": "To join via phone, use this number: {{number}},,{{conferenceID}}#. If you are looking for a different number, this is the full list: {{didUrl}}.", "inviteURLFirstPartGeneral": "You are invited to join a meeting.", "inviteURLFirstPartPersonal": "{{name}} is inviting you to a meeting.\n", "inviteURLSecondPart": "\nJoin the meeting:\n{{url}}\n", diff --git a/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.js b/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.js index d5f32f71e..bbb87d560 100644 --- a/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.js +++ b/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.js @@ -16,6 +16,7 @@ import { updateDialInNumbers } from '../../../actions'; import { _getDefaultPhoneNumber, getInviteText, + getInviteTextiOS, isAddPeopleEnabled, isDialOutEnabled, sharingFeatures, @@ -62,6 +63,12 @@ type Props = { */ _invitationText: string, + /** + * The custom no new-lines meeting invitation text for iOS default email. + * Needed because of this mailto: iOS issue: https://developer.apple.com/forums/thread/681023 + */ + _invitationTextiOS: string, + /** * An alternate app name to be displayed in the email subject. */ @@ -110,6 +117,7 @@ function AddPeopleDialog({ _urlSharingVisible, _emailSharingVisible, _invitationText, + _invitationTextiOS, _inviteAppName, _inviteContactsVisible, _inviteUrl, @@ -160,7 +168,8 @@ function AddPeopleDialog({ _emailSharingVisible ? + inviteText = { _invitationText } + inviteTextiOS = { _invitationTextiOS } /> : null } { _embedMeetingVisible && } @@ -207,6 +216,9 @@ function mapStateToProps(state, ownProps) { _invitationText: getInviteText({ state, phoneNumber, t: ownProps.t }), + _invitationTextiOS: getInviteTextiOS({ state, + phoneNumber, + t: ownProps.t }), _inviteAppName: inviteAppName, _inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts, _inviteUrl: getInviteURL(state), diff --git a/react/features/invite/components/add-people-dialog/web/InviteByEmailSection.js b/react/features/invite/components/add-people-dialog/web/InviteByEmailSection.js index 34493ec3a..cde47d2fe 100644 --- a/react/features/invite/components/add-people-dialog/web/InviteByEmailSection.js +++ b/react/features/invite/components/add-people-dialog/web/InviteByEmailSection.js @@ -2,6 +2,7 @@ import React, { useState } from 'react'; +import { isIosMobileBrowser } from '../../../../base/environment/utils'; import { translate } from '../../../../base/i18n'; import { Icon, @@ -27,6 +28,11 @@ type Props = { */ inviteText: string, + /** + * The encoded no new-lines iOS invitation text to be sent on default mail. + */ + inviteTextiOS: string, + /** * Invoked to obtain translated strings. */ @@ -38,10 +44,13 @@ type Props = { * * @returns {React$Element} */ -function InviteByEmailSection({ inviteSubject, inviteText, t }: Props) { +function InviteByEmailSection({ inviteSubject, inviteText, inviteTextiOS, t }: Props) { const [ isActive, setIsActive ] = useState(false); const encodedInviteSubject = encodeURIComponent(inviteSubject); const encodedInviteText = encodeURIComponent(inviteText); + const encodedInviteTextiOS = encodeURIComponent(inviteTextiOS); + + const encodedDefaultEmailText = isIosMobileBrowser() ? encodedInviteTextiOS : encodedInviteText; /** * Copies the conference invitation to the clipboard. @@ -100,7 +109,7 @@ function InviteByEmailSection({ inviteSubject, inviteText, t }: Props) { { icon: IconEmail, tooltipKey: 'addPeople.defaultEmail', - url: `mailto:?subject=${encodedInviteSubject}&body=${encodedInviteText}` + url: `mailto:?subject=${encodedInviteSubject}&body=${encodedDefaultEmailText}` }, { icon: IconGoogle, diff --git a/react/features/invite/functions.js b/react/features/invite/functions.js index 2ced54cd5..7f90da56d 100644 --- a/react/features/invite/functions.js +++ b/react/features/invite/functions.js @@ -3,6 +3,7 @@ import { getActiveSession } from '../../features/recording/functions'; import { getRoomName } from '../base/conference'; import { getInviteURL } from '../base/connection'; +import { isIosMobileBrowser } from '../base/environment/utils'; import { i18next } from '../base/i18n'; import { JitsiRecordingConstants } from '../base/lib-jitsi-meet'; import { getLocalParticipant, isLocalParticipantModerator } from '../base/participants'; @@ -251,6 +252,49 @@ export function getInviteResultsForQuery( }); } +/** + * Creates a custom no new lines message for iOS default mail describing how to dial in to the conference. + * + * @returns {string} + */ +export function getInviteTextiOS({ + state, + phoneNumber, + t +}: Object) { + if (!isIosMobileBrowser()) { + return ''; + } + + const dialIn = state['features/invite']; + const inviteUrl = getInviteURL(state); + const localParticipant = getLocalParticipant(state); + const localParticipantName = localParticipant?.name; + + const inviteURL = _decodeRoomURI(inviteUrl); + + let invite = localParticipantName + ? t('info.inviteTextiOSPersonal', { name: localParticipantName }) + : t('info.inviteURLFirstPartGeneral'); + + invite += ' '; + + invite += t('info.inviteTextiOSInviteUrl', { inviteUrl }); + invite += ' '; + + if (shouldDisplayDialIn(dialIn)) { + invite += t('info.inviteTextiOSPhone', { + number: phoneNumber, + conferenceID: dialIn.conferenceID, + didUrl: getDialInfoPageURL(state) + }); + } + invite += ' '; + invite += t('info.inviteTextiOSJoinSilent', { silentUrl: `${inviteURL}#config.startSilent=true` }); + + return invite; +} + /** * Creates a message describing how to dial in to the conference. * @@ -271,7 +315,6 @@ export function getInviteText({ const localParticipantName = localParticipant?.name; const inviteURL = _decodeRoomURI(inviteUrl); - let invite = localParticipantName ? t('info.inviteURLFirstPartPersonal', { name: localParticipantName }) : t('info.inviteURLFirstPartGeneral');