Ver código fonte

Implements calendar entries edit. (#3382)

* Implements calendar entries edit.

Share text generation between calendar-sync and the share-room feature.

* Fixing comments.

* Clone the event element we modify on update.
master
Дамян Минков 6 anos atrás
pai
commit
7267f386dc

+ 5
- 0
lang/main.json Ver arquivo

424
         ],
424
         ],
425
         "and": "and"
425
         "and": "and"
426
     },
426
     },
427
+    "share":
428
+    {
429
+        "mainText": "Click the following link to join the meeting:\n__roomUrl__",
430
+        "dialInfoText": "\n\n=====\n\nJust want to dial in on your phone?\n\nClick this link to see the dial in phone numbers for this meetings\n__dialInfoPageUrl__"
431
+    },
427
     "connection":
432
     "connection":
428
     {
433
     {
429
         "ERROR": "Error",
434
         "ERROR": "Error",

+ 9
- 1
react/features/base/util/uri.js Ver arquivo

300
  * references a Jitsi Meet resource (location).
300
  * references a Jitsi Meet resource (location).
301
  * @public
301
  * @public
302
  * @returns {{
302
  * @returns {{
303
- *     room: (string|undefined)
303
+ *     contextRoot: string,
304
+ *     hash: string,
305
+ *     host: string,
306
+ *     hostname: string,
307
+ *     pathname: string,
308
+ *     port: string,
309
+ *     protocol: string,
310
+ *     room: (string|undefined),
311
+ *     search: string
304
  * }}
312
  * }}
305
  */
313
  */
306
 export function parseURIString(uri: ?string) {
314
 export function parseURIString(uri: ?string) {

+ 48
- 0
react/features/calendar-sync/actions.js Ver arquivo

12
     SET_CALENDAR_PROFILE_EMAIL
12
     SET_CALENDAR_PROFILE_EMAIL
13
 } from './actionTypes';
13
 } from './actionTypes';
14
 import { _getCalendarIntegration, isCalendarEnabled } from './functions';
14
 import { _getCalendarIntegration, isCalendarEnabled } from './functions';
15
+import { generateRoomWithoutSeparator } from '../welcome';
15
 
16
 
16
 const logger = require('jitsi-meet-logger').getLogger(__filename);
17
 const logger = require('jitsi-meet-logger').getLogger(__filename);
17
 
18
 
242
             });
243
             });
243
     };
244
     };
244
 }
245
 }
246
+
247
+/**
248
+ * Updates calendar event by generating new invite URL and editing the event
249
+ * adding some descriptive text and location.
250
+ *
251
+ * @param {string} id - The event id.
252
+ * @param {string} calendarId - The id of the calendar to use.
253
+ * @returns {Function}
254
+ */
255
+export function updateCalendarEvent(id: string, calendarId: string): Function {
256
+    return (dispatch: Dispatch<*>, getState: Function) => {
257
+
258
+        const { integrationType } = getState()['features/calendar-sync'];
259
+        const integration = _getCalendarIntegration(integrationType);
260
+
261
+        if (!integration) {
262
+            return Promise.reject('No integration found');
263
+        }
264
+
265
+        const { locationURL } = getState()['features/base/connection'];
266
+        const newRoomName = generateRoomWithoutSeparator();
267
+        let href = locationURL.href;
268
+
269
+        href.endsWith('/') || (href += '/');
270
+
271
+        const roomURL = `${href}${newRoomName}`;
272
+
273
+        return dispatch(integration.updateCalendarEvent(
274
+                id, calendarId, roomURL))
275
+            .then(() => {
276
+                // make a copy of the array
277
+                const events
278
+                    = getState()['features/calendar-sync'].events.slice(0);
279
+
280
+                const eventIx = events.findIndex(
281
+                    e => e.id === id && e.calendarId === calendarId);
282
+
283
+                // clone the event we will modify
284
+                const newEvent = Object.assign({}, events[eventIx]);
285
+
286
+                newEvent.url = roomURL;
287
+                events[eventIx] = newEvent;
288
+
289
+                return dispatch(setCalendarEvents(events));
290
+            });
291
+    };
292
+}

