Browse Source

fix(iOS-mailto): Send no new line invite on default email

- addresses this issue: https://developer.apple.com/forums/thread/681023
j8
hmuresan 3 years ago
parent
commit
6f9944a2d0

+ 4
- 0
lang/main.json View File

418
         "invitePhone": "To join by phone instead, tap this: {{number}},,{{conferenceID}}#\n",
418
         "invitePhone": "To join by phone instead, tap this: {{number}},,{{conferenceID}}#\n",
419
         "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}}",
419
         "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}}",
420
         "inviteSipEndpoint": "To join using the SIP address, enter this: {{sipUri}}",
420
         "inviteSipEndpoint": "To join using the SIP address, enter this: {{sipUri}}",
421
+        "inviteTextiOSPersonal": "{{name}} is inviting you to a meeting.",
422
+        "inviteTextiOSJoinSilent": "If you are dialing-in through a room phone, use this link to join without connecting to audio: {{silentUrl}}.",
423
+        "inviteTextiOSInviteUrl": "Click the following link to join: {{inviteUrl}}.",
424
+        "inviteTextiOSPhone": "To join via phone, use this number: {{number}},,{{conferenceID}}#. If you are looking for a different number, this is the full list: {{didUrl}}.",
421
         "inviteURLFirstPartGeneral": "You are invited to join a meeting.",
425
         "inviteURLFirstPartGeneral": "You are invited to join a meeting.",
422
         "inviteURLFirstPartPersonal": "{{name}} is inviting you to a meeting.\n",
426
         "inviteURLFirstPartPersonal": "{{name}} is inviting you to a meeting.\n",
423
         "inviteURLSecondPart": "\nJoin the meeting:\n{{url}}\n",
427
         "inviteURLSecondPart": "\nJoin the meeting:\n{{url}}\n",

+ 13
- 1
react/features/invite/components/add-people-dialog/web/AddPeopleDialog.js View File

16
 import {
16
 import {
17
     _getDefaultPhoneNumber,
17
     _getDefaultPhoneNumber,
18
     getInviteText,
18
     getInviteText,
19
+    getInviteTextiOS,
19
     isAddPeopleEnabled,
20
     isAddPeopleEnabled,
20
     isDialOutEnabled,
21
     isDialOutEnabled,
21
     sharingFeatures,
22
     sharingFeatures,
62
      */
63
      */
63
     _invitationText: string,
64
     _invitationText: string,
64
 
65
 
66
+    /**
67
+     * The custom no new-lines meeting invitation text for iOS default email.
68
+     * Needed because of this mailto: iOS issue: https://developer.apple.com/forums/thread/681023
69
+     */
70
+    _invitationTextiOS: string,
71
+
65
     /**
72
     /**
66
      * An alternate app name to be displayed in the email subject.
73
      * An alternate app name to be displayed in the email subject.
67
      */
74
      */
110
     _urlSharingVisible,
117
     _urlSharingVisible,
111
     _emailSharingVisible,
118
     _emailSharingVisible,
112
     _invitationText,
119
     _invitationText,
120
+    _invitationTextiOS,
113
     _inviteAppName,
121
     _inviteAppName,
114
     _inviteContactsVisible,
122
     _inviteContactsVisible,
115
     _inviteUrl,
123
     _inviteUrl,
160
                     _emailSharingVisible
168
                     _emailSharingVisible
161
                         ? <InviteByEmailSection
169
                         ? <InviteByEmailSection
162
                             inviteSubject = { inviteSubject }
170
                             inviteSubject = { inviteSubject }
163
-                            inviteText = { _invitationText } />
171
+                            inviteText = { _invitationText }
172
+                            inviteTextiOS = { _invitationTextiOS } />
164
                         : null
173
                         : null
165
                 }
174
                 }
166
                 { _embedMeetingVisible && <EmbedMeetingTrigger /> }
175
                 { _embedMeetingVisible && <EmbedMeetingTrigger /> }
207
         _invitationText: getInviteText({ state,
216
         _invitationText: getInviteText({ state,
208
             phoneNumber,
217
             phoneNumber,
209
             t: ownProps.t }),
218
             t: ownProps.t }),
219
+        _invitationTextiOS: getInviteTextiOS({ state,
220
+            phoneNumber,
221
+            t: ownProps.t }),
210
         _inviteAppName: inviteAppName,
222
         _inviteAppName: inviteAppName,
211
         _inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts,
223
         _inviteContactsVisible: interfaceConfig.ENABLE_DIAL_OUT && !hideInviteContacts,
212
         _inviteUrl: getInviteURL(state),
224
         _inviteUrl: getInviteURL(state),

+ 11
- 2
react/features/invite/components/add-people-dialog/web/InviteByEmailSection.js View File

2
 
2
 
3
 import React, { useState } from 'react';
3
 import React, { useState } from 'react';
4
 
4
 
5
+import { isIosMobileBrowser } from '../../../../base/environment/utils';
5
 import { translate } from '../../../../base/i18n';
6
 import { translate } from '../../../../base/i18n';
