Browse Source

ref(sendInvitesForItems): convert to action.

master
hristoterezov 7 years ago
parent
commit
d1af11c67e

+ 93
- 1
react/features/invite/actions.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { getInviteURL } from '../base/connection';
4
+import { inviteVideoRooms } from '../videosipgw';
5
+
3
 import {
6
 import {
4
     BEGIN_ADD_PEOPLE,
7
     BEGIN_ADD_PEOPLE,
5
     UPDATE_DIAL_IN_NUMBERS_FAILED,
8
     UPDATE_DIAL_IN_NUMBERS_FAILED,
6
     UPDATE_DIAL_IN_NUMBERS_SUCCESS
9
     UPDATE_DIAL_IN_NUMBERS_SUCCESS
7
 } from './actionTypes';
10
 } from './actionTypes';
8
-import { getDialInConferenceID, getDialInNumbers } from './functions';
11
+import {
12
+    getDialInConferenceID,
13
+    getDialInNumbers,
14
+    getDigitsOnly,
15
+    invitePeopleAndChatRooms
16
+} from './functions';
17
+
18
+const logger = require('jitsi-meet-logger').getLogger(__filename);
9
 
19
 
10
 /**
20
 /**
11
  * Creates a (redux) action to signal that a click/tap has been performed on
21
  * Creates a (redux) action to signal that a click/tap has been performed on
64
             });
74
             });
65
     };
75
     };
66
 }
76
 }
77
+
78
+/**
79
+ * Send invites for a list of items (may be a combination of users, rooms, phone
80
+ * numbers, and video rooms).
81
+ *
82
+ * @param  {Array<Object>} invites - Items for which invites should be sent.
83
+ * @returns {Promise} Promise containing the list of invites that were not sent.
84
+ */
85
+export function sendInvitesForItems(invites: Array<Object>) {
86
+    return (
87
+            dispatch: Dispatch<*>,
88
+            getState: Function): Promise<Array<Object>> => {
89
+        let allInvitePromises = [];
90
+        let invitesLeftToSend = [ ...invites ];
91
+        const state = getState();
92
+        const { conference } = state['features/base/conference'];
93
+        const { inviteServiceUrl } = state['features/base/config'];
94
+        const inviteUrl = getInviteURL(state);
95
+        const jwt = state['features/base/jwt'].jwt;
96
+
97
+        // First create all promises for dialing out.
98
+        if (conference) {
99
+            const phoneNumbers
100
+                = invitesLeftToSend.filter(({ type }) => type === 'phone');
101
+
102
+            // For each number, dial out. On success, remove the number from
103
+            // {@link invitesLeftToSend}.
104
+            const phoneInvitePromises = phoneNumbers.map(item => {
105
+                const numberToInvite = getDigitsOnly(item.number);
106
+
107
+                return conference.dial(numberToInvite)
108
+                     .then(() => {
109
+                         invitesLeftToSend
110
+                             = invitesLeftToSend.filter(invite =>
111
+                                 invite !== item);
112
+                     })
113
+                     .catch(error => logger.error(
114
+                         'Error inviting phone number:', error));
115
+            });
116
+
117
+            allInvitePromises = allInvitePromises.concat(phoneInvitePromises);
118
+        }
119
+
120
+        const usersAndRooms = invitesLeftToSend.filter(item =>
121
+            item.type === 'user' || item.type === 'room');
122
+
123
+        if (usersAndRooms.length) {
124
+            // Send a request to invite all the rooms and users. On success,
125
+            // filter all rooms and users from {@link invitesLeftToSend}.
126
+            const peopleInvitePromise = invitePeopleAndChatRooms(
127
+                inviteServiceUrl,
128
+                inviteUrl,
129
+                jwt,
130
+                usersAndRooms)
131
+                .then(() => {
132
+                    invitesLeftToSend = invitesLeftToSend.filter(item =>
133
+                        item.type !== 'user' && item.type !== 'room');
134
+                })
135
+                .catch(error => logger.error(
136
+                    'Error inviting people:', error));
137
+
138
+            allInvitePromises.push(peopleInvitePromise);
139
+        }
140
+
141
+        // Sipgw calls are fire and forget. Invite them to the conference
142
+        // then immediately remove them from {@link invitesLeftToSend}.
143
+        const vrooms = invitesLeftToSend.filter(item =>
144
+            item.type === 'videosipgw');
145
+
146
+        conference
147
+            && vrooms.length > 0
148
+            && dispatch(inviteVideoRooms(conference, vrooms));
149
+
150
+        invitesLeftToSend = invitesLeftToSend.filter(item =>
151
+            item.type !== 'videosipgw');
152
+
153
+        return (
154
+            Promise.all(allInvitePromises)
155
+                .then(() => invitesLeftToSend)
156
+        );
157
+    };
158
+}