+ 17
- 4
react/features/calendar-sync/functions.any.js Ver arquivo

90
     if (event) {
90
     if (event) {
91
         const url = _getURLFromEvent(event, knownDomains);
91
         const url = _getURLFromEvent(event, knownDomains);
92
 
92
 
93
-        if (url) {
93
+        // we only filter events without url on mobile, this is temporary
94
+        // till we implement event edit on mobile
95
+        if (url || navigator.product !== 'ReactNative') {
94
             const startDate = Date.parse(event.startDate);
96
             const startDate = Date.parse(event.startDate);
95
             const endDate = Date.parse(event.endDate);
97
             const endDate = Date.parse(event.endDate);
96
 
98
 
97
-            if (isNaN(startDate) || isNaN(endDate)) {
98
-                logger.warn(
99
+            // we want to hide all events that
100
+            // - has no start or end date
101
+            // - for web, if there is no url and we cannot edit the event (has
102
+            // no calendarId)
103
+            if (isNaN(startDate)
104
+                || isNaN(endDate)
105
+                || (navigator.product !== 'ReactNative'
106
+                        && !url
107
+                        && !event.calendarId)) {
108
+                logger.debug(
99
                     'Skipping invalid calendar event',
109
                     'Skipping invalid calendar event',
100
                     event.title,
110
                     event.title,
101
                     event.startDate,
111
                     event.startDate,
102
-                    event.endDate
112
+                    event.endDate,
113
+                    url,
114
+                    event.calendarId
103
                 );
115
                 );
104
             } else {
116
             } else {
105
                 return {
117
                 return {
118
+                    calendarId: event.calendarId,
106
                     endDate,
119
                     endDate,
107
                     id: event.id,
120
                     id: event.id,
108
                     startDate,
121
                     startDate,

+ 13
- 1
react/features/calendar-sync/web/googleCalendar.js Ver arquivo

5
     googleApi,
5
     googleApi,
6
     loadGoogleAPI,
6
     loadGoogleAPI,
7
     signIn,
7
     signIn,
8
+    updateCalendarEvent,
8
     updateProfile
9
     updateProfile
9
 } from '../../google-api';
10
 } from '../../google-api';
10
 
11
 
62
      */
63
      */
63
     _isSignedIn() {
64
     _isSignedIn() {
64
         return () => googleApi.isSignedIn();
65
         return () => googleApi.isSignedIn();
65
-    }
66
+    },
67
+
68
+    /**
69
+     * Updates calendar event by generating new invite URL and editing the event
70
+     * adding some descriptive text and location.
71
+     *
72
+     * @param {string} id - The event id.
73
+     * @param {string} calendarId - The id of the calendar to use.
74
+     * @param {string} location - The location to save to the event.
75
+     * @returns {function(Dispatch<*>): Promise<string|never>}
76
+     */
77
+    updateCalendarEvent
66
 };
78
 };

+ 65
- 3
react/features/calendar-sync/web/microsoftCalendar.js Ver arquivo

7
 
7
 
8
 import parseURLParams from '../../base/config/parseURLParams';
8
 import parseURLParams from '../../base/config/parseURLParams';
9
 import { parseStandardURIString } from '../../base/util';
9
 import { parseStandardURIString } from '../../base/util';
10
+import { getShareInfoText } from '../../invite';
10
 
11
 
11
 import { setCalendarAPIAuthState } from '../actions';
12
 import { setCalendarAPIAuthState } from '../actions';
12
 
13
 
31
      *
32
      *
32
      * @type {string}
33
      * @type {string}
33
      */
34
      */
34
-    MS_API_SCOPES: 'openid profile Calendars.Read',
35
+    MS_API_SCOPES: 'openid profile Calendars.ReadWrite',
35
 
36
 
36
     /**
37
     /**
37
      * See https://docs.microsoft.com/en-us/azure/active-directory/develop/
38
      * See https://docs.microsoft.com/en-us/azure/active-directory/develop/
106
                 // get .value of every element from the array of results,
107
                 // get .value of every element from the array of results,
107
                 // which is an array of events and flatten it to one array
108
                 // which is an array of events and flatten it to one array
108
                 // of events
109
                 // of events
109
-                .then(result => [].concat(...result.map(en => en.value)))
110
+                .then(result => [].concat(...result))
110
                 .then(entries => entries.map(e => formatCalendarEntry(e)));
111
                 .then(entries => entries.map(e => formatCalendarEntry(e)));
111
         };
112
         };
112
     },
113
     },
308
                 }));
309
                 }));
309
             });
310
             });
310
         };
311
         };
312
+    },
313
+
314
+    /**
315
+     * Updates calendar event by generating new invite URL and editing the event
316
+     * adding some descriptive text and location.
317
+     *
318
+     * @param {string} id - The event id.
319
+     * @param {string} calendarId - The id of the calendar to use.
320
+     * @param {string} location - The location to save to the event.
321
+     * @returns {function(Dispatch<*>): Promise<string|never>}
322
+     */
323
+    updateCalendarEvent(id: string, calendarId: string, location: string) {
324
+        return (dispatch: Dispatch<*>, getState: Function): Promise<*> => {
325
+            const state = getState()['features/calendar-sync'] || {};
326
+            const token = state.msAuthState && state.msAuthState.accessToken;
327
+
328
+            if (!token) {
329
+                return Promise.reject('Not authorized, please sign in!');
330
+            }
331
+
332
+            const { dialInNumbersUrl } = getState()['features/base/config'];
333
+            const text = getShareInfoText(
334
+                location, dialInNumbersUrl !== undefined, true/* use html */);
335
+
336
+
337
+            const client = Client.init({
338
+                authProvider: done => done(null, token)
339
+            });
340
+
341
+            return client
342
+                .api(`/me/events/${id}`)
343
+                .get()
344
+                .then(description => {
345
+                    const body = description.body;
346
+
347
+                    if (description.bodyPreview) {
348
+                        body.content = `${description.bodyPreview}<br><br>`;
349
+                    }
350
+
351
+                    // replace all new lines from the text with html <br>
352
+                    // to make it pretty
353
+                    body.content += text.split('\n').join('<br>');
354
+
355
+                    return client
356
+                        .api(`/me/calendar/events/${id}`)
357
+                        .patch({
358
+                            body,
359
+                            location: {
360
+                                'displayName': location
361
+                            }
362
+                        });
363
+                });
364
+        };
311
     }
365
     }
312
 };
366
 };
313
 
367
 
317
  * @param {Object} entry - The Microsoft calendar entry.
371
  * @param {Object} entry - The Microsoft calendar entry.
318
  * @private
372
  * @private
319
  * @returns {{
373
  * @returns {{
374
+ *     calendarId: string,
320
  *     description: string,
375
  *     description: string,
321
  *     endDate: string,
376
  *     endDate: string,
322
  *     id: string,
377
  *     id: string,
327
  */
382
  */
328
 function formatCalendarEntry(entry) {
383
 function formatCalendarEntry(entry) {
329
     return {
384
     return {
385
+        calendarId: entry.calendarId,
330
         description: entry.body.content,
386
         description: entry.body.content,
331
         endDate: entry.end.dateTime,
387
         endDate: entry.end.dateTime,
332
         id: entry.id,
388
         id: entry.id,
509
         .filter(filter)
565
         .filter(filter)
510
         .select('id,subject,start,end,location,body')
566
         .select('id,subject,start,end,location,body')
511
         .orderby('createdDateTime DESC')
567
         .orderby('createdDateTime DESC')
512
-        .get();
568
+        .get()
569
+        .then(result => result.value.map(item => {
570
+            return {
571
+                ...item,
572
+                calendarId
573
+            };
574
+        }));
513
 }
575
 }
514
 
576
 
515
 /**
577
 /**

+ 22
- 0
react/features/google-api/actions.js Ver arquivo

1
 /* @flow */
1
 /* @flow */
2
+import { getShareInfoText } from '../invite';
2
 
3
 
3
 import {
4
 import {
4
     SET_GOOGLE_API_PROFILE,
5
     SET_GOOGLE_API_PROFILE,
184
             return profile.getEmail();
185
             return profile.getEmail();
185
         });
186
         });
186
 }
187
 }
188
+
189
+/**
190
+ * Updates the calendar event and adds a location and text.
191
+ *
192
+ * @param {string} id - The event id to update.
193
+ * @param {string} calendarId - The calendar id to use.
194
+ * @param {string} location - The location to add to the event.
195
+ * @returns {function(Dispatch<*>): Promise<string | never>}
196
+ */
197
+export function updateCalendarEvent(
198
+        id: string, calendarId: string, location: string) {
199
+    return (dispatch: Dispatch<*>, getState: Function) => {
200
+
201
+        const { dialInNumbersUrl } = getState()['features/base/config'];
202
+        const text = getShareInfoText(location, dialInNumbersUrl !== undefined);
203
+
204
+        return googleApi.get()
205
+            .then(() =>
206
+                googleApi._updateCalendarEntry(id, calendarId, location, text));
207
+    };
208
+}

+ 79
- 13
react/features/google-api/googleApi.js Ver arquivo

204
      *
204
      *
205
      * @param {Object} entry - The google calendar entry.
205
      * @param {Object} entry - The google calendar entry.
206
      * @returns {{
206
      * @returns {{
207
-     *  id: string,
208
-     *  startDate: string,
207
+     *  calendarId: string,
208
+     *  description: string,
209
      *  endDate: string,
209
      *  endDate: string,
210
-     *  title: string,
210
+     *  id: string,
211
      *  location: string,
211
      *  location: string,
212
-     *  description: string}}
212
+     *  startDate: string,
213
+     *  title: string}}
213
      * @private
214
      * @private
214
      */
215
      */
215
     _convertCalendarEntry(entry) {
216
     _convertCalendarEntry(entry) {
216
         return {
217
         return {
217
-            id: entry.id,
218
-            startDate: entry.start.dateTime,
218
+            calendarId: entry.calendarId,
219
+            description: entry.description,
219
             endDate: entry.end.dateTime,
220
             endDate: entry.end.dateTime,
220
-            title: entry.summary,
221
+            id: entry.id,
221
             location: entry.location,
222
             location: entry.location,
222
-            description: entry.description
223
+            startDate: entry.start.dateTime,
224
+            title: entry.summary
223
         };
225
         };
224
     },
226
     },
225
 
227
 
240
                     return null;
242
                     return null;
241
                 }
243
                 }
242
 
244
 
245
+                // user can edit the events, so we want only those that
246
+                // can be edited
243
                 return this._getGoogleApiClient()
247
                 return this._getGoogleApiClient()
244
                     .client.calendar.calendarList.list();
248
                     .client.calendar.calendarList.list();
245
             })