6
 import {
7
 import {
7
     Icon,
8
     Icon,
27
      */
28
      */
28
     inviteText: string,
29
     inviteText: string,
29
 
30
 
31
+    /**
32
+     * The encoded no new-lines iOS invitation text to be sent on default mail.
33
+     */
34
+    inviteTextiOS: string,
35
+
30
     /**
36
     /**
31
      * Invoked to obtain translated strings.
37
      * Invoked to obtain translated strings.
32
      */
38
      */
38
  *
44
  *
39
  * @returns {React$Element<any>}
45
  * @returns {React$Element<any>}
40
  */
46
  */
41
-function InviteByEmailSection({ inviteSubject, inviteText, t }: Props) {
47
+function InviteByEmailSection({ inviteSubject, inviteText, inviteTextiOS, t }: Props) {
42
     const [ isActive, setIsActive ] = useState(false);
48
     const [ isActive, setIsActive ] = useState(false);
43
     const encodedInviteSubject = encodeURIComponent(inviteSubject);
49
     const encodedInviteSubject = encodeURIComponent(inviteSubject);
44
     const encodedInviteText = encodeURIComponent(inviteText);
50
     const encodedInviteText = encodeURIComponent(inviteText);
51
+    const encodedInviteTextiOS = encodeURIComponent(inviteTextiOS);
52
+
53
+    const encodedDefaultEmailText = isIosMobileBrowser() ? encodedInviteTextiOS : encodedInviteText;
45
 
54
 
46
     /**
55
     /**
47
      * Copies the conference invitation to the clipboard.
56
      * Copies the conference invitation to the clipboard.
100
             {
109
             {
101
                 icon: IconEmail,
110
                 icon: IconEmail,
102
                 tooltipKey: 'addPeople.defaultEmail',
111
                 tooltipKey: 'addPeople.defaultEmail',
103
-                url: `mailto:?subject=${encodedInviteSubject}&body=${encodedInviteText}`
112
+                url: `mailto:?subject=${encodedInviteSubject}&body=${encodedDefaultEmailText}`
104
             },
113
             },
105
             {
114
             {
106
                 icon: IconGoogle,
115
                 icon: IconGoogle,

+ 44
- 1
react/features/invite/functions.js View File

3
 import { getActiveSession } from '../../features/recording/functions';
3
 import { getActiveSession } from '../../features/recording/functions';
4
 import { getRoomName } from '../base/conference';
4
 import { getRoomName } from '../base/conference';
5
 import { getInviteURL } from '../base/connection';
5
 import { getInviteURL } from '../base/connection';
6
+import { isIosMobileBrowser } from '../base/environment/utils';
6
 import { i18next } from '../base/i18n';
7
 import { i18next } from '../base/i18n';
7
 import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
8
 import { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
8
 import { getLocalParticipant, isLocalParticipantModerator } from '../base/participants';
9
 import { getLocalParticipant, isLocalParticipantModerator } from '../base/participants';
251
         });
252
         });
252
 }
253
 }
253
 
254
 
255
+/**
256
+ * Creates a custom no new lines message for iOS default mail describing how to dial in to the conference.
257
+ *
258
+ * @returns {string}
259
+ */
260
+export function getInviteTextiOS({
261
+    state,
262
+    phoneNumber,
263
+    t
264
+}: Object) {
265
+    if (!isIosMobileBrowser()) {
266
+        return '';
267
+    }
268
+
269
+    const dialIn = state['features/invite'];
270
+    const inviteUrl = getInviteURL(state);
271
+    const localParticipant = getLocalParticipant(state);
272
+    const localParticipantName = localParticipant?.name;
273
+
274
+    const inviteURL = _decodeRoomURI(inviteUrl);
275
+
276
+    let invite = localParticipantName
277
+        ? t('info.inviteTextiOSPersonal', { name: localParticipantName })
278
+        : t('info.inviteURLFirstPartGeneral');
279
+
280
+    invite += ' ';
281
+
282
+    invite += t('info.inviteTextiOSInviteUrl', { inviteUrl });
283
+    invite += ' ';
284
+
285
+    if (shouldDisplayDialIn(dialIn)) {
286
+        invite += t('info.inviteTextiOSPhone', {
287
+            number: phoneNumber,
288
+            conferenceID: dialIn.conferenceID,
289
+            didUrl: getDialInfoPageURL(state)
290
+        });
291
+    }
292
+    invite += ' ';
293
+    invite += t('info.inviteTextiOSJoinSilent', { silentUrl: `${inviteURL}#config.startSilent=true` });
294
+
295
+    return invite;
296
+}
297
+
254
 /**
298
 /**
255
  * Creates a message describing how to dial in to the conference.
299
  * Creates a message describing how to dial in to the conference.
256
  *
300
  *
271
     const localParticipantName = localParticipant?.name;
315
     const localParticipantName = localParticipant?.name;
272
 
316
 
273
     const inviteURL = _decodeRoomURI(inviteUrl);
317
     const inviteURL = _decodeRoomURI(inviteUrl);
274
-
275
     let invite = localParticipantName
318
     let invite = localParticipantName
276
         ? t('info.inviteURLFirstPartPersonal', { name: localParticipantName })
319
         ? t('info.inviteURLFirstPartPersonal', { name: localParticipantName })
277
         : t('info.inviteURLFirstPartGeneral');
320
         : t('info.inviteURLFirstPartGeneral');

Loading…
Cancel
Save