+ 13
- 85
react/features/invite/components/AddPeopleDialog.web.js View File

7
 import { connect } from 'react-redux';
7
 import { connect } from 'react-redux';
8
 
8
 
9
 import { createInviteDialogEvent, sendAnalytics } from '../../analytics';
9
 import { createInviteDialogEvent, sendAnalytics } from '../../analytics';
10
-import { getInviteURL } from '../../base/connection';
11
 import { Dialog, hideDialog } from '../../base/dialog';
10
 import { Dialog, hideDialog } from '../../base/dialog';
12
 import { translate } from '../../base/i18n';
11
 import { translate } from '../../base/i18n';
13
 import { MultiSelectAutocomplete } from '../../base/react';
12
 import { MultiSelectAutocomplete } from '../../base/react';
14
-import { inviteVideoRooms } from '../../videosipgw';
15
 
13
 
16
 import {
14
 import {
17
-    sendInvitesForItems,
18
-    getInviteResultsForQuery
15
+    getInviteResultsForQuery,
16
+    getInviteTypeCounts
19
 } from '../functions';
17
 } from '../functions';
18
+import { sendInvitesForItems } from '../actions';
20
 
19
 
21
 const logger = require('jitsi-meet-logger').getLogger(__filename);
20
 const logger = require('jitsi-meet-logger').getLogger(__filename);
22
 
21
 
43
          */
42
          */
44
         _dialOutAuthUrl: PropTypes.string,
43
         _dialOutAuthUrl: PropTypes.string,
45
 
44
 
46
-        /**
47
-         * The URL pointing to the service allowing for people invite.
48
-         */
49
-        _inviteServiceUrl: PropTypes.string,
50
-
51
-        /**
52
-         * The url of the conference to invite people to.
53
-         */
54
-        _inviteUrl: PropTypes.string,
55
-
56
         /**
45
         /**
57
          * The JWT token.
46
          * The JWT token.
58
          */
47
          */
79
         dialOutEnabled: PropTypes.bool,
68
         dialOutEnabled: PropTypes.bool,
80
 
69
 
81
         /**
70
         /**
82
-         * The function closing the dialog.
83
-         */
84
-        hideDialog: PropTypes.func,
85
-
86
-        /**
87
-         * Used to invite video rooms.
71
+         * The redux dispatch method.
88
          */
72
          */
89
-        inviteVideoRooms: PropTypes.func,
73
+        dispatch: PropTypes.func,
90
 
74
 
91
         /**
75
         /**
92
          * Invoked to obtain translated strings.
76
          * Invoked to obtain translated strings.
236
         );
220
         );
237
     }
221
     }
238
 
222
 
239
-    /**
240
-     * Helper for determining how many of each type of user is being invited.
241
-     * Used for logging and sending analytics related to invites.
242
-     *
243
-     * @param {Array} inviteItems - An array with the invite items, as created
244
-     * in {@link _parseQueryResults}.
245
-     * @private
246
-     * @returns {Object} An object with keys as user types and values as the
247
-     * number of invites for that type.
248
-     */
249
-    _getInviteTypeCounts(inviteItems = []) {
250
-        const inviteTypeCounts = {};
251
-
252
-        inviteItems.forEach(i => {
253
-            const type = i.item.type;
254
-
255
-            if (!inviteTypeCounts[type]) {
256
-                inviteTypeCounts[type] = 0;
257
-            }
258
-
259
-            inviteTypeCounts[type]++;
260
-        });
261
-
262
-        return inviteTypeCounts;
263
-    }
264
-
265
     _isAddDisabled: () => boolean;
223
     _isAddDisabled: () => boolean;
266
 
224
 
267
     /**
225
     /**
323
      * @returns {void}
281
      * @returns {void}
324
      */
282
      */