249
             })
251
                 }
255
                 }
252
 
256
 
253
                 const calendarIds
257
                 const calendarIds
254
-                    = calendarList.result.items.map(en => en.id);
255
-                const promises = calendarIds.map(id => {
258
+                    = calendarList.result.items.map(en => {
259
+                        return {
260
+                            id: en.id,
261
+                            accessRole: en.accessRole
262
+                        };
263
+                    });
264
+                const promises = calendarIds.map(({ id, accessRole }) => {
256
                     const startDate = new Date();
265
                     const startDate = new Date();
257
                     const endDate = new Date();
266
                     const endDate = new Date();
258
 
267
 
259
                     startDate.setDate(startDate.getDate() + fetchStartDays);
268
                     startDate.setDate(startDate.getDate() + fetchStartDays);
260
                     endDate.setDate(endDate.getDate() + fetchEndDays);
269
                     endDate.setDate(endDate.getDate() + fetchEndDays);
261
 
270
 
271
+                    // retrieve the events and adds to the result the calendarId
262
                     return this._getGoogleApiClient()
272
                     return this._getGoogleApiClient()
263
                         .client.calendar.events.list({
273
                         .client.calendar.events.list({
264
                             'calendarId': id,
274
                             'calendarId': id,
267
                             'showDeleted': false,
277
                             'showDeleted': false,
268
                             'singleEvents': true,
278
                             'singleEvents': true,
269
                             'orderBy': 'startTime'
279
                             'orderBy': 'startTime'
270
-                        });
280
+                        })
281
+                        .then(result => result.result.items
282
+                            .map(item => {
283
+                                const resultItem = { ...item };
284
+
285
+                                // add the calendarId only for the events
286
+                                // we can edit
287
+                                if (accessRole === 'writer'
288
+                                    || accessRole === 'owner') {
289
+                                    resultItem.calendarId = id;
290
+                                }
291
+
292
+                                return resultItem;
293
+                            }));
271
                 });
294
                 });
