@webex/plugin-meetings 3.8.0-next.56 → 3.8.0-next.58

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.
@@ -17,513 +17,517 @@ import {
17
17
  } from '../constants';
18
18
  import ParameterError from '../common/errors/parameter';
19
19
 
20
- const SelfUtils: any = {};
21
20
  const PSTN_DEVICE_TYPE = 'PROVISIONAL';
22
21
 
23
- /**
24
- * parses the relevant values for self: muted, guest, moderator, mediaStatus, state, joinedWith, pstnDevices, creator, id
25
- * @param {Object} self
26
- * @param {String} deviceId
27
- * @returns {undefined}
28
- */
29
- SelfUtils.parse = (self: any, deviceId: string) => {
30
- if (self) {
31
- const joinedWith = self.devices.find((device) => deviceId === device.url);
32
- const pstnDevices = self.devices.filter((device) => PSTN_DEVICE_TYPE === device.deviceType);
22
+ const SelfUtils = {
23
+ /**
24
+ * parses the relevant values for self: muted, guest, moderator, mediaStatus, state, joinedWith, pstnDevices, creator, id
25
+ * @param {Object} self
26
+ * @param {String} deviceId
27
+ * @returns {undefined}
28
+ */
29
+ parse: (self: any, deviceId: string) => {
30
+ if (self) {
31
+ const joinedWith = self.devices.find((device) => deviceId === device.url);
32
+ const pstnDevices = self.devices.filter((device) => PSTN_DEVICE_TYPE === device.deviceType);
33
+
34
+ return {
35
+ remoteVideoMuted: SelfUtils.getRemoteVideoMuted(self),
36
+ remoteMuted: SelfUtils.getRemoteMuted(self),
37
+ unmuteAllowed: SelfUtils.getUnmuteAllowed(self),
38
+ localAudioUnmuteRequested: SelfUtils.getLocalAudioUnmuteRequested(self),
39
+ localAudioUnmuteRequestedTimeStamp: SelfUtils.getLocalAudioUnmuteRequestedTimeStamp(self),
40
+ localAudioUnmuteRequired: SelfUtils.getLocalAudioUnmuteRequired(self),
41
+ lastModified: SelfUtils.getLastModified(self),
42
+ modifiedBy: SelfUtils.getModifiedBy(self),
43
+ guest: self.guest,
44
+ moderator: self.moderator,
45
+ // cumulative media stats
46
+ mediaStatus: SelfUtils.getStatus(self.status),
47
+ // TODO: what should be the status if user has refreshed the page,
48
+ // check the joinedWith parameter and communicate to the user
49
+ state: self.state,
50
+ // TODO: give a proper name . With same device as login or different login`
51
+ // Some times we might have joined with both mobile and web
52
+ joinedWith,
53
+ pstnDevices,
54
+ // current media stats is for the current device who has joined
55
+ currentMediaStatus: SelfUtils.getMediaStatus(joinedWith?.mediaSessions),
56
+ creator: self.isCreator, // check if its used,
57
+ selfId: self.id,
58
+ selfIdentity: SelfUtils.getSelfIdentity(self),
59
+ selfUrl: self.url,
60
+ removed: self.removed,
61
+ roles: SelfUtils.getRoles(self),
62
+ isUserUnadmitted: self.state === _IDLE_ && joinedWith?.intent?.type === _WAIT_,
63
+ layout: SelfUtils.getLayout(self),
64
+ canNotViewTheParticipantList: SelfUtils.canNotViewTheParticipantList(self),
65
+ isSharingBlocked: SelfUtils.isSharingBlocked(self),
66
+ breakoutSessions: SelfUtils.getBreakoutSessions(self),
67
+ breakout: SelfUtils.getBreakout(self),
68
+ interpretation: SelfUtils.getInterpretation(self),
69
+ brb: SelfUtils.getBrb(self),
70
+ };
71
+ }
33
72
 
34
- return {
35
- remoteVideoMuted: SelfUtils.getRemoteVideoMuted(self),
36
- remoteMuted: SelfUtils.getRemoteMuted(self),
37
- unmuteAllowed: SelfUtils.getUnmuteAllowed(self),
38
- localAudioUnmuteRequested: SelfUtils.getLocalAudioUnmuteRequested(self),
39
- localAudioUnmuteRequestedTimeStamp: SelfUtils.getLocalAudioUnmuteRequestedTimeStamp(self),
40
- localAudioUnmuteRequired: SelfUtils.getLocalAudioUnmuteRequired(self),
41
- lastModified: SelfUtils.getLastModified(self),
42
- modifiedBy: SelfUtils.getModifiedBy(self),
43
- guest: self.guest,
44
- moderator: self.moderator,
45
- // cumulative media stats
46
- mediaStatus: SelfUtils.getStatus(self.status),
47
- // TODO: what should be the status if user has refreshed the page,
48
- // check the joinedWith parameter and communicate to the user
49
- state: self.state,
50
- // TODO: give a proper name . With same device as login or different login`
51
- // Some times we might have joined with both mobile and web
52
- joinedWith,
53
- pstnDevices,
54
- // current media stats is for the current device who has joined
55
- currentMediaStatus: SelfUtils.getMediaStatus(joinedWith?.mediaSessions),
56
- creator: self.isCreator, // check if its used,
57
- selfId: self.id,
58
- selfIdentity: SelfUtils.getSelfIdentity(self),
59
- selfUrl: self.url,
60
- removed: self.removed,
61
- roles: SelfUtils.getRoles(self),
62
- isUserUnadmitted: self.state === _IDLE_ && joinedWith?.intent?.type === _WAIT_,
63
- layout: SelfUtils.getLayout(self),
64
- canNotViewTheParticipantList: SelfUtils.canNotViewTheParticipantList(self),
65
- isSharingBlocked: SelfUtils.isSharingBlocked(self),
66
- breakoutSessions: SelfUtils.getBreakoutSessions(self),
67
- breakout: SelfUtils.getBreakout(self),
68
- interpretation: SelfUtils.getInterpretation(self),
69
- brb: SelfUtils.getBrb(self),
70
- };
71
- }
73
+ return null;
74
+ },
72
75
 
73
- return null;
74
- };
76
+ getBreakoutSessions: (self) => self?.controls?.breakout?.sessions,
77
+ getBreakout: (self) => self?.controls?.breakout,
78
+ getInterpretation: (self) => self?.controls?.interpretation,
79
+ getBrb: (self) => self?.controls?.brb,
75
80
 
76
- SelfUtils.getBreakoutSessions = (self) => self?.controls?.breakout?.sessions;
77
- SelfUtils.getBreakout = (self) => self?.controls?.breakout;
78
- SelfUtils.getInterpretation = (self) => self?.controls?.interpretation;
79
- SelfUtils.getBrb = (self) => self?.controls?.brb;
81
+ getLayout: (self) =>
82
+ Array.isArray(self?.controls?.layouts) ? self.controls.layouts[0].type : undefined,
80
83
 
81
- SelfUtils.getLayout = (self) =>
82
- Array.isArray(self?.controls?.layouts) ? self.controls.layouts[0].type : undefined;
84
+ getRoles: (self) =>
85
+ (self?.controls?.role?.roles || []).reduce((roles, role) => {
86
+ if (role.hasRole) {
87
+ roles.push(role.type);
88
+ }
83
89
 
84
- SelfUtils.getRoles = (self) =>
85
- (self?.controls?.role?.roles || []).reduce((roles, role) => {
86
- if (role.hasRole) {
87
- roles.push(role.type);
88
- }
90
+ return roles;
91
+ }, []),
89
92
 
90
- return roles;
91
- }, []);
92
-
93
- SelfUtils.canNotViewTheParticipantList = (self) => !!self?.canNotViewTheParticipantList;
94
-
95
- SelfUtils.isSharingBlocked = (self) => !!self?.isSharingBlocked;
96
-
97
- SelfUtils.getSelves = (oldSelf, newSelf, deviceId) => {
98
- const previous = oldSelf && SelfUtils.parse(oldSelf, deviceId);
99
- const current = newSelf && SelfUtils.parse(newSelf, deviceId);
100
- const updates: any = {};
101
-
102
- updates.isUserUnadmitted = SelfUtils.isUserUnadmitted(previous, current);
103
- updates.isUserAdmitted = SelfUtils.isUserAdmitted(previous, current);
104
- updates.isVideoMutedByOthersChanged = SelfUtils.videoMutedByOthersChanged(previous, current);
105
- updates.isMutedByOthersChanged = SelfUtils.mutedByOthersChanged(previous, current);
106
- updates.localAudioUnmuteRequestedByServer = SelfUtils.localAudioUnmuteRequestedByServer(
107
- previous,
108
- current
109
- );
110
- updates.localAudioUnmuteRequiredByServer = SelfUtils.localAudioUnmuteRequiredByServer(
111
- previous,
112
- current
113
- );
114
- updates.moderatorChanged = SelfUtils.moderatorChanged(previous, current);
115
- updates.isRolesChanged = SelfUtils.isRolesChanged(previous, current);
116
- updates.isMediaInactiveOrReleased = SelfUtils.wasMediaInactiveOrReleased(previous, current);
117
- updates.isUserObserving = SelfUtils.isDeviceObserving(previous, current);
118
- updates.layoutChanged = SelfUtils.layoutChanged(previous, current);
119
-
120
- updates.isMediaInactive = SelfUtils.isMediaInactive(previous, current);
121
- updates.audioStateChange =
122
- previous?.currentMediaStatus.audio !== current.currentMediaStatus.audio;
123
- updates.videoStateChange =
124
- previous?.currentMediaStatus.video !== current.currentMediaStatus.video;
125
- updates.shareStateChange =
126
- previous?.currentMediaStatus.share !== current.currentMediaStatus.share;
127
-
128
- updates.canNotViewTheParticipantListChanged =
129
- previous?.canNotViewTheParticipantList !== current.canNotViewTheParticipantList;
130
- updates.isSharingBlockedChanged = previous?.isSharingBlocked !== current.isSharingBlocked;
131
- updates.breakoutsChanged = SelfUtils.breakoutsChanged(previous, current);
132
- updates.interpretationChanged = SelfUtils.interpretationChanged(previous, current);
133
- updates.brbChanged = SelfUtils.brbChanged(previous, current);
134
-
135
- return {
136
- previous,
137
- current,
138
- updates,
139
- };
140
- };
93
+ canNotViewTheParticipantList: (self) => !!self?.canNotViewTheParticipantList,
94
+
95
+ isSharingBlocked: (self) => !!self?.isSharingBlocked,
96
+
97
+ getSelves: (oldSelf, newSelf, deviceId) => {
98
+ const previous = oldSelf && SelfUtils.parse(oldSelf, deviceId);
99
+ const current = newSelf && SelfUtils.parse(newSelf, deviceId);
100
+ const updates: any = {};
141
101
 
142
- /**
143
- * Checks if user has joined the meeting
144
- * @param {Object} self
145
- * @returns {boolean} isJoined
146
- */
147
- SelfUtils.isJoined = (self: any) => self?.state === _JOINED_;
148
-
149
- /**
150
- * Validate if the Meeting Layout Controls Layout has changed.
151
- *
152
- * @param {Self} previous - Previous self state
153
- * @param {Self} current - Current self state [per event]
154
- * @returns {boolean} - If the Meeting Layout Controls Layout has changed.
155
- */
156
- SelfUtils.layoutChanged = (previous: any, current: any) =>
157
- current?.layout && previous?.layout !== current?.layout;
158
-
159
- SelfUtils.breakoutsChanged = (previous, current) =>
160
- !isEqual(previous?.breakoutSessions, current?.breakoutSessions) && !!current?.breakout;
161
-
162
- SelfUtils.interpretationChanged = (previous, current) =>
163
- !isEqual(previous?.interpretation, current?.interpretation) && !!current?.interpretation;
164
-
165
- SelfUtils.brbChanged = (previous, current) =>
166
- !isEqual(previous?.brb, current?.brb) && current?.brb !== undefined;
167
-
168
- SelfUtils.isMediaInactive = (previous, current) => {
169
- if (
170
- previous &&
171
- previous.joinedWith &&
172
- previous.joinedWith.mediaSessions &&
173
- current &&
174
- current.joinedWith &&
175
- current.joinedWith.mediaSessions
176
- ) {
177
- const previousMediaStatus = SelfUtils.getMediaStatus(previous.joinedWith.mediaSessions);
178
- const currentMediaStatus = SelfUtils.getMediaStatus(current.joinedWith.mediaSessions);
102
+ updates.isUserUnadmitted = SelfUtils.isUserUnadmitted(previous, current);
103
+ updates.isUserAdmitted = SelfUtils.isUserAdmitted(previous, current);
104
+ updates.isVideoMutedByOthersChanged = SelfUtils.videoMutedByOthersChanged(previous, current);
105
+ updates.isMutedByOthersChanged = SelfUtils.mutedByOthersChanged(previous, current);
106
+ updates.localAudioUnmuteRequestedByServer = SelfUtils.localAudioUnmuteRequestedByServer(
107
+ previous,
108
+ current
109
+ );
110
+ updates.localAudioUnmuteRequiredByServer = SelfUtils.localAudioUnmuteRequiredByServer(
111
+ previous,
112
+ current
113
+ );
114
+ updates.moderatorChanged = SelfUtils.moderatorChanged(previous, current);
115
+ updates.isRolesChanged = SelfUtils.isRolesChanged(previous, current);
116
+ updates.isMediaInactiveOrReleased = SelfUtils.wasMediaInactiveOrReleased(previous, current);
117
+ updates.isUserObserving = SelfUtils.isDeviceObserving(previous, current);
118
+ updates.layoutChanged = SelfUtils.layoutChanged(previous, current);
119
+
120
+ updates.isMediaInactive = SelfUtils.isMediaInactive(previous, current);
121
+ updates.audioStateChange =
122
+ previous?.currentMediaStatus.audio !== current.currentMediaStatus.audio;
123
+ updates.videoStateChange =
124
+ previous?.currentMediaStatus.video !== current.currentMediaStatus.video;
125
+ updates.shareStateChange =
126
+ previous?.currentMediaStatus.share !== current.currentMediaStatus.share;
127
+
128
+ updates.canNotViewTheParticipantListChanged =
129
+ previous?.canNotViewTheParticipantList !== current.canNotViewTheParticipantList;
130
+ updates.isSharingBlockedChanged = previous?.isSharingBlocked !== current.isSharingBlocked;
131
+ updates.breakoutsChanged = SelfUtils.breakoutsChanged(previous, current);
132
+ updates.interpretationChanged = SelfUtils.interpretationChanged(previous, current);
133
+ updates.brbChanged = SelfUtils.brbChanged(previous, current);
179
134
 
135
+ return {
136
+ previous,
137
+ current,
138
+ updates,
139
+ };
140
+ },
141
+
142
+ /**
143
+ * Checks if user has joined the meeting
144
+ * @param {Object} self
145
+ * @returns {boolean} isJoined
146
+ */
147
+ isJoined: (self: any) => self?.state === _JOINED_,
148
+
149
+ /**
150
+ * Validate if the Meeting Layout Controls Layout has changed.
151
+ *
152
+ * @param {Self} previous - Previous self state
153
+ * @param {Self} current - Current self state [per event]
154
+ * @returns {boolean} - If the Meeting Layout Controls Layout has changed.
155
+ */
156
+ layoutChanged: (previous: any, current: any) =>
157
+ current?.layout && previous?.layout !== current?.layout,
158
+
159
+ breakoutsChanged: (previous, current) =>
160
+ !isEqual(previous?.breakoutSessions, current?.breakoutSessions) && !!current?.breakout,
161
+
162
+ interpretationChanged: (previous, current) =>
163
+ !isEqual(previous?.interpretation, current?.interpretation) && !!current?.interpretation,
164
+
165
+ brbChanged: (previous, current) =>
166
+ !isEqual(previous?.brb, current?.brb) && current?.brb !== undefined,
167
+
168
+ isMediaInactive: (previous, current) => {
180
169
  if (
181
- previousMediaStatus.audio &&
182
- currentMediaStatus.audio &&
183
- previousMediaStatus.audio.state !== MEDIA_STATE.inactive &&
184
- currentMediaStatus.audio.state === MEDIA_STATE.inactive &&
185
- currentMediaStatus.audio.direction !== MEDIA_STATE.inactive
170
+ previous &&
171
+ previous.joinedWith &&
172
+ previous.joinedWith.mediaSessions &&
173
+ current &&
174
+ current.joinedWith &&
175
+ current.joinedWith.mediaSessions
186
176
  ) {
187
- return true;
177
+ const previousMediaStatus = SelfUtils.getMediaStatus(previous.joinedWith.mediaSessions);
178
+ const currentMediaStatus = SelfUtils.getMediaStatus(current.joinedWith.mediaSessions);
179
+
180
+ if (
181
+ previousMediaStatus.audio &&
182
+ currentMediaStatus.audio &&
183
+ previousMediaStatus.audio.state !== MEDIA_STATE.inactive &&
184
+ currentMediaStatus.audio.state === MEDIA_STATE.inactive &&
185
+ currentMediaStatus.audio.direction !== MEDIA_STATE.inactive
186
+ ) {
187
+ return true;
188
+ }
189
+
190
+ if (
191
+ previousMediaStatus.video &&
192
+ currentMediaStatus.video &&
193
+ previousMediaStatus.video.state !== MEDIA_STATE.inactive &&
194
+ currentMediaStatus.video.state === MEDIA_STATE.inactive &&
195
+ currentMediaStatus.video.direction !== MEDIA_STATE.inactive
196
+ ) {
197
+ return true;
198
+ }
199
+
200
+ if (
201
+ previousMediaStatus.share &&
202
+ currentMediaStatus.share &&
203
+ previousMediaStatus.share.state !== MEDIA_STATE.inactive &&
204
+ currentMediaStatus.share.state === MEDIA_STATE.inactive &&
205
+ currentMediaStatus.share.direction !== MEDIA_STATE.inactive
206
+ ) {
207
+ return true;
208
+ }
209
+
210
+ return false;
188
211
  }
189
212
 
213
+ return false;
214
+ },
215
+
216
+ getLastModified: (self) => {
190
217
  if (
191
- previousMediaStatus.video &&
192
- currentMediaStatus.video &&
193
- previousMediaStatus.video.state !== MEDIA_STATE.inactive &&
194
- currentMediaStatus.video.state === MEDIA_STATE.inactive &&
195
- currentMediaStatus.video.direction !== MEDIA_STATE.inactive
218
+ !self ||
219
+ !self.controls ||
220
+ !self.controls.audio ||
221
+ !self.controls.audio.meta ||
222
+ !self.controls.audio.meta.lastModified
196
223
  ) {
197
- return true;
224
+ return null;
198
225
  }
199
226
 
227
+ return self.controls.audio.meta.lastModified;
228
+ },
229
+
230
+ getModifiedBy: (self) => {
200
231
  if (
201
- previousMediaStatus.share &&
202
- currentMediaStatus.share &&
203
- previousMediaStatus.share.state !== MEDIA_STATE.inactive &&
204
- currentMediaStatus.share.state === MEDIA_STATE.inactive &&
205
- currentMediaStatus.share.direction !== MEDIA_STATE.inactive
232
+ !self ||
233
+ !self.controls ||
234
+ !self.controls.audio ||
235
+ !self.controls.audio.meta ||
236
+ !self.controls.audio.meta.modifiedBy
206
237
  ) {
207
- return true;
238
+ return null;
208
239
  }
209
240
 
210
- return false;
211
- }
241
+ return self.controls.audio.meta.modifiedBy;
242
+ },
243
+
244
+ /**
245
+ * get the id from the self object
246
+ * @param {Object} self
247
+ * @returns {String}
248
+ */
249
+ getSelfIdentity: (self: any) => {
250
+ if (!self || !self.person) {
251
+ return null;
252
+ }
212
253
 
213
- return false;
214
- };
254
+ return self.person.id;
255
+ },
256
+
257
+ /**
258
+ * get the "remote video mute" property from the self object
259
+ * @param {Object} self
260
+ * @returns {Boolean}
261
+ */
262
+ getRemoteVideoMuted: (self: any) => {
263
+ if (!self || !self.controls || !self.controls.video) {
264
+ return null;
265
+ }
215
266
 
216
- SelfUtils.getLastModified = (self) => {
217
- if (
218
- !self ||
219
- !self.controls ||
220
- !self.controls.audio ||
221
- !self.controls.audio.meta ||
222
- !self.controls.audio.meta.lastModified
223
- ) {
224
- return null;
225
- }
267
+ return self.controls.video.muted;
268
+ },
269
+
270
+ /**
271
+ * get the "remote mute" property from the self object
272
+ * @param {Object} self
273
+ * @returns {Boolean}
274
+ */
275
+ getRemoteMuted: (self: any) => {
276
+ if (!self || !self.controls || !self.controls.audio) {
277
+ return null;
278
+ }
226
279
 
227
- return self.controls.audio.meta.lastModified;
228
- };
280
+ return self.controls.audio.muted;
281
+ },
229
282
 
230
- SelfUtils.getModifiedBy = (self) => {
231
- if (
232
- !self ||
233
- !self.controls ||
234
- !self.controls.audio ||
235
- !self.controls.audio.meta ||
236
- !self.controls.audio.meta.modifiedBy
237
- ) {
238
- return null;
239
- }
283
+ getLocalAudioUnmuteRequested: (self) => !!self?.controls?.audio?.requestedToUnmute,
240
284
 
241
- return self.controls.audio.meta.modifiedBy;
242
- };
285
+ // requestedToUnmute timestamp
286
+ getLocalAudioUnmuteRequestedTimeStamp: (self) =>
287
+ Date.parse(self?.controls?.audio?.lastModifiedRequestedToUnmute) || 0,
243
288
 
244
- /**
245
- * get the id from the self object
246
- * @param {Object} self
247
- * @returns {String}
248
- */
249
- SelfUtils.getSelfIdentity = (self: any) => {
250
- if (!self && !self.person) {
251
- return null;
252
- }
289
+ getUnmuteAllowed: (self) => {
290
+ if (!self || !self.controls || !self.controls.audio) {
291
+ return null;
292
+ }
253
293
 
254
- return self.person.id;
255
- };
294
+ return !self.controls.audio.disallowUnmute;
295
+ },
296
+
297
+ getLocalAudioUnmuteRequired: (self) => !!self?.controls?.audio?.localAudioUnmuteRequired,
298
+
299
+ getStatus: (status) => ({
300
+ audio: status.audioStatus,
301
+ video: status.videoStatus,
302
+ slides: status.videoSlidesStatus,
303
+ }),
304
+
305
+ /**
306
+ * @param {Object} oldSelf
307
+ * @param {Object} changedSelf
308
+ * @returns {Boolean}
309
+ */
310
+ wasMediaInactiveOrReleased: (oldSelf: any = {}, changedSelf: any) =>
311
+ oldSelf.joinedWith &&
312
+ oldSelf.joinedWith.state === _JOINED_ &&
313
+ changedSelf.joinedWith &&
314
+ changedSelf.joinedWith.state === _LEFT_ &&
315
+ (changedSelf.joinedWith.reason === MEETING_END_REASON.INACTIVE ||
316
+ changedSelf.joinedWith.reason === MEETING_END_REASON.MEDIA_RELEASED),
317
+
318
+ /**
319
+ * @param {Object} check
320
+ * @returns {Boolean}
321
+ */
322
+ isLocusUserUnadmitted: (check: any) =>
323
+ check && check.joinedWith?.intent?.type === _WAIT_ && check.state === _IDLE_,
324
+
325
+ /**
326
+ * @param {Object} check
327
+ * @returns {Boolean}
328
+ */
329
+ isLocusUserAdmitted: (check: any) =>
330
+ check && check.joinedWith?.intent?.type !== _WAIT_ && check.state === _JOINED_,
331
+
332
+ /**
333
+ * @param {Object} oldSelf
334
+ * @param {Object} changedSelf
335
+ * @returns {Boolean}
336
+ * @throws {Error} when self is undefined
337
+ */
338
+ isUserUnadmitted: (oldSelf: any, changedSelf: any) => {
339
+ if (!changedSelf) {
340
+ throw new ParameterError(
341
+ 'changedSelf must be defined to determine if self is unadmitted as guest.'
342
+ );
343
+ }
256
344
 
257
- /**
258
- * get the "remote video mute" property from the self object
259
- * @param {Object} self
260
- * @returns {Boolean}
261
- */
262
- SelfUtils.getRemoteVideoMuted = (self: any) => {
263
- if (!self || !self.controls || !self.controls.video) {
264
- return null;
265
- }
345
+ if (SelfUtils.isLocusUserUnadmitted(oldSelf)) {
346
+ return false;
347
+ }
266
348
 
267
- return self.controls.video.muted;
268
- };
349
+ return SelfUtils.isLocusUserUnadmitted(changedSelf);
350
+ },
269
351
 
270
- /**
271
- * get the "remote mute" property from the self object
272
- * @param {Object} self
273
- * @returns {Boolean}
274
- */
275
- SelfUtils.getRemoteMuted = (self: any) => {
276
- if (!self || !self.controls || !self.controls.audio) {
277
- return null;
278
- }
352
+ moderatorChanged: (oldSelf, changedSelf) => {
353
+ if (!oldSelf) {
354
+ return true;
355
+ }
356
+ if (!changedSelf) {
357
+ throw new ParameterError(
358
+ 'New self must be defined to determine if self transitioned moderator status.'
359
+ );
360
+ }
279
361
 
280
- return self.controls.audio.muted;
281
- };
362
+ return oldSelf.moderator !== changedSelf.moderator;
363
+ },
364
+
365
+ /**
366
+ * determine whether the roles of self is changed or not
367
+ * @param {Object} oldSelf
368
+ * @param {Object} changedSelf
369
+ * @returns {Boolean}
370
+ */
371
+ isRolesChanged: (oldSelf, changedSelf) => {
372
+ if (!changedSelf) {
373
+ // no new self means no change
374
+ return false;
375
+ }
282
376
 
283
- SelfUtils.getLocalAudioUnmuteRequested = (self) => !!self?.controls?.audio?.requestedToUnmute;
377
+ return !isEqual(oldSelf?.roles, changedSelf?.roles);
378
+ },
379
+ /**
380
+ * @param {Object} oldSelf
381
+ * @param {Object} changedSelf
382
+ * @returns {Boolean}
383
+ * @throws {Error} if changed self was undefined
384
+ */
385
+ isDeviceObserving: (oldSelf: any, changedSelf: any) =>
386
+ oldSelf &&
387
+ oldSelf.joinedWith?.intent?.type === _MOVE_MEDIA_ &&
388
+ changedSelf &&
389
+ changedSelf.joinedWith?.intent?.type === _OBSERVE_,
390
+
391
+ /**
392
+ * @param {Object} oldSelf
393
+ * @param {Object} changedSelf
394
+ * @returns {Boolean}
395
+ * @throws {Error} if changed self was undefined
396
+ */
397
+ isUserAdmitted: (oldSelf: object, changedSelf: object) => {
398
+ if (!oldSelf) {
399
+ // if there was no previous locus, it couldn't have been admitted yet
400
+ return false;
401
+ }
402
+ if (!changedSelf) {
403
+ throw new ParameterError(
404
+ 'New self must be defined to determine if self transitioned to admitted as guest.'
405
+ );
406
+ }
284
407
 
285
- // requestedToUnmute timestamp
286
- SelfUtils.getLocalAudioUnmuteRequestedTimeStamp = (self) =>
287
- Date.parse(self?.controls?.audio?.lastModifiedRequestedToUnmute) || 0;
408
+ return SelfUtils.isLocusUserUnadmitted(oldSelf) && SelfUtils.isLocusUserAdmitted(changedSelf);
409
+ },
288
410
 
289
- SelfUtils.getUnmuteAllowed = (self) => {
290
- if (!self || !self.controls || !self.controls.audio) {
291
- return null;
292
- }
411
+ videoMutedByOthersChanged: (oldSelf, changedSelf) => {
412
+ if (!changedSelf) {
413
+ throw new ParameterError(
414
+ 'New self must be defined to determine if self was video muted by others.'
415
+ );
416
+ }
293
417
 
294
- return !self.controls.audio.disallowUnmute;
295
- };
418
+ if (!oldSelf || oldSelf.remoteVideoMuted === null) {
419
+ if (changedSelf.remoteVideoMuted) {
420
+ return true; // this happens when host disables "Allow start video"
421
+ }
296
422
 
297
- SelfUtils.getLocalAudioUnmuteRequired = (self) => !!self?.controls?.audio?.localAudioUnmuteRequired;
298
-
299
- SelfUtils.getStatus = (status) => ({
300
- audio: status.audioStatus,
301
- video: status.videoStatus,
302
- slides: status.videoSlidesStatus,
303
- });
304
-
305
- /**
306
- * @param {Object} oldSelf
307
- * @param {Object} changedSelf
308
- * @returns {Boolean}
309
- */
310
- SelfUtils.wasMediaInactiveOrReleased = (oldSelf: any = {}, changedSelf: any) =>
311
- oldSelf.joinedWith &&
312
- oldSelf.joinedWith.state === _JOINED_ &&
313
- changedSelf.joinedWith &&
314
- changedSelf.joinedWith.state === _LEFT_ &&
315
- (changedSelf.joinedWith.reason === MEETING_END_REASON.INACTIVE ||
316
- changedSelf.joinedWith.reason === MEETING_END_REASON.MEDIA_RELEASED);
317
-
318
- /**
319
- * @param {Object} check
320
- * @returns {Boolean}
321
- */
322
- SelfUtils.isLocusUserUnadmitted = (check: any) =>
323
- check && check.joinedWith?.intent?.type === _WAIT_ && check.state === _IDLE_;
324
-
325
- /**
326
- * @param {Object} check
327
- * @returns {Boolean}
328
- */
329
- SelfUtils.isLocusUserAdmitted = (check: any) =>
330
- check && check.joinedWith?.intent?.type !== _WAIT_ && check.state === _JOINED_;
331
-
332
- /**
333
- * @param {Object} oldSelf
334
- * @param {Object} changedSelf
335
- * @returns {Boolean}
336
- * @throws {Error} when self is undefined
337
- */
338
- SelfUtils.isUserUnadmitted = (oldSelf: object, changedSelf: object) => {
339
- if (!changedSelf) {
340
- throw new ParameterError(
341
- 'changedSelf must be defined to determine if self is unadmitted as guest.'
342
- );
343
- }
423
+ // we don't want to be sending the 'meeting:self:videoUnmutedByOthers' notification on meeting join
424
+ return false;
425
+ }
344
426
 
345
- if (SelfUtils.isLocusUserUnadmitted(oldSelf)) {
346
- return false;
347
- }
427
+ return oldSelf.remoteVideoMuted !== changedSelf.remoteVideoMuted;
428
+ },
348
429
 
349
- return SelfUtils.isLocusUserUnadmitted(changedSelf);
350
- };
430
+ mutedByOthersChanged: (oldSelf, changedSelf) => {
431
+ if (!changedSelf) {
432
+ throw new ParameterError(
433
+ 'New self must be defined to determine if self was muted by others.'
434
+ );
435
+ }
351
436
 
352
- SelfUtils.moderatorChanged = (oldSelf, changedSelf) => {
353
- if (!oldSelf) {
354
- return true;
355
- }
356
- if (!changedSelf) {
357
- throw new ParameterError(
358
- 'New self must be defined to determine if self transitioned moderator status.'
359
- );
360
- }
437
+ if (!oldSelf || oldSelf.remoteMuted === null) {
438
+ if (changedSelf.remoteMuted) {
439
+ return true; // this happens when mute on-entry is enabled
440
+ }
361
441
 
362
- return oldSelf.moderator !== changedSelf.moderator;
363
- };
442
+ // we don't want to be sending the 'meeting:self:unmutedByOthers' notification on meeting join
443
+ return false;
444
+ }
364
445
 
365
- /**
366
- * determine whether the roles of self is changed or not
367
- * @param {Object} oldSelf
368
- * @param {Object} changedSelf
369
- * @returns {Boolean}
370
- */
371
- SelfUtils.isRolesChanged = (oldSelf, changedSelf) => {
372
- if (!changedSelf) {
373
- // no new self means no change
374
- return false;
375
- }
446
+ // there is no need to trigger user update if no one muted user
447
+ if (changedSelf.selfIdentity === changedSelf.modifiedBy) {
448
+ return false;
449
+ }
376
450
 
377
- return !isEqual(oldSelf?.roles, changedSelf?.roles);
378
- };
379
- /**
380
- * @param {Object} oldSelf
381
- * @param {Object} changedSelf
382
- * @returns {Boolean}
383
- * @throws {Error} if changed self was undefined
384
- */
385
- SelfUtils.isDeviceObserving = (oldSelf: any, changedSelf: any) =>
386
- oldSelf &&
387
- oldSelf.joinedWith?.intent?.type === _MOVE_MEDIA_ &&
388
- changedSelf &&
389
- changedSelf.joinedWith?.intent?.type === _OBSERVE_;
390
-
391
- /**
392
- * @param {Object} oldSelf
393
- * @param {Object} changedSelf
394
- * @returns {Boolean}
395
- * @throws {Error} if changed self was undefined
396
- */
397
- SelfUtils.isUserAdmitted = (oldSelf: object, changedSelf: object) => {
398
- if (!oldSelf) {
399
- // if there was no previous locus, it couldn't have been admitted yet
400
- return false;
401
- }
402
- if (!changedSelf) {
403
- throw new ParameterError(
404
- 'New self must be defined to determine if self transitioned to admitted as guest.'
451
+ return (
452
+ changedSelf.remoteMuted !== null &&
453
+ (oldSelf.remoteMuted !== changedSelf.remoteMuted ||
454
+ (changedSelf.remoteMuted && oldSelf.unmuteAllowed !== changedSelf.unmuteAllowed))
405
455
  );
406
- }
456
+ },
407
457
 
408
- return SelfUtils.isLocusUserUnadmitted(oldSelf) && SelfUtils.isLocusUserAdmitted(changedSelf);
409
- };
458
+ localAudioUnmuteRequestedByServer: (oldSelf: any = {}, changedSelf: any) => {
459
+ if (!changedSelf) {
460
+ throw new ParameterError(
461
+ 'New self must be defined to determine if self received request to unmute.'
462
+ );
463
+ }
410
464
 
411
- SelfUtils.videoMutedByOthersChanged = (oldSelf, changedSelf) => {
412
- if (!changedSelf) {
413
- throw new ParameterError(
414
- 'New self must be defined to determine if self was video muted by others.'
465
+ return (
466
+ changedSelf.localAudioUnmuteRequested &&
467
+ changedSelf.localAudioUnmuteRequestedTimeStamp > oldSelf.localAudioUnmuteRequestedTimeStamp
415
468
  );
416
- }
469
+ },
417
470
 
418
- if (!oldSelf || oldSelf.remoteVideoMuted === null) {
419
- if (changedSelf.remoteVideoMuted) {
420
- return true; // this happens when host disables "Allow start video"
471
+ localAudioUnmuteRequiredByServer: (oldSelf: any = {}, changedSelf: any) => {
472
+ if (!changedSelf) {
473
+ throw new ParameterError(
474
+ 'New self must be defined to determine if localAudioUnmuteRequired changed.'
475
+ );
421
476
  }
422
477
 
423
- // we don't want to be sending the 'meeting:self:videoUnmutedByOthers' notification on meeting join
424
- return false;
425
- }
426
-
427
- return oldSelf.remoteVideoMuted !== changedSelf.remoteVideoMuted;
428
- };
429
-
430
- SelfUtils.mutedByOthersChanged = (oldSelf, changedSelf) => {
431
- if (!changedSelf) {
432
- throw new ParameterError('New self must be defined to determine if self was muted by others.');
433
- }
434
-
435
- if (!oldSelf || oldSelf.remoteMuted === null) {
436
- if (changedSelf.remoteMuted) {
437
- return true; // this happens when mute on-entry is enabled
478
+ return (
479
+ !changedSelf.remoteMuted &&
480
+ changedSelf.localAudioUnmuteRequired &&
481
+ oldSelf.localAudioUnmuteRequired !== changedSelf.localAudioUnmuteRequired
482
+ );
483
+ },
484
+
485
+ /**
486
+ * extract the sipUrl from the partner
487
+ * @param {Object} partner
488
+ * @param {Object} info
489
+ * @returns {Object}
490
+ */
491
+
492
+ getSipUrl: (partner: any, type, sipUri) => {
493
+ // For webex meeting the sipUrl gets updated in info parser
494
+ if (partner && type === _CALL_) {
495
+ return {sipUri: partner.person.sipUrl || partner.person.id};
438
496
  }
439
497
 
440
- // we don't want to be sending the 'meeting:self:unmutedByOthers' notification on meeting join
441
- return false;
442
- }
443
-
444
- // there is no need to trigger user update if no one muted user
445
- if (changedSelf.selfIdentity === changedSelf.modifiedBy) {
446
- return false;
447
- }
498
+ return {sipUri};
499
+ },
448
500
 
449
- return (
450
- changedSelf.remoteMuted !== null &&
451
- (oldSelf.remoteMuted !== changedSelf.remoteMuted ||
452
- (changedSelf.remoteMuted && oldSelf.unmuteAllowed !== changedSelf.unmuteAllowed))
453
- );
454
- };
501
+ getMediaStatus: (mediaSessions = []): {audio: any; video: any; share: any} => {
502
+ const mediaStatus = {
503
+ audio: {},
504
+ video: {},
505
+ share: {},
506
+ };
455
507
 
456
- SelfUtils.localAudioUnmuteRequestedByServer = (oldSelf: any = {}, changedSelf: any) => {
457
- if (!changedSelf) {
458
- throw new ParameterError(
459
- 'New self must be defined to determine if self received request to unmute.'
508
+ mediaStatus.audio = mediaSessions.find(
509
+ (media) => media.mediaType === AUDIO && media.mediaContent === MediaContent.main
460
510
  );
461
- }
462
-
463
- return (
464
- changedSelf.localAudioUnmuteRequested &&
465
- changedSelf.localAudioUnmuteRequestedTimeStamp > oldSelf.localAudioUnmuteRequestedTimeStamp
466
- );
467
- };
468
-
469
- SelfUtils.localAudioUnmuteRequiredByServer = (oldSelf: any = {}, changedSelf: any) => {
470
- if (!changedSelf) {
471
- throw new ParameterError(
472
- 'New self must be defined to determine if localAudioUnmuteRequired changed.'
511
+ mediaStatus.video = mediaSessions.find(
512
+ (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.main
513
+ );
514
+ mediaStatus.share = mediaSessions.find(
515
+ (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.slides
473
516
  );
474
- }
475
-
476
- return (
477
- !changedSelf.remoteMuted &&
478
- changedSelf.localAudioUnmuteRequired &&
479
- oldSelf.localAudioUnmuteRequired !== changedSelf.localAudioUnmuteRequired
480
- );
481
- };
482
-
483
- /**
484
- * extract the sipUrl from the partner
485
- * @param {Object} partner
486
- * @param {Object} info
487
- * @returns {Object}
488
- */
489
-
490
- SelfUtils.getSipUrl = (partner: any, type, sipUri) => {
491
- // For webex meeting the sipUrl gets updated in info parser
492
- if (partner && type === _CALL_) {
493
- return {sipUri: partner.person.sipUrl || partner.person.id};
494
- }
495
-
496
- return {sipUri};
497
- };
498
517
 
499
- SelfUtils.getMediaStatus = (mediaSessions = []) => {
500
- const mediaStatus = {
501
- audio: {},
502
- video: {},
503
- share: {},
504
- };
505
-
506
- mediaStatus.audio = mediaSessions.find(
507
- (media) => media.mediaType === AUDIO && media.mediaContent === MediaContent.main
508
- );
509
- mediaStatus.video = mediaSessions.find(
510
- (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.main
511
- );
512
- mediaStatus.share = mediaSessions.find(
513
- (media) => media.mediaType === VIDEO && media.mediaContent === MediaContent.slides
514
- );
515
-
516
- return mediaStatus;
517
- };
518
+ return mediaStatus;
519
+ },
518
520
 
519
- SelfUtils.getReplacedBreakoutMoveId = (self: any, deviceId: string) => {
520
- if (self && Array.isArray(self.devices)) {
521
- const joinedDevice = self.devices.find((device) => deviceId === device.url);
522
- if (Array.isArray(joinedDevice?.replaces)) {
523
- return joinedDevice.replaces[0]?.breakoutMoveId;
521
+ getReplacedBreakoutMoveId: (self: any, deviceId: string) => {
522
+ if (self && Array.isArray(self.devices)) {
523
+ const joinedDevice = self.devices.find((device) => deviceId === device.url);
524
+ if (Array.isArray(joinedDevice?.replaces)) {
525
+ return joinedDevice.replaces[0]?.breakoutMoveId;
526
+ }
524
527
  }
525
- }
526
528
 
527
- return null;
529
+ return null;
530
+ },
528
531
  };
532
+
529
533
  export default SelfUtils;