325
     _onSubmit() {
283
     _onSubmit() {
326
-        const inviteTypeCounts
327
-            = this._getInviteTypeCounts(this.state.inviteItems);
284
+        const { inviteItems } = this.state;
285
+        const items = inviteItems.map(item => item.item);
286
+        const inviteTypeCounts = getInviteTypeCounts(items);
328
 
287
 
329
         sendAnalytics(createInviteDialogEvent(
288
         sendAnalytics(createInviteDialogEvent(
330
             'clicked', 'inviteButton', {
289
             'clicked', 'inviteButton', {
340
             addToCallInProgress: true
299
             addToCallInProgress: true
341
         });
300
         });
342
 
301
 
343
-        const {
344
-            _conference,
345
-            _inviteServiceUrl,
346
-            _inviteUrl,
347
-            _jwt
348
-        } = this.props;
349
-
350
-        const inviteItems = this.state.inviteItems;
351
-        const items = inviteItems.map(item => item.item);
352
-
353
-        const options = {
354
-            conference: _conference,
355
-            inviteServiceUrl: _inviteServiceUrl,
356
-            inviteUrl: _inviteUrl,
357
-            inviteVideoRooms: this.props.inviteVideoRooms,
358
-            jwt: _jwt
359
-        };
302
+        const { dispatch } = this.props;
360
 
303
 
361
-        sendInvitesForItems(items, options)
304
+        dispatch(sendInvitesForItems(items))
362
             .then(invitesLeftToSend => {
305
             .then(invitesLeftToSend => {
363
                 // If any invites are left that means something failed to send
306
                 // If any invites are left that means something failed to send
364
                 // so treat it as an error.
307
                 // so treat it as an error.
365
                 if (invitesLeftToSend.length) {
308
                 if (invitesLeftToSend.length) {
366
                     const erroredInviteTypeCounts
309
                     const erroredInviteTypeCounts
367
-                        = this._getInviteTypeCounts(invitesLeftToSend);
310
+                        = getInviteTypeCounts(invitesLeftToSend);
368
 
311
 
369
                     logger.error(`${invitesLeftToSend.length} invites failed`,
312
                     logger.error(`${invitesLeftToSend.length} invites failed`,
370
                         erroredInviteTypeCounts);
313
                         erroredInviteTypeCounts);
400
                     addToCallInProgress: false
343
                     addToCallInProgress: false
401
                 });
344
                 });
402
 
345
 
403
-                this.props.hideDialog();
346
+                dispatch(hideDialog());
404
             });
347
             });
405
     }
348
     }
406
 
349
 
580
  * @param {Object} state - The Redux state.
523
  * @param {Object} state - The Redux state.
581
  * @private
524
  * @private
582
  * @returns {{
525
  * @returns {{
583
- *     _conference: Object,
584
  *     _dialOutAuthUrl: string,
526
  *     _dialOutAuthUrl: string,
585
- *     _inviteServiceUrl: string,
586
- *     _inviteUrl: string,
587
  *     _jwt: string,
527
  *     _jwt: string,
588
  *     _peopleSearchQueryTypes: Array<string>,
528
  *     _peopleSearchQueryTypes: Array<string>,
589
  *     _peopleSearchUrl: string
529
  *     _peopleSearchUrl: string
590
  * }}
530
  * }}
591
  */
531
  */
592
 function _mapStateToProps(state) {
532
 function _mapStateToProps(state) {
593
-    const { conference } = state['features/base/conference'];
594
     const {
533
     const {
595
         dialOutAuthUrl,
534
         dialOutAuthUrl,
596
-        inviteServiceUrl,
597
         peopleSearchQueryTypes,
535
         peopleSearchQueryTypes,
598
         peopleSearchUrl
536
         peopleSearchUrl
599
     } = state['features/base/config'];
537
     } = state['features/base/config'];
600
 
538
 
601
     return {
539
     return {
602
-        _conference: conference,
603
         _dialOutAuthUrl: dialOutAuthUrl,
540
         _dialOutAuthUrl: dialOutAuthUrl,
604
-        _inviteServiceUrl: inviteServiceUrl,
605
-        _inviteUrl: getInviteURL(state),
606
         _jwt: state['features/base/jwt'].jwt,
541
         _jwt: state['features/base/jwt'].jwt,
607
         _peopleSearchQueryTypes: peopleSearchQueryTypes,
542
         _peopleSearchQueryTypes: peopleSearchQueryTypes,
608
         _peopleSearchUrl: peopleSearchUrl
543
         _peopleSearchUrl: peopleSearchUrl
609
     };
544
     };
610
 }
545
 }
611
 
546
 
612
-export default translate(
613
-    connect(
614
-            _mapStateToProps,
615
-            /* mapDispatchToProps */ {
616
-                hideDialog,
617
-                inviteVideoRooms
618
-            })(
619
-        AddPeopleDialog));
547
+export default translate(connect(_mapStateToProps)(AddPeopleDialog));