272
 
295
 
273
                 return Promise.all(promises)
296
                 return Promise.all(promises)
274
-                    .then(results =>
275
-                        [].concat(...results.map(rItem => rItem.result.items)))
297
+                    .then(results => [].concat(...results))
276
                     .then(entries =>
298
                     .then(entries =>
277
                         entries.map(e => this._convertCalendarEntry(e)));
299
                         entries.map(e => this._convertCalendarEntry(e)));
278
             });
300
             });
279
     },
301
     },
280
 
302
 
303
+    /* eslint-disable max-params */
304
+    /**
305
+     * Updates the calendar event and adds a location and text.
306
+     *
307
+     * @param {string} id - The event id to update.
308
+     * @param {string} calendarId - The calendar id to use.
309
+     * @param {string} location - The location to add to the event.
310
+     * @param {string} text - The description text to set/append.
311
+     * @returns {Promise<T | never>}
312
+     * @private
313
+     */
314
+    _updateCalendarEntry(id, calendarId, location, text) {
315
+        return this.get()
316
+            .then(() => this.isSignedIn())
317
+            .then(isSignedIn => {
318
+                if (!isSignedIn) {
319
+                    return null;
320
+                }
321
+
322
+                return this._getGoogleApiClient()
323
+                    .client.calendar.events.get({
324
+                        'calendarId': calendarId,
325
+                        'eventId': id
326
+                    }).then(event => {
327
+                        let newDescription = text;
328
+
329
+                        if (event.result.description) {
330
+                            newDescription = `${event.result.description}\n\n${
331
+                                text}`;
332
+                        }
333
+
334
+                        return this._getGoogleApiClient()
335
+                            .client.calendar.events.patch({
336
+                                'calendarId': calendarId,
337
+                                'eventId': id,
338
+                                'description': newDescription,
339
+                                'location': location
340
+                            });
341
+                    });
342
+
343
+            });
344
+    },
345
+    /* eslint-enable max-params */
346
+
281
     /**
347
     /**
282
      * Returns the global Google API Client Library object. Direct use of this
348
      * Returns the global Google API Client Library object. Direct use of this
283
      * method is discouraged; instead use the {@link get} method.
349
      * method is discouraged; instead use the {@link get} method.

+ 3
- 17
react/features/invite/components/info-dialog/InfoDialog.web.js Ver arquivo

7
 import { translate } from '../../../base/i18n';
7
 import { translate } from '../../../base/i18n';
8
 import { isLocalParticipantModerator } from '../../../base/participants';
8
 import { isLocalParticipantModerator } from '../../../base/participants';
9
 
9
 
10
+import { getDialInfoPageURL } from '../../functions';
10
 import DialInNumber from './DialInNumber';
11
 import DialInNumber from './DialInNumber';
11
 import PasswordForm from './PasswordForm';
12
 import PasswordForm from './PasswordForm';
12
 
13
 
266
      * @returns {string}
267
      * @returns {string}
267
      */
