@webex/plugin-meetings 3.9.0-webinar5k.1 → 3.10.0

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.
Files changed (138) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +24 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/controls-options-manager/index.js +22 -5
  6. package/dist/controls-options-manager/index.js.map +1 -1
  7. package/dist/index.js +2 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/interceptors/index.js +7 -0
  10. package/dist/interceptors/index.js.map +1 -1
  11. package/dist/interceptors/locusRouteToken.js +116 -0
  12. package/dist/interceptors/locusRouteToken.js.map +1 -0
  13. package/dist/interpretation/index.js +1 -1
  14. package/dist/interpretation/siLanguage.js +1 -1
  15. package/dist/locus-info/controlsUtils.js +11 -2
  16. package/dist/locus-info/controlsUtils.js.map +1 -1
  17. package/dist/locus-info/index.js +76 -322
  18. package/dist/locus-info/index.js.map +1 -1
  19. package/dist/locus-info/parser.js +4 -1
  20. package/dist/locus-info/parser.js.map +1 -1
  21. package/dist/media/properties.js +53 -5
  22. package/dist/media/properties.js.map +1 -1
  23. package/dist/meeting/in-meeting-actions.js +14 -0
  24. package/dist/meeting/in-meeting-actions.js.map +1 -1
  25. package/dist/meeting/index.js +467 -277
  26. package/dist/meeting/index.js.map +1 -1
  27. package/dist/meeting/request.js +177 -14
  28. package/dist/meeting/request.js.map +1 -1
  29. package/dist/meeting/type.js +7 -0
  30. package/dist/meeting/type.js.map +1 -0
  31. package/dist/meeting/util.js +100 -3
  32. package/dist/meeting/util.js.map +1 -1
  33. package/dist/meeting-info/meeting-info-v2.js +29 -21
  34. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  35. package/dist/meetings/index.js +20 -16
  36. package/dist/meetings/index.js.map +1 -1
  37. package/dist/member/index.js +9 -0
  38. package/dist/member/index.js.map +1 -1
  39. package/dist/member/util.js +10 -0
  40. package/dist/member/util.js.map +1 -1
  41. package/dist/members/index.js +10 -7
  42. package/dist/members/index.js.map +1 -1
  43. package/dist/members/util.js +7 -2
  44. package/dist/members/util.js.map +1 -1
  45. package/dist/metrics/constants.js +2 -1
  46. package/dist/metrics/constants.js.map +1 -1
  47. package/dist/multistream/mediaRequestManager.js +1 -1
  48. package/dist/multistream/mediaRequestManager.js.map +1 -1
  49. package/dist/multistream/remoteMedia.js +34 -5
  50. package/dist/multistream/remoteMedia.js.map +1 -1
  51. package/dist/multistream/remoteMediaGroup.js +42 -2
  52. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  53. package/dist/reachability/index.js +3 -3
  54. package/dist/reachability/index.js.map +1 -1
  55. package/dist/types/constants.d.ts +23 -0
  56. package/dist/types/controls-options-manager/index.d.ts +9 -1
  57. package/dist/types/interceptors/index.d.ts +2 -1
  58. package/dist/types/interceptors/locusRouteToken.d.ts +38 -0
  59. package/dist/types/locus-info/index.d.ts +9 -54
  60. package/dist/types/media/properties.d.ts +21 -0
  61. package/dist/types/meeting/in-meeting-actions.d.ts +14 -0
  62. package/dist/types/meeting/index.d.ts +64 -29
  63. package/dist/types/meeting/request.d.ts +42 -0
  64. package/dist/types/meeting/type.d.ts +9 -0
  65. package/dist/types/meeting/util.d.ts +13 -0
  66. package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
  67. package/dist/types/meetings/index.d.ts +3 -1
  68. package/dist/types/member/index.d.ts +1 -0
  69. package/dist/types/member/util.d.ts +5 -0
  70. package/dist/types/members/index.d.ts +12 -11
  71. package/dist/types/members/util.d.ts +8 -4
  72. package/dist/types/metrics/constants.d.ts +1 -0
  73. package/dist/types/multistream/remoteMedia.d.ts +20 -1
  74. package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
  75. package/dist/webinar/index.js +1 -1
  76. package/package.json +25 -27
  77. package/src/constants.ts +26 -2
  78. package/src/controls-options-manager/index.ts +26 -5
  79. package/src/index.ts +2 -1
  80. package/src/interceptors/index.ts +2 -1
  81. package/src/interceptors/locusRouteToken.ts +80 -0
  82. package/src/locus-info/controlsUtils.ts +18 -0
  83. package/src/locus-info/index.ts +69 -357
  84. package/src/locus-info/parser.ts +5 -1
  85. package/src/media/properties.ts +43 -0
  86. package/src/meeting/in-meeting-actions.ts +29 -0
  87. package/src/meeting/index.ts +296 -87
  88. package/src/meeting/request.ts +141 -0
  89. package/src/meeting/type.ts +9 -0
  90. package/src/meeting/util.ts +107 -3
  91. package/src/meeting-info/meeting-info-v2.ts +24 -5
  92. package/src/meetings/index.ts +15 -22
  93. package/src/member/index.ts +10 -0
  94. package/src/member/util.ts +14 -0
  95. package/src/members/index.ts +20 -10
  96. package/src/members/util.ts +20 -3
  97. package/src/metrics/constants.ts +1 -0
  98. package/src/multistream/mediaRequestManager.ts +7 -7
  99. package/src/multistream/remoteMedia.ts +34 -4
  100. package/src/multistream/remoteMediaGroup.ts +37 -2
  101. package/src/reachability/index.ts +3 -3
  102. package/test/unit/spec/common/browser-detection.js +0 -24
  103. package/test/unit/spec/controls-options-manager/index.js +47 -0
  104. package/test/unit/spec/fixture/locus.js +1 -0
  105. package/test/unit/spec/interceptors/locusRouteToken.ts +87 -0
  106. package/test/unit/spec/locus-info/index.js +80 -361
  107. package/test/unit/spec/locus-info/parser.js +3 -2
  108. package/test/unit/spec/media/properties.ts +137 -0
  109. package/test/unit/spec/meeting/in-meeting-actions.ts +14 -0
  110. package/test/unit/spec/meeting/index.js +637 -53
  111. package/test/unit/spec/meeting/muteState.js +32 -6
  112. package/test/unit/spec/meeting/request.js +21 -0
  113. package/test/unit/spec/meeting/utils.js +171 -18
  114. package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
  115. package/test/unit/spec/meetings/index.js +12 -5
  116. package/test/unit/spec/member/util.js +24 -0
  117. package/test/unit/spec/members/collection.js +120 -0
  118. package/test/unit/spec/members/index.js +107 -2
  119. package/test/unit/spec/members/request.js +55 -0
  120. package/test/unit/spec/members/utils.js +116 -14
  121. package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
  122. package/test/unit/spec/multistream/remoteMedia.ts +66 -2
  123. package/test/unit/spec/reachability/index.ts +158 -3
  124. package/test/unit/spec/roap/turnDiscovery.ts +3 -3
  125. package/dist/hashTree/constants.js +0 -23
  126. package/dist/hashTree/constants.js.map +0 -1
  127. package/dist/hashTree/hashTree.js +0 -516
  128. package/dist/hashTree/hashTree.js.map +0 -1
  129. package/dist/hashTree/hashTreeParser.js +0 -521
  130. package/dist/hashTree/hashTreeParser.js.map +0 -1
  131. package/dist/types/hashTree/constants.d.ts +0 -8
  132. package/dist/types/hashTree/hashTree.d.ts +0 -128
  133. package/dist/types/hashTree/hashTreeParser.d.ts +0 -152
  134. package/src/hashTree/constants.ts +0 -12
  135. package/src/hashTree/hashTree.ts +0 -460
  136. package/src/hashTree/hashTreeParser.ts +0 -556
  137. package/test/unit/spec/hashTree/hashTree.ts +0 -394
  138. package/test/unit/spec/hashTree/hashTreeParser.ts +0 -156