+ 18
- 115
react/features/invite/functions.js View File

81
  * @private
81
  * @private
82
  * @returns {string} A string with only numbers.
82
  * @returns {string} A string with only numbers.
83
  */
83
  */
84
-function getDigitsOnly(text: string = ''): string {
84
+export function getDigitsOnly(text: string = ''): string {
85
     return text.replace(/\D/g, '');
85
     return text.replace(/\D/g, '');
86
 }
86
 }
87
 
87
 
227
  * type items to invite.
227
  * type items to invite.
228
  * @returns {Promise} - The promise created by the request.
228
  * @returns {Promise} - The promise created by the request.
229
  */
229
  */
230
-function invitePeopleAndChatRooms( // eslint-disable-line max-params
230
+export function invitePeopleAndChatRooms( // eslint-disable-line max-params
231
         inviteServiceUrl: string,
231
         inviteServiceUrl: string,
232
         inviteUrl: string,
232
         inviteUrl: string,
233
         jwt: string,
233
         jwt: string,
367
 }
367
 }
368
 
368
 
369
 /**
369
 /**
370
- * Type of the options to use when sending invites.
371
- */
372
-export type SendInvitesOptions = {
373
-
374
-    /**
375
-     * Conference object used to dial out.
376
-     */
377
-    conference: Object,
378
-
379
-    /**
380
-     * The URL to send invites through.
381
-     */
382
-    inviteServiceUrl: string,
383
-
384
-    /**
385
-     * The URL sent with each invite.
386
-     */
387
-    inviteUrl: string,
388
-
389
-    /**
390
-     * The function to use to invite video rooms.
391
-     *
392
-     * @param  {Object} The conference to which the video rooms should be
393
-     * invited.
394
-     * @param  {Array<Object>} The list of rooms that should be invited.
395
-     * @returns {void}
396
-     */
397
-    inviteVideoRooms: (Object, Array<Object>) => void,
398
-
399
-    /**
400
-     * The jwt token to pass to the invite service.
401
-     */
402
-    jwt: string
403
-};
404
-
405
-/**
406
- * Send invites for a list of items (may be a combination of users, rooms, phone
407
- * numbers, and video rooms).
370
+ * Helper for determining how many of each type of user is being invited.
371
+ * Used for logging and sending analytics related to invites.
408
  *
372
  *
409
- * @param  {Array<Object>} invites - Items for which invites should be sent.
410
- * @param  {SendInvitesOptions} options - Options to use when sending the
411
- * provided invites.
412
- * @returns {Promise} Promise containing the list of invites that were not sent.
373
+ * @param {Array} inviteItems - An array with the invite items, as created
374
+ * in {@link _parseQueryResults}.
375
+ * @private
376
+ * @returns {Object} An object with keys as user types and values as the
377
+ * number of invites for that type.
413
  */
378
  */