268
      */
268
     _getDialInfoPageURL() {
269
     _getDialInfoPageURL() {
269
-        const origin = window.location.origin;
270
-        const encodedConferenceName
271
-            = encodeURIComponent(this.props._conferenceName);
272
-        const pathParts = window.location.pathname.split('/');
273
-
274
-        pathParts.length = pathParts.length - 1;
275
-
276
-        const newPath = pathParts.reduce((accumulator, currentValue) => {
277
-            if (currentValue) {
278
-                return `${accumulator}/${currentValue}`;
279
-            }
280
-
281
-            return accumulator;
282
-        }, '');
283
-
284
-        return `${origin}${newPath}/static/dialInInfo.html?room=${
285
-            encodedConferenceName}`;
270
+        return getDialInfoPageURL(
271
+            encodeURIComponent(this.props._conferenceName));
286
     }
272
     }
287
 
273
 
288
     /**
274
     /**

+ 61
- 1
react/features/invite/functions.js Ver arquivo

1
 // @flow
1
 // @flow
2
 
2
 
3
 import { getAppProp } from '../base/app';
3
 import { getAppProp } from '../base/app';
4
+import { i18next } from '../base/i18n';
4
 import { isLocalParticipantModerator } from '../base/participants';
5
 import { isLocalParticipantModerator } from '../base/participants';
5
-import { doGetJSON } from '../base/util';
6
+import { doGetJSON, parseURIString } from '../base/util';
6
 
7
 
7
 declare var $: Function;
8
 declare var $: Function;
8
 declare var interfaceConfig: Object;
9
 declare var interfaceConfig: Object;
397
                 return Promise.reject(error);
398
                 return Promise.reject(error);
398
             });
399
             });
399
 }
400
 }
401
+
402
+/**
403
+ * Returns descriptive text that can be used to invite participants to a meeting
404
+ * (share via mobile or use it for calendar event description).
405
+ *
406
+ * @param {string} inviteUrl - The conference/location URL.
407
+ * @param {boolean} includeDialInfo - Whether to include or not the dialing
408
+ * information link.
409
+ * @param {boolean} useHtml - Whether to return html text.
410
+ * @returns {string}
411
+ */
412
+export function getShareInfoText(
413
+        inviteUrl: string, includeDialInfo: boolean, useHtml: ?boolean) {
414
+    let roomUrl = inviteUrl;
415
+
416
+    if (useHtml) {
417
+        roomUrl = `<a href="${roomUrl}">${roomUrl}</a>`;
418
+    }
419
+
420
+    let infoText = i18next.t('share.mainText', { roomUrl });
421
+
422
+    if (includeDialInfo) {
423
+        const { room } = parseURIString(inviteUrl);
424
+        let dialInfoPageUrl = getDialInfoPageURL(room);
425
+
426
+        if (useHtml) {
427
+            dialInfoPageUrl
428
+                = `<a href="${dialInfoPageUrl}">${dialInfoPageUrl}</a>`;
429
+        }
430
+
431
+        infoText += i18next.t('share.dialInfoText', { dialInfoPageUrl });
432
+    }
433
+
434
+    return infoText;
435
+}
436
+
437
+/**
438
+ * Generates the URL for the static dial in info page.
439
+ *
440
+ * @param {string} conferenceName - The conference name.
441
+ * @private
442
+ * @returns {string}
443
+ */
444
+export function getDialInfoPageURL(conferenceName: string) {
445
+    const origin = window.location.origin;
446
+    const pathParts = window.location.pathname.split('/');
447
+
448
+    pathParts.length = pathParts.length - 1;
449
+
450
+    const newPath = pathParts.reduce((accumulator, currentValue) => {
451
+        if (currentValue) {
452
+            return `${accumulator}/${currentValue}`;
453
+        }
454
+
455
+        return accumulator;
456
+    }, '');
457
+
458
+    return `${origin}${newPath}/static/dialInInfo.html?room=${conferenceName}`;
459
+}