@@ -1,4 +1,3 @@
1
- /* eslint-disable class-methods-use-this */
2
1
  import {isEqual, assignWith, cloneDeep, isEmpty, forEach} from 'lodash';
3
2
 
4
3
  import LoggerProxy from '../common/logs/logger-proxy';
@@ -31,21 +30,6 @@ import MediaSharesUtils from './mediaSharesUtils';
31
30
  import LocusDeltaParser from './parser';
32
31
  import Metrics from '../metrics';
33
32
  import BEHAVIORAL_METRICS from '../metrics/constants';
34
- import HashTreeParser, {
35
- DataSet,
36
- HashTreeMessage,
37
- HashTreeObject,
38
- HtMeta,
39
- LocusInfoUpdateType,
40
- ObjectType,
41
- } from '../hashTree/hashTreeParser';
42
-
43
- export type LocusLLMEvent = {
44
- data: {
45
- eventType: 'locus.state_message';
46
- stateElementsMessage: HashTreeMessage;
47
- };
48
- };
49
33
 
50
34
  export type LocusDTO = {
51
35
  controls?: any;
@@ -67,11 +51,7 @@ export type LocusDTO = {
67
51
  name: string;
68
52
  orgId: string;
69
53
  };
70
- htMeta?: HtMeta;
71
54
  info?: any;
72
- jsSdkMeta?: {
73
- removedParticipantIds: string[]; // list of ids of participants that are removed in the last update
74
- };
75
55
  links?: any;
76
56
  mediaShares?: any[];
77
57
  meetings?: any[];
@@ -93,26 +73,9 @@ export type LocusDTO = {
93
73
  };
94
74
 
95
75
  export type LocusApiResponseBody = {
96
- dataSets?: DataSet[];
97
76
  locus: LocusDTO; // this LocusDTO here might not be the full one (for example it won't have all the participants, but it should have self)
98
77
  };
99
78
 
100
- const LocusDtoTopLevelKeys = [
101
- 'controls',
102
- 'fullState',
103
- 'host',
104
- 'info',
105
- 'links',
106
- 'mediaShares',
107
- 'meetings',
108
- 'participants',
109
- 'replaces',
110
- 'self',
111
- 'sequence',
112
- 'syncUrl',
113
- 'url',
114
- ];
115
-
116
79
  /**
117
80
  * @description LocusInfo extends ChildEmitter to convert locusInfo info a private emitter to parent object
118
81
  * @export
@@ -130,7 +93,6 @@ export default class LocusInfo extends EventsScope {
130
93
  aclUrl: any;
131
94
  baseSequence: any;
132
95
  created: any;
133
- deltaParticipants: any;
134
96
  identities: any;
135
97
  membership: any;
136
98
  participants: any;
@@ -152,9 +114,6 @@ export default class LocusInfo extends EventsScope {
152
114
  resources: any;
153
115
  mainSessionLocusCache: any;
154
116
  self: any;
155
- hashTreeParser?: HashTreeParser;
156
- hashTreeObjectId2ParticipantId: Map<number, string>; // mapping of hash tree object ids to participant ids
157
-
158
117
  /**
159
118
  * Constructor
160
119
  * @param {function} updateMeeting callback to update the meeting object from an object
@@ -173,26 +132,32 @@ export default class LocusInfo extends EventsScope {
173
132
  this.meetingId = meetingId;
174
133
  this.updateMeeting = updateMeeting;
175
134
  this.locusParser = new LocusDeltaParser();
176
- this.hashTreeObjectId2ParticipantId = new Map();
177
135
  }
178
136
 
179
137
  /**
180
138
  * Does a Locus sync. It tries to get the latest delta DTO or if it can't, it falls back to getting the full Locus DTO.
181
139
  *
182
140
  * @param {Meeting} meeting
141
+ * @param {boolean} isLocusUrlChanged
142
+ * @param {Locus} locus
183
143
  * @returns {undefined}
184
144
  */
185
- private doLocusSync(meeting: any) {
186
- let isDelta;
145
+ private doLocusSync(meeting: any, isLocusUrlChanged: boolean, locus: any) {
187
146
  let url;
147
+ let isDelta = false;
188
148
  let meetingDestroyed = false;
189
149
 
190
- if (this.locusParser.workingCopy.syncUrl) {
150
+ if (isLocusUrlChanged) {
151
+ // for the locus url changed case from breakout to main session, we should always do a full sync, in this case, the url from locus is always on main session,
152
+ // so use the main session locus url to get the full locus(full participants list in the response).
153
+ // for the locus url changed case from main session to breakout, we don't need to care about it here,
154
+ // because it is a USE_INCOMING case, it will not be executed here.
155
+ url = locus.url;
156
+ } else if (this.locusParser.workingCopy?.syncUrl) {
191
157
  url = this.locusParser.workingCopy.syncUrl;
192
158
  isDelta = true;
193
159
  } else {
194
160
  url = meeting.locusUrl;
195
- isDelta = false;
196
161
  }
197
162
 
198
163
  LoggerProxy.logger.info(
@@ -261,7 +226,7 @@ export default class LocusInfo extends EventsScope {
261
226
 
262
227
  if (isDelta) {
263
228
  if (res.body.baseSequence) {
264
- meeting.locusInfo.handleLocusDelta(res.body, meeting); // todo: check if this is safe, is isDelta=true always only for non-hash tree locus
229
+ meeting.locusInfo.handleLocusDelta(res.body, meeting);
265
230
 
266
231
  return;
267
232
  }
@@ -304,6 +269,7 @@ export default class LocusInfo extends EventsScope {
304
269
  */
305
270
  applyLocusDeltaData(action: string, locus: any, meeting: any) {
306
271
  const {DESYNC, USE_CURRENT, USE_INCOMING, WAIT, LOCUS_URL_CHANGED} = LocusDeltaParser.loci;
272
+ const isLocusUrlChanged = action === LOCUS_URL_CHANGED;
307
273
 
308
274
  switch (action) {
309
275
  case USE_INCOMING:
@@ -315,7 +281,7 @@ export default class LocusInfo extends EventsScope {
315
281
  break;
316
282
  case DESYNC:
317
283
  case LOCUS_URL_CHANGED:
318
- this.doLocusSync(meeting);
284
+ this.doLocusSync(meeting, isLocusUrlChanged, locus);
319
285
  break;
320
286
  default:
321
287
  LoggerProxy.logger.info(
@@ -370,17 +336,6 @@ export default class LocusInfo extends EventsScope {
370
336
  * @property {Object} person - Contains person data.
371
337
  */
372
338
 
373
- /**
374
- * Stored participant changes between the last event and the current event.
375
- * All previously stored events are overwritten between events.
376
- *
377
- * @instance
378
- * @type {Array<DeltaParticipant>}
379
- * @private
380
- * @member LocusInfo
381
- */
382
- this.deltaParticipants = [];
383
-
384
339
  this.updateLocusCache(locus);
385
340
  // above section only updates the locusInfo object
386
341
  // The below section makes sure it updates the locusInfo as well as updates the meeting object
@@ -388,7 +343,7 @@ export default class LocusInfo extends EventsScope {
388
343
  // For 1:1 space meeting the conversation Url does not exist in locus.conversation
389
344
  this.updateConversationUrl(locus.conversationUrl, locus.info);
390
345
  this.updateControls(locus.controls, locus.self);
391
- this.updateLocusUrl(locus.url);
346
+ this.updateLocusUrl(locus.url, ControlsUtils.isMainSessionDTO(locus));
392
347
  this.updateFullState(locus.fullState);
393
348
  this.updateMeetingInfo(locus.info);
394
349
  this.updateEmbeddedApps(locus.embeddedApps);
@@ -402,188 +357,25 @@ export default class LocusInfo extends EventsScope {
402
357
 
403
358
  /**
404
359
  * @param {Object} locus
405
- * @param {DataSet[]} [dataSets=[]] - Array of data sets
406
360
  * @returns {undefined}
407
361
  * @memberof LocusInfo
408
362
  */
409
- initialSetup(locus: object, dataSets: DataSet[] = []) {
363
+ initialSetup(locus: object) {
410
364
  this.updateLocusCache(locus);
411
- this.onFullLocus(locus, undefined, dataSets);
365
+ this.onFullLocus(locus);
412
366
 
413
367
  // Change it to true after it receives it first locus object
414
368
  this.emitChange = true;
415
369
  }
416
370
 
417
371
  /**
418
- *
419
- * @param {HashTreeObject} object data set object
420
- * @param {any} locus
421
- * @returns {void}
422
- */
423
- updateHashTreeObjectInLocus(object: HashTreeObject, locus: LocusDTO): LocusDTO {
424
- const type = object.htMeta.elementId.type.toLowerCase();
425
-
426
- switch (type) {
427
- case ObjectType.locus: {
428
- if (!object.data) {
429
- LoggerProxy.logger.warn(
430
- `Locus-info:index#updateHashTreeObjectInLocus --> received LOCUS object without data, this is not supported!`
431
- );
432
-
433
- return locus;
434
- }
435
- // replace the main locus
436
-
437
- // The Locus object from MAIN dataset has empty participants, so removing them to avoid it overriding the ones in our current locus object
438
- // Also, it doesn't have "self". That's OK as it won't override existing locus.self and also existing SDK code can handle that missing self in Locus updates
439
- const locusObjectFromData = object.data;
440
- delete locusObjectFromData.participants;
441
-
442
- locus = {...locus, ...locusObjectFromData};
443
- locus.htMeta = object.htMeta;
444
- break;
445
- }
446
- case ObjectType.participant:
447
- LoggerProxy.logger.info(
448
- `Locus-info:index#updateHashTreeObjectInLocus --> participant id=${
449
- object.htMeta.elementId.id
450
- } ${object.data ? 'updated' : 'removed'}`
451
- );
452
- console.log(
453
- 'marcin: hashTreeObjectId2ParticipantId=',
454
- cloneDeep(this.hashTreeObjectId2ParticipantId)
455
- );
456
- if (object.data) {
457
- if (!locus.participants) {
458
- locus.participants = [];
459
- }
460
- const participantObject = object.data;
461
- participantObject.htMeta = object.htMeta;
462
- locus.participants.push(participantObject);
463
- this.hashTreeObjectId2ParticipantId.set(object.htMeta.elementId.id, participantObject.id);
464
- } else {
465
- const participantId = this.hashTreeObjectId2ParticipantId.get(object.htMeta.elementId.id);
466
-
467
- if (!locus.jsSdkMeta) {
468
- locus.jsSdkMeta = {removedParticipantIds: []};
469
- }
470
- locus.jsSdkMeta.removedParticipantIds.push(participantId);
471
- this.hashTreeObjectId2ParticipantId.delete(object.htMeta.elementId.id);
472
- }
473
- break;
474
- case ObjectType.self:
475
- if (!object.data) {
476
- LoggerProxy.logger.warn(
477
- `Locus-info:index#updateHashTreeObjectInLocus --> received SELF object without data, this is not supported!`
478
- );
479
-
480
- return locus;
481
- }
482
- locus.self = object.data;
483
- break;
484
- }
485
-
486
- return locus;
487
- }
488
-
489
- /**
490
- * Handles HTTP response from Locus API call when hash tree update.
372
+ * Handles HTTP response from Locus API call.
491
373
  * @param {Meeting} meeting meeting object
492
- * @param {LocusApiResponseBody} responseBody body of the http reponse from Locus API call
374
+ * @param {LocusApiResponseBody} responseBody body of the http response from Locus API call
493
375
  * @returns {void}
494
376
  */
495
377
  handleLocusAPIResponse(meeting, responseBody: LocusApiResponseBody): void {
496
- console.log('marcin: locus response from API call:', responseBody);
497
- if (responseBody.dataSets) {
498
- if (!this.hashTreeParser) {
499
- LoggerProxy.logger.warn(
500
- `Locus-info:index#handleLocusAPIResponse --> received response with hash tree info from Locus API, but we don't have the hashTreeParser created`
501
- );
502
-
503
- return;
504
- }
505
- // Locus is using the new hash tree mechanism
506
- // so update our data in the hash tree parser
507
- this.hashTreeParser.handleLocusUpdate(responseBody);
508
-
509
- // but the Locus object we receive in this case looks same like classic delta, so we can use existing delta method to process it
510
- this.onDeltaLocus(responseBody.locus);
511
- } else {
512
- // classic Locus delta
513
- this.handleLocusDelta(responseBody.locus, meeting);
514
- }
515
- }
516
-
517
- /**
518
- * Handles a hash tree message received from Locus.
519
- *
520
- * @param {Meeting} meeting - The meeting object
521
- * @param {HashTreeMessage} message incoming hash tree message
522
- * @returns {void}
523
- */
524
- private handleHashTreeMessage(meeting: any, message: HashTreeMessage) {
525
- if (!this.hashTreeParser) {
526
- LoggerProxy.logger.warn(
527
- `Locus-info:index#handleHashTreeMessage --> received hash tree message, but we don't have the hashTreeParser`
528
- );
529
-
530
- return;
531
- }
532
- if (message.locusStateElements === undefined) {
533
- // todo: need to see in practice how exactly the heartbeat messages look like
534
- this.hashTreeParser.handleRootHashHeartBeatMessage(message);
535
- } else {
536
- this.hashTreeParser.handleMessage(message);
537
- }
538
- }
539
-
540
- /**
541
- * Updates our locus info based on the data parsed by the hash tree parser.
542
- *
543
- * @param {LocusInfoUpdateType} updateType - The type of update received.
544
- * @param {Object} [data] - Additional data for the update, if applicable.
545
- * @returns {void}
546
- */
547
- private updateFromHashTree(
548
- updateType: LocusInfoUpdateType,
549
- data?: {updatedObjects: HashTreeObject[]}
550
- ) {
551
- switch (updateType) {
552
- case LocusInfoUpdateType.OBJECTS_UPDATED: {
553
- // initialize the main locus with what we currently have
554
- // but with empty participants array
555
- let locus: LocusDTO = {
556
- participants: [],
557
- jsSdkMeta: {removedParticipantIds: []},
558
- };
559
-
560
- LocusDtoTopLevelKeys.forEach((key) => {
561
- if (key === 'participants') {
562
- locus[key] = [];
563
- } else {
564
- locus[key] = cloneDeep(this[key]);
565
- }
566
- });
567
-
568
- // apply the updates from the hash tree onto the locus
569
- data.updatedObjects.forEach((object) => {
570
- locus = this.updateHashTreeObjectInLocus(object, locus);
571
- });
572
-
573
- // update our locus info with the new locus
574
- this.onDeltaLocus(locus);
575
-
576
- break;
577
- }
578
-
579
- case LocusInfoUpdateType.MEETING_ENDED: {
580
- LoggerProxy.logger.info(
581
- `Locus-info:index#updateFromHashTree --> received signal that meeting ended, destroying meeting ${this.meetingId}`
582
- );
583
- const meeting = this.webex.meetings.meetingCollection.get(this.meetingId);
584
- this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
585
- }
586
- }
378
+ this.handleLocusDelta(responseBody.locus, meeting);
587
379
  }
588
380
 
589
381
  /**
@@ -593,43 +385,38 @@ export default class LocusInfo extends EventsScope {
593
385
  * @memberof LocusInfo
594
386
  */
595
387
  parse(meeting: any, data: any) {
596
- if (data.eventType === 'locus.state_message') {
597
- // this is the new hashmap Locus message format (only applicable to webinars for now)
598
- this.handleHashTreeMessage(meeting, data.stateElementsMessage as HashTreeMessage);
599
- } else {
600
- // eslint-disable-next-line @typescript-eslint/no-shadow
601
- const {eventType} = data;
602
- const locus = this.getTheLocusToUpdate(data.locus);
603
- LoggerProxy.logger.info(`Locus-info:index#parse --> received locus data: ${eventType}`);
604
-
605
- locus.jsSdkMeta = {removedParticipantIds: []};
606
-
607
- switch (eventType) {
608
- case LOCUSEVENT.PARTICIPANT_JOIN:
609
- case LOCUSEVENT.PARTICIPANT_LEFT:
610
- case LOCUSEVENT.CONTROLS_UPDATED:
611
- case LOCUSEVENT.PARTICIPANT_AUDIO_MUTED:
612
- case LOCUSEVENT.PARTICIPANT_AUDIO_UNMUTED:
613
- case LOCUSEVENT.PARTICIPANT_VIDEO_MUTED:
614
- case LOCUSEVENT.PARTICIPANT_VIDEO_UNMUTED:
615
- case LOCUSEVENT.SELF_CHANGED:
616
- case LOCUSEVENT.PARTICIPANT_UPDATED:
617
- case LOCUSEVENT.PARTICIPANT_CONTROLS_UPDATED:
618
- case LOCUSEVENT.PARTICIPANT_ROLES_UPDATED:
619
- case LOCUSEVENT.PARTICIPANT_DECLINED:
620
- case LOCUSEVENT.FLOOR_GRANTED:
621
- case LOCUSEVENT.FLOOR_RELEASED:
622
- this.onFullLocus(locus, eventType);
623
- break;
624
- case LOCUSEVENT.DIFFERENCE:
625
- this.handleLocusDelta(locus, meeting);
626
- break;
627
-
628
- default:
629
- // Why will there be a event with no eventType ????
630
- // we may not need this, we can get full locus
631
- this.handleLocusDelta(locus, meeting);
632
- }
388
+ // eslint-disable-next-line @typescript-eslint/no-shadow
389
+ const {eventType} = data;
390
+ const locus = this.getTheLocusToUpdate(data.locus);
391
+ LoggerProxy.logger.info(`Locus-info:index#parse --> received locus data: ${eventType}`);
392
+
393
+ locus.jsSdkMeta = {removedParticipantIds: []};
394
+
395
+ switch (eventType) {
396
+ case LOCUSEVENT.PARTICIPANT_JOIN:
397
+ case LOCUSEVENT.PARTICIPANT_LEFT:
398
+ case LOCUSEVENT.CONTROLS_UPDATED:
399
+ case LOCUSEVENT.PARTICIPANT_AUDIO_MUTED:
400
+ case LOCUSEVENT.PARTICIPANT_AUDIO_UNMUTED:
401
+ case LOCUSEVENT.PARTICIPANT_VIDEO_MUTED:
402
+ case LOCUSEVENT.PARTICIPANT_VIDEO_UNMUTED:
403
+ case LOCUSEVENT.SELF_CHANGED:
404
+ case LOCUSEVENT.PARTICIPANT_UPDATED:
405
+ case LOCUSEVENT.PARTICIPANT_CONTROLS_UPDATED:
406
+ case LOCUSEVENT.PARTICIPANT_ROLES_UPDATED:
407
+ case LOCUSEVENT.PARTICIPANT_DECLINED:
408
+ case LOCUSEVENT.FLOOR_GRANTED:
409
+ case LOCUSEVENT.FLOOR_RELEASED:
410
+ this.onFullLocus(locus, eventType);
411
+ break;
412
+ case LOCUSEVENT.DIFFERENCE:
413
+ this.handleLocusDelta(locus, meeting);
414
+ break;
415
+
416
+ default:
417
+ // Why will there be a event with no eventType ????
418
+ // we may not need this, we can get full locus
419
+ this.handleLocusDelta(locus, meeting);
633
420
  }
634
421
  }
635
422
 
@@ -648,46 +435,17 @@ export default class LocusInfo extends EventsScope {
648
435
  * updates the locus with full locus object
649
436
  * @param {object} locus locus object
650
437
  * @param {string} eventType particulat locus event
651
- * @param {DataSet[]} dataSets
652
438
  * @returns {object} null
653
439
  * @memberof LocusInfo
654
440
  */
655
- onFullLocus(locus: any, eventType?: string, dataSets?: Array<DataSet>) {
441
+ onFullLocus(locus: any, eventType?: string) {
656
442
  if (!locus) {
657
443
  LoggerProxy.logger.error(
658
444
  'Locus-info:index#onFullLocus --> object passed as argument was invalid, continuing.'
659
445
  );
660
446
  }
661
447
 
662
- if (dataSets) {
663
- // this is the new hashmap Locus DTO format (only applicable to webinars for now)
664
- if (!this.hashTreeParser) {
665
- LoggerProxy.logger.info(`Locus-info:index#onFullLocus --> creating hash tree parser`);
666
- LoggerProxy.logger.info(
667
- 'Locus-info:index#onFullLocus --> dataSets:',
668
- dataSets,
669
- ' and locus:',
670
- locus
671
- );
672
- this.hashTreeParser = new HashTreeParser({
673
- initialLocus: {locus, dataSets},
674
- webexRequest: this.webex.request.bind(this.webex),
675
- locusInfoUpdateCallback: this.updateFromHashTree.bind(this),
676
- debugId: `HT-${this.meetingId.substring(0, 4)}`,
677
- });
678
- } else {
679
- // in this case the Locus we're getting is not necessarily the full one
680
- // so treat it like if we just got it in a message
681
- console.log('marcin: !!!!!!!! full DTO - this is not fully implemented/tested yet');
682
-
683
- LoggerProxy.logger.warn(
684
- 'Locus-info:index#onFullLocus --> full DTO - this is not fully implemented/tested yet!!!!!!!!'
685
- );
686
- this.handleLocusAPIResponse(undefined, {dataSets, locus});
687
-
688
- return;
689
- }
690
- } else if (!this.locusParser.isNewFullLocus(locus)) {
448
+ if (!this.locusParser.isNewFullLocus(locus)) {
691
449
  LoggerProxy.logger.info(
692
450
  `Locus-info:index#onFullLocus --> ignoring old full locus DTO, eventType=${eventType}`
693
451
  );
@@ -695,12 +453,8 @@ export default class LocusInfo extends EventsScope {
695
453
  return;
696
454
  }
697
455
 
698
- this.updateParticipantDeltas(locus.participants);
699
456
  this.scheduledMeeting = locus.meeting || null;
700
457
  this.participants = locus.participants;
701
- this.participants?.forEach((participant) => {
702
- this.hashTreeObjectId2ParticipantId.set(participant.htMeta.elementId.id, participant.id);
703
- });
704
458
  const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
705
459
  this.updateLocusInfo(locus);
706
460
  this.updateParticipants(
@@ -795,7 +549,7 @@ export default class LocusInfo extends EventsScope {
795
549
  this.updateCreated(locus.created);
796
550
  this.updateFullState(locus.fullState);
797
551
  this.updateHostInfo(locus.host);
798
- this.updateLocusUrl(locus.url);
552
+ this.updateLocusUrl(locus.url, ControlsUtils.isMainSessionDTO(locus));
799
553
  this.updateMeetingInfo(locus.info, locus.self);
800
554
  this.updateMediaShares(locus.mediaShares);
801
555
  this.updateParticipantsUrl(locus.participantsUrl);
@@ -1061,55 +815,6 @@ export default class LocusInfo extends EventsScope {
1061
815
  }
1062
816
  }
1063
817
 
1064
- /**
1065
- * Update the deltaParticipants property of this object based on a list of
1066
- * provided participants.
1067
- *
1068
- * @param {Array} [participants] - The participants to update against.
1069
- * @returns {void}
1070
- */
1071
- updateParticipantDeltas(participants: Array<any> = []) {
1072
- // Used to find a participant within a participants collection.
1073
- const findParticipant = (participant, collection) =>
1074
- collection.find((item) => item.person.id === participant.person.id);
1075
-
1076
- // Generates an object that indicates which state properties have changed.
1077
- const generateDelta = (prevState: any = {}, newState: any = {}) => {
1078
- // Setup deltas.
1079
- const deltas = {
1080
- audioStatus: prevState.audioStatus !== newState.audioStatus,
1081
- videoSlidesStatus: prevState.videoSlidesStatus !== newState.videoSlidesStatus,
1082
- videoStatus: prevState.videoStatus !== newState.videoStatus,
1083
- };
1084
-
1085
- // Clean the object
1086
- Object.keys(deltas).forEach((key) => {
1087
- if (deltas[key] !== true) {
1088
- delete deltas[key];
1089
- }
1090
- });
1091
-
1092
- return deltas;
1093
- };
1094
-
1095
- this.deltaParticipants = participants.reduce((collection, participant) => {
1096
- const existingParticipant = findParticipant(participant, this.participants || []) || {};
1097
-
1098
- const delta = generateDelta(existingParticipant.status, participant.status);
1099
-
1100
- const changed = Object.keys(delta).length > 0;
1101
-
1102
- if (changed) {
1103
- collection.push({
1104
- person: participant.person,
1105
- delta,
1106
- });
1107
- }
1108
-
1109
- return collection;
1110
- }, []);
1111
- }
1112
-
1113
818
  /**
1114
819
  * update meeting's members
1115
820
  * @param {Object} participants new participants object
@@ -1118,7 +823,7 @@ export default class LocusInfo extends EventsScope {
1118
823
  * @returns {Array} updatedParticipants
1119
824
  * @memberof LocusInfo
1120
825
  */
1121
- updateParticipants(participants: object, removedParticipantIds: string[], isReplace?: boolean) {
826
+ updateParticipants(participants: object, removedParticipantIds?: string[], isReplace?: boolean) {
1122
827
  this.emitScoped(
1123
828
  {
1124
829
  file: 'locus-info',
@@ -1190,6 +895,7 @@ export default class LocusInfo extends EventsScope {
1190
895
  hasAnnotationControlChanged,
1191
896
  hasRemoteDesktopControlChanged,
1192
897
  hasPollingQAControlChanged,
898
+ hasAutoEndMeetingChanged,
1193
899
  },
1194
900
  current,
1195
901
  } = ControlsUtils.getControls(this.controls, controls);
@@ -1464,6 +1170,14 @@ export default class LocusInfo extends EventsScope {
1464
1170
  );
1465
1171
  }
1466
1172
 
1173
+ if (hasAutoEndMeetingChanged) {
1174
+ this.emitScoped(
1175
+ {file: 'locus-info', function: 'updateControls'},
1176
+ LOCUSINFO.EVENTS.CONTROLS_AUTO_END_MEETING_WARNING_CHANGED,
1177
+ {state: current.autoEndMeetingWarning}
1178
+ );
1179
+ }
1180
+
1467
1181
  this.controls = controls;
1468
1182
  }
1469
1183
  }
@@ -1624,10 +1338,7 @@ export default class LocusInfo extends EventsScope {
1624
1338
  */
1625
1339
  updateMeetingInfo(info: object, self?: object) {
1626
1340
  const roles = self ? SelfUtils.getRoles(self) : this.parsedLocus.self?.roles || [];
1627
- if (
1628
- (info && !isEqual(this.info, info)) ||
1629
- (roles.length && !isEqual(this.roles, roles) && info)
1630
- ) {
1341
+ if ((info && !isEqual(this.info, info)) || (!isEqual(this.roles, roles) && info)) {
1631
1342
  const isJoined = SelfUtils.isJoined(self || this.parsedLocus.self);
1632
1343
  const parsedInfo = InfoUtils.getInfos(this.parsedLocus.info, info, roles, isJoined);
1633
1344
 
@@ -2030,10 +1741,11 @@ export default class LocusInfo extends EventsScope {
2030
1741
  /**
2031
1742
  * handles when the locus.url is updated
2032
1743
  * @param {String} url
1744
+ * @param {Boolean} isMainLocus
2033
1745
  * @returns {undefined}
2034
1746
  * emits internal event locus_info_update_url
2035
1747
  */
2036
- updateLocusUrl(url: string) {
1748
+ updateLocusUrl(url: string, isMainLocus = true) {
2037
1749
  if (url && this.url !== url) {
2038
1750
  this.url = url;
2039
1751
  this.updateMeeting({locusUrl: url});
@@ -2043,7 +1755,7 @@ export default class LocusInfo extends EventsScope {
2043
1755
  function: 'updateLocusUrl',
2044
1756
  },
2045
1757
  EVENTS.LOCUS_INFO_UPDATE_URL,
2046
- url
1758
+ {url, isMainLocus}
2047
1759
  );
2048
1760
  }
2049
1761
  }
@@ -728,13 +728,17 @@ export default class Parser {
728
728
  break;
729
729
 
730
730
  case USE_INCOMING:
731
- case LOCUS_URL_CHANGED:
732
731
  // update working copy for future comparisons.
733
732
  // Note: The working copy of parser gets updated in .onFullLocus()
734
733
  // and here when USE_INCOMING or LOCUS_URL_CHANGED locus.
735
734
  this.workingCopy = newLoci;
736
735
  break;
737
736
 
737
+ case LOCUS_URL_CHANGED:
738
+ // clear the working copy completely, do a full locus sync
739
+ this.workingCopy = null;
740
+ break;
741
+
738
742
  case WAIT:
739
743
  // we've taken newLoci from the front of the queue, so put it back there as we have to wait
740
744
  // for the one that should be in front of it, before we can process it