414
-export function sendInvitesForItems(
415
-        invites: Array<Object>,
416
-        options: SendInvitesOptions
417
-): Promise<Array<Object>> {
418
-
419
-    const {
420
-        conference,
421
-        inviteServiceUrl,
422
-        inviteUrl,
423
-        inviteVideoRooms,
424
-        jwt
425
-    } = options;
426
-
427
-    let allInvitePromises = [];
428
-    let invitesLeftToSend = [ ...invites ];
379
+export function getInviteTypeCounts(inviteItems: Array<Object> = []) {
380
+    const inviteTypeCounts = {};
429
 
381
 
430
-    // First create all promises for dialing out.
431
-    if (conference) {
432
-        const phoneNumbers = invitesLeftToSend.filter(
433
-            item => item.type === 'phone');
382
+    inviteItems.forEach(({ type }) => {
434
 
383
 
435
-        // For each number, dial out. On success, remove the number from
436
-        // {@link invitesLeftToSend}.
437
-        const phoneInvitePromises = phoneNumbers.map(item => {
438
-            const numberToInvite = getDigitsOnly(item.number);
439
-
440
-            return conference.dial(numberToInvite)
441
-                    .then(() => {
442
-                        invitesLeftToSend
443
-                            = invitesLeftToSend.filter(invite =>
444
-                                invite !== item);
445
-                    })
446
-                    .catch(error => logger.error(
447
-                        'Error inviting phone number:', error));
448
-
449
-        });
450
-
451
-        allInvitePromises = allInvitePromises.concat(phoneInvitePromises);
452
-    }
453
-
454
-    const usersAndRooms = invitesLeftToSend.filter(item =>
455
-        item.type === 'user' || item.type === 'room');
456
-
457
-    if (usersAndRooms.length) {
458
-        // Send a request to invite all the rooms and users. On success,
459
-        // filter all rooms and users from {@link invitesLeftToSend}.
460
-        const peopleInvitePromise = invitePeopleAndChatRooms(
461
-            inviteServiceUrl,
462
-            inviteUrl,
463
-            jwt,
464
-            usersAndRooms)
465
-            .then(() => {
466
-                invitesLeftToSend = invitesLeftToSend.filter(item =>
467
-                    item.type !== 'user' && item.type !== 'room');
468
-            })
469
-            .catch(error => logger.error(
470
-                'Error inviting people:', error));
471
-
472
-        allInvitePromises.push(peopleInvitePromise);
473
-    }
474
-
475
-    // Sipgw calls are fire and forget. Invite them to the conference
476
-    // then immediately remove them from {@link invitesLeftToSend}.
477
-    const vrooms = invitesLeftToSend.filter(item =>
478
-        item.type === 'videosipgw');
479
-
480
-    conference
481
-        && vrooms.length > 0
482
-        && inviteVideoRooms(conference, vrooms);
384
+        if (!inviteTypeCounts[type]) {
385
+            inviteTypeCounts[type] = 0;
386
+        }
483
 
387
 
484
-    invitesLeftToSend = invitesLeftToSend.filter(item =>
485
-        item.type !== 'videosipgw');
388
+        inviteTypeCounts[type]++;
389
+    });
486
 
390
 
487
-    return Promise.all(allInvitePromises)
488
-        .then(() => invitesLeftToSend);
391
+    return inviteTypeCounts;
489
 }
392
 }

+ 6
- 18
react/features/invite/middleware.native.js View File

5
 
5
 
6
 import { MiddlewareRegistry } from '../base/redux';
6
 import { MiddlewareRegistry } from '../base/redux';
7
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
7
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
8
-import { getInviteURL } from '../base/connection';
9
-import { inviteVideoRooms } from '../videosipgw';
10
 
8
 
11
 import {
9
 import {
12
     BEGIN_ADD_PEOPLE,
10
     BEGIN_ADD_PEOPLE,
15
 import {
13
 import {
16
     getInviteResultsForQuery,
14
     getInviteResultsForQuery,
17
     isAddPeopleEnabled,
15
     isAddPeopleEnabled,
18
-    isDialOutEnabled,
19
-    sendInvitesForItems
16
+    isDialOutEnabled
20
 } from './functions';
17
 } from './functions';
18
+import { sendInvitesForItems } from './actions';
21
 import './middleware.any';
19
 import './middleware.any';
22
 
20
 
23
 /**
21
 /**
137
  */
135
  */
138
 function _onInvite(
136
 function _onInvite(
139
         { addPeopleControllerScope, externalAPIScope, invitees }) {
137
         { addPeopleControllerScope, externalAPIScope, invitees }) {
140
-    const { getState } = this; // eslint-disable-line no-invalid-this
141
-    const state = getState();
138
+    const { dispatch, getState } = this; // eslint-disable-line no-invalid-this
142
 
139
 
143
     // If there are multiple JitsiMeetView instances alive, they will all get
140
     // If there are multiple JitsiMeetView instances alive, they will all get
144
     // the event, since there is a single bridge, so make sure we don't act if
141
     // the event, since there is a single bridge, so make sure we don't act if
145
     // the event is not for us.
142
     // the event is not for us.
146
-    if (state['features/app'].app.props.externalAPIScope !== externalAPIScope) {
143
+    if (getState()['features/app'].app.props.externalAPIScope
144
+            !== externalAPIScope) {
147
         return;
145
         return;
148
     }
146
     }
149
 
147
 
150
-    const { conference } = state['features/base/conference'];
151
-    const { inviteServiceUrl } = state['features/base/config'];
152
-    const options = {
153
-        conference,
154
-        inviteServiceUrl,
155
-        inviteUrl: getInviteURL(state),
156
-        inviteVideoRooms,
157
-        jwt: state['features/base/jwt'].jwt
158
-    };
159
-
160
-    sendInvitesForItems(invitees, options)
148
+    dispatch(sendInvitesForItems(invitees))
161
         .then(failedInvitees =>
149
         .then(failedInvitees =>
162
             Invite.inviteSettled(
150
             Invite.inviteSettled(
163
                 externalAPIScope,
151
                 externalAPIScope,

Loading…
Cancel
Save