+ 2
- 1
react/features/share-room/actionTypes.js Ver arquivo

4
  *
4
  *
5
  * {
5
  * {
6
  *     type: BEGIN_SHARE_ROOM,
6
  *     type: BEGIN_SHARE_ROOM,
7
- *     roomURL: string
7
+ *     roomURL: string,
8
+ *     includeDialInfo: boolean
8
  * }
9
  * }
9
  */
10
  */
10
 export const BEGIN_SHARE_ROOM = Symbol('BEGIN_SHARE_ROOM');
11
 export const BEGIN_SHARE_ROOM = Symbol('BEGIN_SHARE_ROOM');

+ 3
- 1
react/features/share-room/actions.js Ver arquivo

19
         }
19
         }
20
         roomURL && dispatch({
20
         roomURL && dispatch({
21
             type: BEGIN_SHARE_ROOM,
21
             type: BEGIN_SHARE_ROOM,
22
-            roomURL
22
+            roomURL,
23
+            includeDialInfo: getState()['features/base/config']
24
+                .dialInNumbersUrl !== undefined
23
         });
25
         });
24
     };
26
     };
25
 }
27
 }

+ 7
- 6
react/features/share-room/middleware.js Ver arquivo

4
 
4
 
5
 import { getName } from '../app';
5
 import { getName } from '../app';
