@webex/plugin-meetings 3.8.0-next.82 → 3.8.0-next.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/member/index.js +45 -9
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +3 -0
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +18 -13
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +95 -29
- package/dist/members/index.js.map +1 -1
- package/dist/types/member/index.d.ts +20 -6
- package/dist/types/member/types.d.ts +73 -14
- package/dist/types/member/util.d.ts +31 -34
- package/dist/types/members/collection.d.ts +6 -5
- package/dist/types/members/index.d.ts +17 -43
- package/dist/webinar/index.js +1 -1
- package/package.json +3 -3
- package/src/member/index.ts +58 -23
- package/src/member/types.ts +82 -16
- package/src/member/util.ts +45 -41
- package/src/members/collection.ts +4 -3
- package/src/members/index.ts +90 -18
- package/test/unit/spec/members/index.js +164 -52
package/src/member/types.ts
CHANGED
@@ -15,22 +15,6 @@ export type ServerRoleShape = {
|
|
15
15
|
hasRole: boolean;
|
16
16
|
};
|
17
17
|
|
18
|
-
export type ParticipantWithRoles = {
|
19
|
-
controls: {
|
20
|
-
role: {
|
21
|
-
roles: Array<ServerRoleShape>;
|
22
|
-
};
|
23
|
-
};
|
24
|
-
};
|
25
|
-
|
26
|
-
export type ParticipantWithBrb = {
|
27
|
-
controls: {
|
28
|
-
brb?: {
|
29
|
-
enabled: boolean;
|
30
|
-
};
|
31
|
-
};
|
32
|
-
};
|
33
|
-
|
34
18
|
// values are inherited from locus so don't update these
|
35
19
|
export enum MediaStatus {
|
36
20
|
RECVONLY = 'RECVONLY', // participant only receiving and not sending
|
@@ -44,3 +28,85 @@ export interface IMediaStatus {
|
|
44
28
|
audio: MediaStatus;
|
45
29
|
video: MediaStatus;
|
46
30
|
}
|
31
|
+
|
32
|
+
export type Csi = number;
|
33
|
+
export type Direction = 'inactive' | 'sendrecv' | 'sendonly' | 'recvonly';
|
34
|
+
export type ParticipantUrl = string;
|
35
|
+
export interface MediaSession {
|
36
|
+
csi: Csi;
|
37
|
+
direction: Direction;
|
38
|
+
mediaContent: 'main' | 'slides';
|
39
|
+
mediaType: 'audio' | 'video';
|
40
|
+
state: string;
|
41
|
+
}
|
42
|
+
|
43
|
+
export interface Intent {
|
44
|
+
associatedWith: ParticipantUrl;
|
45
|
+
id: string;
|
46
|
+
type: string; // could be "WAIT" or "OBSERVE" or other....
|
47
|
+
}
|
48
|
+
export interface ParticipantDevice {
|
49
|
+
correlationId: string;
|
50
|
+
csis: Csi[];
|
51
|
+
deviceType: string; // WDM device type, could be "WEB", "TP_ENDPOINT", "MAC" or other things, don't know the full list, so keeping it as string
|
52
|
+
intent?: Intent;
|
53
|
+
intents: Array<Intent | null>;
|
54
|
+
isVideoCallback: boolean;
|
55
|
+
mediaSessions: Array<MediaSession>;
|
56
|
+
mediaSessionsExternal: boolean;
|
57
|
+
state: string; // probably one of MEETING_STATE.STATES
|
58
|
+
}
|
59
|
+
|
60
|
+
// this is not a complete type, Locus may send more fields
|
61
|
+
export interface ParticipantPerson {
|
62
|
+
id: string;
|
63
|
+
isExternal: boolean;
|
64
|
+
name: string;
|
65
|
+
orgId: string;
|
66
|
+
}
|
67
|
+
|
68
|
+
export interface ParticipantMediaStatus {
|
69
|
+
audioStatus: MediaStatus;
|
70
|
+
videoStatus: MediaStatus;
|
71
|
+
audioSlidesStatus?: MediaStatus;
|
72
|
+
videoSlidesStatus?: MediaStatus;
|
73
|
+
csis: Csi[];
|
74
|
+
}
|
75
|
+
|
76
|
+
// this is not a complete type, Locus may send more fields
|
77
|
+
export interface ParticipantControls {
|
78
|
+
role: {
|
79
|
+
roles: Array<ServerRoleShape>;
|
80
|
+
};
|
81
|
+
brb?: {
|
82
|
+
enabled: boolean;
|
83
|
+
};
|
84
|
+
hand: {
|
85
|
+
raised: boolean;
|
86
|
+
};
|
87
|
+
localRecord: {
|
88
|
+
recording: boolean;
|
89
|
+
};
|
90
|
+
}
|
91
|
+
|
92
|
+
// this is not a complete type, Locus may send more fields
|
93
|
+
export interface Participant {
|
94
|
+
canBeController: boolean;
|
95
|
+
controls: ParticipantControls;
|
96
|
+
deviceUrl: string;
|
97
|
+
devices: Array<ParticipantDevice>;
|
98
|
+
guest: boolean;
|
99
|
+
id: string;
|
100
|
+
identity: string;
|
101
|
+
identityTrustLevel: string; // could be 'INTERNAL', 'EXTERNAL' or other....
|
102
|
+
isCreator: boolean;
|
103
|
+
moderator: boolean; // Locus docs say this is deprecated and role control should be used instead
|
104
|
+
moderatorAssignmentNotAllowed: boolean;
|
105
|
+
presenterAssignmentNotAllowed: boolean;
|
106
|
+
person: ParticipantPerson;
|
107
|
+
resourceGuest: boolean;
|
108
|
+
state: string; // probably one of MEETING_STATE.STATES
|
109
|
+
status: ParticipantMediaStatus;
|
110
|
+
type: string;
|
111
|
+
url: ParticipantUrl;
|
112
|
+
}
|
package/src/member/util.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import {
|
2
2
|
IExternalRoles,
|
3
|
-
ParticipantWithRoles,
|
4
3
|
ServerRoles,
|
5
4
|
ServerRoleShape,
|
6
5
|
IMediaStatus,
|
7
|
-
|
6
|
+
Participant,
|
7
|
+
ParticipantUrl,
|
8
8
|
} from './types';
|
9
9
|
import {
|
10
10
|
_USER_,
|
@@ -46,23 +46,23 @@ const MemberUtil = {
|
|
46
46
|
* @param {Object} participant - The locus participant object.
|
47
47
|
* @returns {[ServerRoleShape]}
|
48
48
|
*/
|
49
|
-
getControlsRoles: (participant:
|
49
|
+
getControlsRoles: (participant: Participant): Array<ServerRoleShape> =>
|
50
50
|
participant?.controls?.role?.roles,
|
51
51
|
|
52
52
|
/**
|
53
53
|
* Checks if the participant has the brb status enabled.
|
54
54
|
*
|
55
|
-
* @param {
|
55
|
+
* @param {Participant} participant - The locus participant object.
|
56
56
|
* @returns {boolean} - True if the participant has brb enabled, false otherwise.
|
57
57
|
*/
|
58
|
-
isBrb: (participant:
|
58
|
+
isBrb: (participant: Participant): boolean => participant.controls?.brb?.enabled || false,
|
59
59
|
|
60
60
|
/**
|
61
61
|
* @param {Object} participant - The locus participant object.
|
62
62
|
* @param {ServerRoles} controlRole the search role
|
63
63
|
* @returns {Boolean}
|
64
64
|
*/
|
65
|
-
hasRole: (participant:
|
65
|
+
hasRole: (participant: Participant, controlRole: ServerRoles): boolean =>
|
66
66
|
MemberUtil.getControlsRoles(participant)?.some(
|
67
67
|
(role) => role.type === controlRole && role.hasRole
|
68
68
|
),
|
@@ -71,28 +71,28 @@ const MemberUtil = {
|
|
71
71
|
* @param {Object} participant - The locus participant object.
|
72
72
|
* @returns {Boolean}
|
73
73
|
*/
|
74
|
-
hasCohost: (participant:
|
74
|
+
hasCohost: (participant: Participant): boolean =>
|
75
75
|
MemberUtil.hasRole(participant, ServerRoles.Cohost) || false,
|
76
76
|
|
77
77
|
/**
|
78
78
|
* @param {Object} participant - The locus participant object.
|
79
79
|
* @returns {Boolean}
|
80
80
|
*/
|
81
|
-
hasModerator: (participant:
|
81
|
+
hasModerator: (participant: Participant): boolean =>
|
82
82
|
MemberUtil.hasRole(participant, ServerRoles.Moderator) || false,
|
83
83
|
|
84
84
|
/**
|
85
85
|
* @param {Object} participant - The locus participant object.
|
86
86
|
* @returns {Boolean}
|
87
87
|
*/
|
88
|
-
hasPresenter: (participant:
|
88
|
+
hasPresenter: (participant: Participant): boolean =>
|
89
89
|
MemberUtil.hasRole(participant, ServerRoles.Presenter) || false,
|
90
90
|
|
91
91
|
/**
|
92
92
|
* @param {Object} participant - The locus participant object.
|
93
93
|
* @returns {IExternalRoles}
|
94
94
|
*/
|
95
|
-
extractControlRoles: (participant:
|
95
|
+
extractControlRoles: (participant: Participant): IExternalRoles => {
|
96
96
|
const roles = {
|
97
97
|
cohost: MemberUtil.hasCohost(participant),
|
98
98
|
moderator: MemberUtil.hasModerator(participant),
|
@@ -106,26 +106,26 @@ const MemberUtil = {
|
|
106
106
|
* @param {Object} participant - The locus participant object.
|
107
107
|
* @returns {Boolean}
|
108
108
|
*/
|
109
|
-
isUser: (participant:
|
109
|
+
isUser: (participant: Participant) => participant && participant.type === _USER_,
|
110
110
|
|
111
|
-
isModerator: (participant) => participant && participant.moderator,
|
111
|
+
isModerator: (participant: Participant) => participant && participant.moderator,
|
112
112
|
|
113
113
|
/**
|
114
114
|
* @param {Object} participant - The locus participant object.
|
115
115
|
* @returns {Boolean}
|
116
116
|
*/
|
117
|
-
isGuest: (participant:
|
117
|
+
isGuest: (participant: Participant) => participant && participant.guest,
|
118
118
|
|
119
119
|
/**
|
120
120
|
* @param {Object} participant - The locus participant object.
|
121
121
|
* @returns {Boolean}
|
122
122
|
*/
|
123
|
-
isDevice: (participant:
|
123
|
+
isDevice: (participant: Participant) => participant && participant.type === _RESOURCE_ROOM_,
|
124
124
|
|
125
|
-
isModeratorAssignmentProhibited: (participant) =>
|
125
|
+
isModeratorAssignmentProhibited: (participant: Participant) =>
|
126
126
|
participant && participant.moderatorAssignmentNotAllowed,
|
127
127
|
|
128
|
-
isPresenterAssignmentProhibited: (participant) =>
|
128
|
+
isPresenterAssignmentProhibited: (participant: Participant) =>
|
129
129
|
participant && participant.presenterAssignmentNotAllowed,
|
130
130
|
|
131
131
|
/**
|
@@ -135,30 +135,16 @@ const MemberUtil = {
|
|
135
135
|
* @param {String} id
|
136
136
|
* @returns {Boolean}
|
137
137
|
*/
|
138
|
-
isSame: (participant:
|
138
|
+
isSame: (participant: Participant, id: string) =>
|
139
139
|
participant && (participant.id === id || (participant.person && participant.person.id === id)),
|
140
140
|
|
141
|
-
/**
|
142
|
-
* checks to see if the participant id is the same as the passed id for associated devices
|
143
|
-
* there are multiple ids that can be used
|
144
|
-
* @param {Object} participant - The locus participant object.
|
145
|
-
* @param {String} id
|
146
|
-
* @returns {Boolean}
|
147
|
-
*/
|
148
|
-
isAssociatedSame: (participant: any, id: string) =>
|
149
|
-
participant &&
|
150
|
-
participant.associatedUsers &&
|
151
|
-
participant.associatedUsers.some(
|
152
|
-
(user) => user.id === id || (user.person && user.person.id === id)
|
153
|
-
),
|
154
|
-
|
155
141
|
/**
|
156
142
|
* @param {Object} participant - The locus participant object.
|
157
143
|
* @param {Boolean} isGuest
|
158
144
|
* @param {String} status
|
159
145
|
* @returns {Boolean}
|
160
146
|
*/
|
161
|
-
isNotAdmitted: (participant:
|
147
|
+
isNotAdmitted: (participant: Participant, isGuest: boolean, status: string): boolean =>
|
162
148
|
participant &&
|
163
149
|
participant.guest &&
|
164
150
|
((participant.devices &&
|
@@ -175,7 +161,7 @@ const MemberUtil = {
|
|
175
161
|
* @param {Object} participant - The locus participant object.
|
176
162
|
* @returns {Boolean}
|
177
163
|
*/
|
178
|
-
isAudioMuted: (participant:
|
164
|
+
isAudioMuted: (participant: Participant) => {
|
179
165
|
if (!participant) {
|
180
166
|
throw new ParameterError('Audio could not be processed, participant is undefined.');
|
181
167
|
}
|
@@ -187,7 +173,7 @@ const MemberUtil = {
|
|
187
173
|
* @param {Object} participant - The locus participant object.
|
188
174
|
* @returns {Boolean}
|
189
175
|
*/
|
190
|
-
isVideoMuted: (participant:
|
176
|
+
isVideoMuted: (participant: Participant): boolean => {
|
191
177
|
if (!participant) {
|
192
178
|
throw new ParameterError('Video could not be processed, participant is undefined.');
|
193
179
|
}
|
@@ -199,7 +185,7 @@ const MemberUtil = {
|
|
199
185
|
* @param {Object} participant - The locus participant object.
|
200
186
|
* @returns {Boolean}
|
201
187
|
*/
|
202
|
-
isHandRaised: (participant:
|
188
|
+
isHandRaised: (participant: Participant) => {
|
203
189
|
if (!participant) {
|
204
190
|
throw new ParameterError('Raise hand could not be processed, participant is undefined.');
|
205
191
|
}
|
@@ -256,7 +242,7 @@ const MemberUtil = {
|
|
256
242
|
* @param {String} controlsAccessor
|
257
243
|
* @returns {Boolean | undefined}
|
258
244
|
*/
|
259
|
-
isMuted: (participant:
|
245
|
+
isMuted: (participant: Participant, statusAccessor: string, controlsAccessor: string) => {
|
260
246
|
// check remote mute
|
261
247
|
const remoteMute = participant?.controls?.[controlsAccessor]?.muted;
|
262
248
|
if (remoteMute === true) {
|
@@ -295,7 +281,7 @@ const MemberUtil = {
|
|
295
281
|
* @param {Object} participant - The locus participant object.
|
296
282
|
* @returns {Boolean}
|
297
283
|
*/
|
298
|
-
isRecording: (participant:
|
284
|
+
isRecording: (participant: Participant) => {
|
299
285
|
if (!participant) {
|
300
286
|
throw new ParameterError('Recording could not be processed, participant is undefined.');
|
301
287
|
}
|
@@ -341,7 +327,7 @@ const MemberUtil = {
|
|
341
327
|
* @param {Object} participant - The locus participant object.
|
342
328
|
* @returns {String}
|
343
329
|
*/
|
344
|
-
extractStatus: (participant:
|
330
|
+
extractStatus: (participant: Participant) => {
|
345
331
|
if (!(participant && participant.devices && participant.devices.length)) {
|
346
332
|
return _NOT_IN_MEETING_;
|
347
333
|
}
|
@@ -371,7 +357,7 @@ const MemberUtil = {
|
|
371
357
|
* @param {Object} participant - The locus participant object.
|
372
358
|
* @returns {String}
|
373
359
|
*/
|
374
|
-
extractId: (participant:
|
360
|
+
extractId: (participant: Participant) => {
|
375
361
|
if (participant) {
|
376
362
|
return participant.id;
|
377
363
|
}
|
@@ -384,7 +370,7 @@ const MemberUtil = {
|
|
384
370
|
* @param {Object} participant - The locus participant object.
|
385
371
|
* @returns {Object}
|
386
372
|
*/
|
387
|
-
extractMediaStatus: (participant:
|
373
|
+
extractMediaStatus: (participant: Participant): IMediaStatus => {
|
388
374
|
if (!participant) {
|
389
375
|
throw new ParameterError('Media status could not be extracted, participant is undefined.');
|
390
376
|
}
|
@@ -399,12 +385,30 @@ const MemberUtil = {
|
|
399
385
|
* @param {Object} participant - The locus participant object.
|
400
386
|
* @returns {String}
|
401
387
|
*/
|
402
|
-
extractName: (participant:
|
388
|
+
extractName: (participant: Participant) => {
|
403
389
|
if (participant && participant.person) {
|
404
390
|
return participant.person.name;
|
405
391
|
}
|
406
392
|
|
407
393
|
return null;
|
408
394
|
},
|
395
|
+
|
396
|
+
/**
|
397
|
+
* @param {Object} participant - The locus participant object.
|
398
|
+
* @returns {String}
|
399
|
+
*/
|
400
|
+
extractPairedWithParticipantUrl: (participant: Participant): ParticipantUrl | undefined => {
|
401
|
+
let participantUrl;
|
402
|
+
|
403
|
+
participant?.devices?.forEach((device) => {
|
404
|
+
device?.intents?.forEach((intent) => {
|
405
|
+
if (intent?.type === _OBSERVE_ && intent?.associatedWith) {
|
406
|
+
participantUrl = intent.associatedWith;
|
407
|
+
}
|
408
|
+
});
|
409
|
+
});
|
410
|
+
|
411
|
+
return participantUrl;
|
412
|
+
},
|
409
413
|
};
|
410
414
|
export default MemberUtil;
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import {MEETINGS} from '../constants';
|
2
|
+
import Member from '../member';
|
2
3
|
|
3
4
|
/**
|
4
5
|
* @class MembersCollection
|
5
6
|
*/
|
6
7
|
export default class MembersCollection {
|
7
|
-
members:
|
8
|
+
members: Record<string, Member>;
|
8
9
|
namespace = MEETINGS;
|
9
10
|
/**
|
10
11
|
* @param {Object} locus
|
@@ -14,11 +15,11 @@ export default class MembersCollection {
|
|
14
15
|
this.members = {};
|
15
16
|
}
|
16
17
|
|
17
|
-
set(id, member) {
|
18
|
+
set(id: string, member: Member) {
|
18
19
|
this.members[id] = member;
|
19
20
|
}
|
20
21
|
|
21
|
-
setAll(members) {
|
22
|
+
setAll(members: Record<string, Member>) {
|
22
23
|
this.members = members;
|
23
24
|
}
|
24
25
|
|
package/src/members/index.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*!
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
3
3
|
*/
|
4
|
-
import {isEmpty} from 'lodash';
|
4
|
+
import {get, isEmpty, set} from 'lodash';
|
5
5
|
// @ts-ignore
|
6
6
|
import {StatelessWebexPlugin} from '@webex/webex-core';
|
7
7
|
|
@@ -73,6 +73,7 @@ import {ServerRoleShape} from './types';
|
|
73
73
|
* @memberof Members
|
74
74
|
*/
|
75
75
|
|
76
|
+
type UpdatedMembers = {added: Array<Member>; updated: Array<Member>};
|
76
77
|
/**
|
77
78
|
* @class Members
|
78
79
|
*/
|
@@ -81,7 +82,7 @@ export default class Members extends StatelessWebexPlugin {
|
|
81
82
|
locusUrl: any;
|
82
83
|
mediaShareContentId: any;
|
83
84
|
mediaShareWhiteboardId: any;
|
84
|
-
membersCollection:
|
85
|
+
membersCollection: MembersCollection;
|
85
86
|
membersRequest: any;
|
86
87
|
receiveSlotManager: ReceiveSlotManager;
|
87
88
|
mediaRequestManagers: {
|
@@ -321,6 +322,63 @@ export default class Members extends StatelessWebexPlugin {
|
|
321
322
|
);
|
322
323
|
}
|
323
324
|
|
325
|
+
/**
|
326
|
+
* Updates properties on members that rely on information from other members.
|
327
|
+
* This function MUST be called only after the membersCollection has been fully updated
|
328
|
+
* @param {UpdatedMembers} membersUpdate
|
329
|
+
* @returns {Object} membersCollection
|
330
|
+
* @private
|
331
|
+
* @memberof Members
|
332
|
+
*/
|
333
|
+
private updateRelationsBetweenMembers(membersUpdate: UpdatedMembers) {
|
334
|
+
const updatePairedMembers = (membersList: Member[]) => {
|
335
|
+
membersList.forEach((member) => {
|
336
|
+
if (!member.pairedWith.participantUrl) {
|
337
|
+
// if we don't have a participantUrl set, it may be that we had it in the past and not anymore, so cleanup the rest of the data
|
338
|
+
if (member.pairedWith.memberId) {
|
339
|
+
const pairedMember = this.membersCollection.get(member.pairedWith.memberId);
|
340
|
+
|
341
|
+
if (pairedMember) {
|
342
|
+
// remove member from pairedMember's associatedUsers array
|
343
|
+
pairedMember.associatedUsers.delete(member.id);
|
344
|
+
|
345
|
+
if (pairedMember.associatedUser === member.id) {
|
346
|
+
pairedMember.associatedUser = null;
|
347
|
+
}
|
348
|
+
|
349
|
+
// reset all the props that we set on pairedMember
|
350
|
+
pairedMember.isPairedWithSelf = false;
|
351
|
+
pairedMember.isHost = false;
|
352
|
+
}
|
353
|
+
}
|
354
|
+
member.pairedWith.memberId = undefined;
|
355
|
+
} else if (member.pairedWith.memberId === undefined) {
|
356
|
+
// we have participantUrl set but not memberId, so find the member and set it
|
357
|
+
const pairedMember = Object.values(this.membersCollection.getAll()).find(
|
358
|
+
(m) => m.participant?.url === member.pairedWith.participantUrl
|
359
|
+
);
|
360
|
+
|
361
|
+
if (pairedMember) {
|
362
|
+
member.pairedWith.memberId = pairedMember.id;
|
363
|
+
pairedMember.associatedUsers.add(member.id);
|
364
|
+
|
365
|
+
if (pairedMember.associatedUsers.size === 1) {
|
366
|
+
// associatedUser is deprecated, because it's broken - device can have multiple associated users,
|
367
|
+
// so for backwards compatibility we set it to the first associated user
|
368
|
+
pairedMember.associatedUser = member.id;
|
369
|
+
}
|
370
|
+
|
371
|
+
pairedMember.isPairedWithSelf = member.isSelf;
|
372
|
+
pairedMember.isHost = member.isHost;
|
373
|
+
}
|
374
|
+
}
|
375
|
+
});
|
376
|
+
};
|
377
|
+
|
378
|
+
updatePairedMembers(membersUpdate.updated);
|
379
|
+
updatePairedMembers(membersUpdate.added);
|
380
|
+
}
|
381
|
+
|
324
382
|
/**
|
325
383
|
* when new participant updates come in, both delta and full participants, update them in members collection
|
326
384
|
* delta object in the event will have {updated, added} and full will be the full membersCollection
|
@@ -338,6 +396,8 @@ export default class Members extends StatelessWebexPlugin {
|
|
338
396
|
const delta = this.handleLocusInfoUpdatedParticipants(payload);
|
339
397
|
const full = this.handleMembersUpdate(delta); // SDK should propagate the full list for both delta and non delta updates
|
340
398
|
|
399
|
+
this.updateRelationsBetweenMembers(delta);
|
400
|
+
|
341
401
|
this.receiveSlotManager?.updateMemberIds();
|
342
402
|
|
343
403
|
Trigger.trigger(
|
@@ -478,20 +538,14 @@ export default class Members extends StatelessWebexPlugin {
|
|
478
538
|
|
479
539
|
/**
|
480
540
|
* sets values in the members collection for updated and added properties from delta
|
481
|
-
* @param {
|
541
|
+
* @param {UpdatedMembers} membersUpdate
|
482
542
|
* @returns {Object} membersCollection
|
483
543
|
* @private
|
484
544
|
* @memberof Members
|
485
545
|
*/
|
486
|
-
private handleMembersUpdate(membersUpdate:
|
487
|
-
|
488
|
-
|
489
|
-
this.constructMembers(membersUpdate.updated);
|
490
|
-
}
|
491
|
-
if (membersUpdate.added) {
|
492
|
-
this.constructMembers(membersUpdate.added);
|
493
|
-
}
|
494
|
-
}
|
546
|
+
private handleMembersUpdate(membersUpdate: UpdatedMembers) {
|
547
|
+
this.constructMembers(membersUpdate.updated, true);
|
548
|
+
this.constructMembers(membersUpdate.added, false);
|
495
549
|
|
496
550
|
return this.membersCollection.getAll();
|
497
551
|
}
|
@@ -499,12 +553,30 @@ export default class Members extends StatelessWebexPlugin {
|
|
499
553
|
/**
|
500
554
|
* set members to the member collection from each updated/added lists as passed in
|
501
555
|
* @param {Array} list
|
556
|
+
* @param {boolean} isUpdate
|
502
557
|
* @returns {undefined}
|
503
558
|
* @private
|
504
559
|
* @memberof Members
|
505
560
|
*/
|
506
|
-
private constructMembers(list: Array<any
|
561
|
+
private constructMembers(list: Array<any>, isUpdate: boolean) {
|
507
562
|
list.forEach((member) => {
|
563
|
+
if (isUpdate) {
|
564
|
+
// some member props are generated by SDK and need to be preserved on update,
|
565
|
+
// because they depend on relationships with other members so they need to be handled
|
566
|
+
// at the end, once all members are updated - this is done in updateRelationsBetweenMembers()
|
567
|
+
const propsToKeepOnUpdate = ['pairedWith.memberId'];
|
568
|
+
|
569
|
+
const existingMember = this.membersCollection.get(member.id);
|
570
|
+
if (existingMember) {
|
571
|
+
propsToKeepOnUpdate.forEach((prop) => {
|
572
|
+
const existingValue = get(existingMember, prop);
|
573
|
+
|
574
|
+
if (existingValue !== undefined) {
|
575
|
+
set(member, prop, existingValue);
|
576
|
+
}
|
577
|
+
});
|
578
|
+
}
|
579
|
+
}
|
508
580
|
this.membersCollection.set(member.id, member);
|
509
581
|
});
|
510
582
|
}
|
@@ -512,11 +584,11 @@ export default class Members extends StatelessWebexPlugin {
|
|
512
584
|
/**
|
513
585
|
* Internal update the participants value
|
514
586
|
* @param {Object} payload
|
515
|
-
* @returns {
|
587
|
+
* @returns {UpdatedMembers}
|
516
588
|
* @private
|
517
589
|
* @memberof Members
|
518
590
|
*/
|
519
|
-
private handleLocusInfoUpdatedParticipants(payload: any) {
|
591
|
+
private handleLocusInfoUpdatedParticipants(payload: any): UpdatedMembers {
|
520
592
|
this.hostId = payload.hostId || this.hostId;
|
521
593
|
this.selfId = payload.selfId || this.selfId;
|
522
594
|
this.recordingId = payload.recordingId;
|
@@ -681,12 +753,12 @@ export default class Members extends StatelessWebexPlugin {
|
|
681
753
|
* Removed/left members will end up in updates
|
682
754
|
* Each array contains only members
|
683
755
|
* @param {Array} participants the locus participants
|
684
|
-
* @returns {
|
756
|
+
* @returns {UpdatedMembers} {added: {Array}, updated: {Array}}
|
685
757
|
* @private
|
686
758
|
* @memberof Members
|
687
759
|
*/
|
688
|
-
private update(participants: Array<any>) {
|
689
|
-
const membersUpdate = {added: [], updated: []};
|
760
|
+
private update(participants: Array<any>): UpdatedMembers {
|
761
|
+
const membersUpdate: UpdatedMembers = {added: [], updated: []};
|
690
762
|
|
691
763
|
if (participants) {
|
692
764
|
participants.forEach((participant) => {
|