6
 import { MiddlewareRegistry } from '../base/redux';
6
 import { MiddlewareRegistry } from '../base/redux';
7
+import { getShareInfoText } from '../invite';
7
 
8
 
8
 import { endShareRoom } from './actions';
9
 import { endShareRoom } from './actions';
9
 import { BEGIN_SHARE_ROOM } from './actionTypes';
10
 import { BEGIN_SHARE_ROOM } from './actionTypes';
20
 MiddlewareRegistry.register(store => next => action => {
21
 MiddlewareRegistry.register(store => next => action => {
21
     switch (action.type) {
22
     switch (action.type) {
22
     case BEGIN_SHARE_ROOM:
23
     case BEGIN_SHARE_ROOM:
23
-        _shareRoom(action.roomURL, store.dispatch);
24
+        _shareRoom(action.roomURL, action.includeDialInfo, store.dispatch);
24
         break;
25
         break;
25
     }
26
     }
26
 
27
 
31
  * Open the native sheet for sharing a specific conference/room URL.
32
  * Open the native sheet for sharing a specific conference/room URL.
32
  *
33
  *
33
  * @param {string} roomURL - The URL of the conference/room to be shared.
34
  * @param {string} roomURL - The URL of the conference/room to be shared.
35
+ * @param {boolean} includeDialInfo - Whether to include or not the dialing
36
+ * information link.
34
  * @param {Dispatch} dispatch - The Redux dispatch function.
37
  * @param {Dispatch} dispatch - The Redux dispatch function.
35
  * @private
38
  * @private
36
  * @returns {void}
39
  * @returns {void}
37
  */
40
  */
38
-function _shareRoom(roomURL: string, dispatch: Function) {
39
-    // TODO The following display/human-readable strings were submitted for
40
-    // review before i18n was introduces in react/. However, I reviewed it
41
-    // afterwards. Translate the display/human-readable strings.
42
-    const message = `Click the following link to join the meeting: ${roomURL}`;
41
+function _shareRoom(
42
+        roomURL: string, includeDialInfo: boolean, dispatch: Function) {
43
+    const message = getShareInfoText(roomURL, includeDialInfo);
43
     const title = `${getName()} Conference`;
44
     const title = `${getName()} Conference`;
44
     const onFulfilled
45
     const onFulfilled
45
         = (shared: boolean) => dispatch(endShareRoom(roomURL, shared));
46
         = (shared: boolean) => dispatch(endShareRoom(roomURL, shared));

Carregando…
Cancelar
Salvar