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

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 (296) hide show
  1. package/README.md +26 -13
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/constants.js +16 -3
  5. package/dist/constants.js.map +1 -1
  6. package/dist/controls-options-manager/enums.js +1 -0
  7. package/dist/controls-options-manager/enums.js.map +1 -1
  8. package/dist/controls-options-manager/types.js.map +1 -1
  9. package/dist/controls-options-manager/util.js +26 -0
  10. package/dist/controls-options-manager/util.js.map +1 -1
  11. package/dist/hashTree/constants.js +23 -0
  12. package/dist/hashTree/constants.js.map +1 -0
  13. package/dist/hashTree/hashTree.js +516 -0
  14. package/dist/hashTree/hashTree.js.map +1 -0
  15. package/dist/hashTree/hashTreeParser.js +521 -0
  16. package/dist/hashTree/hashTreeParser.js.map +1 -0
  17. package/dist/interpretation/index.js +1 -1
  18. package/dist/interpretation/siLanguage.js +1 -1
  19. package/dist/locus-info/controlsUtils.js +11 -3
  20. package/dist/locus-info/controlsUtils.js.map +1 -1
  21. package/dist/locus-info/index.js +331 -59
  22. package/dist/locus-info/index.js.map +1 -1
  23. package/dist/media/index.js +2 -2
  24. package/dist/media/index.js.map +1 -1
  25. package/dist/meeting/brbState.js +17 -14
  26. package/dist/meeting/brbState.js.map +1 -1
  27. package/dist/meeting/in-meeting-actions.js +5 -1
  28. package/dist/meeting/in-meeting-actions.js.map +1 -1
  29. package/dist/meeting/index.js +264 -125
  30. package/dist/meeting/index.js.map +1 -1
  31. package/dist/meeting/muteState.js +2 -5
  32. package/dist/meeting/muteState.js.map +1 -1
  33. package/dist/meeting/request.js +19 -0
  34. package/dist/meeting/request.js.map +1 -1
  35. package/dist/meeting/request.type.js.map +1 -1
  36. package/dist/meeting/util.js +8 -11
  37. package/dist/meeting/util.js.map +1 -1
  38. package/dist/meetings/index.js +6 -2
  39. package/dist/meetings/index.js.map +1 -1
  40. package/dist/member/types.js.map +1 -1
  41. package/dist/members/collection.js +13 -0
  42. package/dist/members/collection.js.map +1 -1
  43. package/dist/members/index.js +44 -23
  44. package/dist/members/index.js.map +1 -1
  45. package/dist/members/request.js +3 -3
  46. package/dist/members/request.js.map +1 -1
  47. package/dist/members/util.js +18 -6
  48. package/dist/members/util.js.map +1 -1
  49. package/dist/metrics/constants.js +1 -0
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/multistream/sendSlotManager.js +32 -2
  52. package/dist/multistream/sendSlotManager.js.map +1 -1
  53. package/dist/reachability/index.js +5 -10
  54. package/dist/reachability/index.js.map +1 -1
  55. package/dist/types/constants.d.ts +12 -0
  56. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  57. package/dist/types/controls-options-manager/types.d.ts +4 -1
  58. package/dist/types/hashTree/constants.d.ts +8 -0
  59. package/dist/types/hashTree/hashTree.d.ts +128 -0
  60. package/dist/types/hashTree/hashTreeParser.d.ts +152 -0
  61. package/dist/types/locus-info/index.d.ts +93 -3
  62. package/dist/types/meeting/brbState.d.ts +0 -1
  63. package/dist/types/meeting/in-meeting-actions.d.ts +4 -0
  64. package/dist/types/meeting/index.d.ts +36 -3
  65. package/dist/types/meeting/request.d.ts +9 -1
  66. package/dist/types/meeting/request.type.d.ts +74 -0
  67. package/dist/types/meeting/util.d.ts +3 -3
  68. package/dist/types/member/types.d.ts +1 -0
  69. package/dist/types/members/collection.d.ts +6 -0
  70. package/dist/types/members/index.d.ts +15 -3
  71. package/dist/types/members/request.d.ts +1 -1
  72. package/dist/types/members/util.d.ts +5 -2
  73. package/dist/types/metrics/constants.d.ts +1 -0
  74. package/dist/types/multistream/sendSlotManager.d.ts +16 -0
  75. package/dist/types/reachability/index.d.ts +2 -2
  76. package/dist/webinar/index.js +1 -1
  77. package/package.json +26 -25
  78. package/src/constants.ts +16 -0
  79. package/src/controls-options-manager/enums.ts +1 -0
  80. package/src/controls-options-manager/types.ts +6 -1
  81. package/src/controls-options-manager/util.ts +31 -0
  82. package/src/hashTree/constants.ts +12 -0
  83. package/src/hashTree/hashTree.ts +460 -0
  84. package/src/hashTree/hashTreeParser.ts +556 -0
  85. package/src/locus-info/controlsUtils.ts +15 -0
  86. package/src/locus-info/index.ts +434 -58
  87. package/src/media/index.ts +2 -2
  88. package/src/meeting/brbState.ts +13 -9
  89. package/src/meeting/in-meeting-actions.ts +8 -0
  90. package/src/meeting/index.ts +193 -39
  91. package/src/meeting/muteState.ts +2 -6
  92. package/src/meeting/request.ts +16 -0
  93. package/src/meeting/request.type.ts +64 -0
  94. package/src/meeting/util.ts +17 -20
  95. package/src/meetings/index.ts +17 -3
  96. package/src/member/types.ts +1 -0
  97. package/src/members/collection.ts +11 -0
  98. package/src/members/index.ts +33 -7
  99. package/src/members/request.ts +2 -2
  100. package/src/members/util.ts +14 -3
  101. package/src/metrics/constants.ts +1 -0
  102. package/src/multistream/sendSlotManager.ts +34 -2
  103. package/src/reachability/index.ts +5 -13
  104. package/test/unit/spec/controls-options-manager/util.js +58 -0
  105. package/test/unit/spec/hashTree/hashTree.ts +394 -0
  106. package/test/unit/spec/hashTree/hashTreeParser.ts +156 -0
  107. package/test/unit/spec/locus-info/controlsUtils.js +52 -0
  108. package/test/unit/spec/locus-info/index.js +547 -54
  109. package/test/unit/spec/media/index.ts +107 -0
  110. package/test/unit/spec/meeting/brbState.ts +23 -4
  111. package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
  112. package/test/unit/spec/meeting/index.js +647 -46
  113. package/test/unit/spec/meeting/request.js +71 -0
  114. package/test/unit/spec/members/index.js +33 -10
  115. package/test/unit/spec/members/request.js +2 -2
  116. package/test/unit/spec/members/utils.js +27 -7
  117. package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
  118. package/test/unit/spec/reachability/index.ts +2 -6
  119. package/dist/annotation/annotation.types.d.ts +0 -42
  120. package/dist/annotation/constants.d.ts +0 -31
  121. package/dist/annotation/index.d.ts +0 -117
  122. package/dist/breakouts/breakout.d.ts +0 -8
  123. package/dist/breakouts/collection.d.ts +0 -5
  124. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  125. package/dist/breakouts/events.d.ts +0 -8
  126. package/dist/breakouts/index.d.ts +0 -5
  127. package/dist/breakouts/request.d.ts +0 -22
  128. package/dist/breakouts/utils.d.ts +0 -15
  129. package/dist/common/browser-detection.d.ts +0 -9
  130. package/dist/common/collection.d.ts +0 -48
  131. package/dist/common/config.d.ts +0 -2
  132. package/dist/common/errors/captcha-error.d.ts +0 -15
  133. package/dist/common/errors/intent-to-join.d.ts +0 -16
  134. package/dist/common/errors/join-meeting.d.ts +0 -17
  135. package/dist/common/errors/media.d.ts +0 -15
  136. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  137. package/dist/common/errors/parameter.d.ts +0 -15
  138. package/dist/common/errors/password-error.d.ts +0 -15
  139. package/dist/common/errors/permission.d.ts +0 -14
  140. package/dist/common/errors/reclaim-host-role-error.d.ts +0 -60
  141. package/dist/common/errors/reclaim-host-role-error.js +0 -158
  142. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  143. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  144. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  145. package/dist/common/errors/reconnection-in-progress.js +0 -35
  146. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  147. package/dist/common/errors/reconnection.d.ts +0 -15
  148. package/dist/common/errors/stats.d.ts +0 -15
  149. package/dist/common/errors/webex-errors.d.ts +0 -81
  150. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  151. package/dist/common/events/events-scope.d.ts +0 -17
  152. package/dist/common/events/events.d.ts +0 -12
  153. package/dist/common/events/trigger-proxy.d.ts +0 -2
  154. package/dist/common/events/util.d.ts +0 -2
  155. package/dist/common/logs/logger-config.d.ts +0 -2
  156. package/dist/common/logs/logger-proxy.d.ts +0 -2
  157. package/dist/common/logs/request.d.ts +0 -34
  158. package/dist/common/queue.d.ts +0 -32
  159. package/dist/config.d.ts +0 -73
  160. package/dist/constants.d.ts +0 -952
  161. package/dist/controls-options-manager/constants.d.ts +0 -4
  162. package/dist/controls-options-manager/enums.d.ts +0 -5
  163. package/dist/controls-options-manager/index.d.ts +0 -120
  164. package/dist/controls-options-manager/types.d.ts +0 -43
  165. package/dist/controls-options-manager/util.d.ts +0 -7
  166. package/dist/index.d.ts +0 -4
  167. package/dist/interceptors/index.d.ts +0 -2
  168. package/dist/interceptors/locusRetry.d.ts +0 -27
  169. package/dist/interpretation/collection.d.ts +0 -5
  170. package/dist/interpretation/index.d.ts +0 -5
  171. package/dist/interpretation/siLanguage.d.ts +0 -5
  172. package/dist/locus-info/controlsUtils.d.ts +0 -2
  173. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  174. package/dist/locus-info/fullState.d.ts +0 -2
  175. package/dist/locus-info/hostUtils.d.ts +0 -2
  176. package/dist/locus-info/index.d.ts +0 -269
  177. package/dist/locus-info/infoUtils.d.ts +0 -2
  178. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  179. package/dist/locus-info/parser.d.ts +0 -212
  180. package/dist/locus-info/selfUtils.d.ts +0 -2
  181. package/dist/media/index.d.ts +0 -32
  182. package/dist/media/properties.d.ts +0 -108
  183. package/dist/media/util.d.ts +0 -2
  184. package/dist/mediaQualityMetrics/config.d.ts +0 -233
  185. package/dist/mediaQualityMetrics/config.js +0 -513
  186. package/dist/mediaQualityMetrics/config.js.map +0 -1
  187. package/dist/meeting/effectsState.d.ts +0 -42
  188. package/dist/meeting/effectsState.js +0 -260
  189. package/dist/meeting/effectsState.js.map +0 -1
  190. package/dist/meeting/in-meeting-actions.d.ts +0 -79
  191. package/dist/meeting/index.d.ts +0 -1622
  192. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  193. package/dist/meeting/muteState.d.ts +0 -116
  194. package/dist/meeting/request.d.ts +0 -257
  195. package/dist/meeting/request.type.d.ts +0 -11
  196. package/dist/meeting/state.d.ts +0 -9
  197. package/dist/meeting/util.d.ts +0 -2
  198. package/dist/meeting/voicea-meeting.d.ts +0 -16
  199. package/dist/meeting-info/collection.d.ts +0 -20
  200. package/dist/meeting-info/index.d.ts +0 -57
  201. package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
  202. package/dist/meeting-info/request.d.ts +0 -22
  203. package/dist/meeting-info/util.d.ts +0 -2
  204. package/dist/meeting-info/utilv2.d.ts +0 -2
  205. package/dist/meetings/collection.d.ts +0 -23
  206. package/dist/meetings/index.d.ts +0 -296
  207. package/dist/meetings/meetings.types.d.ts +0 -4
  208. package/dist/meetings/request.d.ts +0 -27
  209. package/dist/meetings/util.d.ts +0 -18
  210. package/dist/member/index.d.ts +0 -148
  211. package/dist/member/member.types.d.ts +0 -11
  212. package/dist/member/member.types.js +0 -18
  213. package/dist/member/member.types.js.map +0 -1
  214. package/dist/member/types.d.ts +0 -32
  215. package/dist/member/util.d.ts +0 -2
  216. package/dist/members/collection.d.ts +0 -24
  217. package/dist/members/index.d.ts +0 -308
  218. package/dist/members/request.d.ts +0 -58
  219. package/dist/members/types.d.ts +0 -25
  220. package/dist/members/util.d.ts +0 -2
  221. package/dist/metrics/config.d.ts +0 -169
  222. package/dist/metrics/config.js +0 -289
  223. package/dist/metrics/config.js.map +0 -1
  224. package/dist/metrics/constants.d.ts +0 -59
  225. package/dist/metrics/index.d.ts +0 -152
  226. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  227. package/dist/multistream/receiveSlot.d.ts +0 -68
  228. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  229. package/dist/multistream/remoteMedia.d.ts +0 -72
  230. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  231. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  232. package/dist/multistream/sendSlotManager.d.ts +0 -69
  233. package/dist/networkQualityMonitor/index.d.ts +0 -70
  234. package/dist/networkQualityMonitor/index.js +0 -226
  235. package/dist/networkQualityMonitor/index.js.map +0 -1
  236. package/dist/peer-connection-manager/index.d.ts +0 -6
  237. package/dist/peer-connection-manager/index.js +0 -671
  238. package/dist/peer-connection-manager/index.js.map +0 -1
  239. package/dist/peer-connection-manager/util.d.ts +0 -6
  240. package/dist/peer-connection-manager/util.js +0 -110
  241. package/dist/peer-connection-manager/util.js.map +0 -1
  242. package/dist/personal-meeting-room/index.d.ts +0 -47
  243. package/dist/personal-meeting-room/request.d.ts +0 -14
  244. package/dist/personal-meeting-room/util.d.ts +0 -2
  245. package/dist/reachability/clusterReachability.d.ts +0 -109
  246. package/dist/reachability/index.d.ts +0 -139
  247. package/dist/reachability/request.d.ts +0 -35
  248. package/dist/reachability/util.d.ts +0 -8
  249. package/dist/reactions/constants.d.ts +0 -3
  250. package/dist/reactions/reactions.d.ts +0 -4
  251. package/dist/reactions/reactions.type.d.ts +0 -32
  252. package/dist/reconnection-manager/index.d.ts +0 -112
  253. package/dist/recording-controller/enums.d.ts +0 -7
  254. package/dist/recording-controller/index.d.ts +0 -193
  255. package/dist/recording-controller/util.d.ts +0 -13
  256. package/dist/roap/collection.d.ts +0 -10
  257. package/dist/roap/collection.js +0 -63
  258. package/dist/roap/collection.js.map +0 -1
  259. package/dist/roap/handler.d.ts +0 -47
  260. package/dist/roap/handler.js +0 -279
  261. package/dist/roap/handler.js.map +0 -1
  262. package/dist/roap/index.d.ts +0 -116
  263. package/dist/roap/request.d.ts +0 -35
  264. package/dist/roap/state.d.ts +0 -9
  265. package/dist/roap/state.js +0 -127
  266. package/dist/roap/state.js.map +0 -1
  267. package/dist/roap/turnDiscovery.d.ts +0 -81
  268. package/dist/roap/util.d.ts +0 -2
  269. package/dist/roap/util.js +0 -76
  270. package/dist/roap/util.js.map +0 -1
  271. package/dist/rtcMetrics/constants.d.ts +0 -4
  272. package/dist/rtcMetrics/constants.js +0 -11
  273. package/dist/rtcMetrics/constants.js.map +0 -1
  274. package/dist/rtcMetrics/index.d.ts +0 -61
  275. package/dist/rtcMetrics/index.js +0 -197
  276. package/dist/rtcMetrics/index.js.map +0 -1
  277. package/dist/statsAnalyzer/global.d.ts +0 -118
  278. package/dist/statsAnalyzer/global.js +0 -127
  279. package/dist/statsAnalyzer/global.js.map +0 -1
  280. package/dist/statsAnalyzer/index.d.ts +0 -193
  281. package/dist/statsAnalyzer/index.js +0 -1019
  282. package/dist/statsAnalyzer/index.js.map +0 -1
  283. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
  284. package/dist/statsAnalyzer/mqaUtil.js +0 -181
  285. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  286. package/dist/transcription/index.d.ts +0 -64
  287. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  288. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  289. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  290. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  291. package/dist/types/rtcMetrics/index.d.ts +0 -71
  292. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  293. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  294. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  295. package/dist/webinar/collection.d.ts +0 -16
  296. package/dist/webinar/index.d.ts +0 -5
@@ -66,6 +66,7 @@ import JoinWebinarError from '../common/errors/join-webinar-error';
66
66
  import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
67
67
  import NoMeetingInfoError from '../common/errors/no-meeting-info';
68
68
  import JoinForbiddenError from '../common/errors/join-forbidden-error';
69
+ import {DataSet} from '../hashTree/hashTreeParser';
69
70
 
70
71
  let mediaLogger;
71
72
 
@@ -407,6 +408,13 @@ export default class Meetings extends WebexPlugin {
407
408
  * @memberof Meetings
408
409
  */
409
410
  getCorrespondingMeetingByLocus(data) {
411
+ if (data.eventType === 'locus.state_message' && data.stateElementsMessage?.locusUrl) {
412
+ return this.meetingCollection.getByKey(
413
+ MEETING_KEY.LOCUS_URL,
414
+ data.stateElementsMessage.locusUrl
415
+ );
416
+ }
417
+
410
418
  // getting meeting by correlationId. This will happen for the new event
411
419
  // Either the locus
412
420
  // TODO : Add check for the callBack Address
@@ -445,7 +453,10 @@ export default class Meetings extends WebexPlugin {
445
453
  * @private
446
454
  * @memberof Meetings
447
455
  */
448
- private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
456
+ private handleLocusEvent(
457
+ data: {locusUrl: string; locus: any; dataSets?: DataSet[]},
458
+ useRandomDelayForInfo = false
459
+ ) {
449
460
  let meeting = this.getCorrespondingMeetingByLocus(data);
450
461
 
451
462
  // Special case when locus has got replaced, This only happend once if a replace locus exists
@@ -524,7 +535,7 @@ export default class Meetings extends WebexPlugin {
524
535
  meeting = newMeeting;
525
536
 
526
537
  // It's a new meeting so initialize the locus data
527
- meeting.locusInfo.initialSetup(data.locus);
538
+ meeting.locusInfo.initialSetup(data.locus, data.dataSets);
528
539
  this.checkHandleBreakoutLocus(data.locus);
529
540
  })
530
541
  .catch((e) => {
@@ -1824,7 +1835,10 @@ export default class Meetings extends WebexPlugin {
1824
1835
  }
1825
1836
 
1826
1837
  const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
1827
- this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
1838
+ this.handleLocusEvent({
1839
+ locus: associateBreakoutLocus,
1840
+ locusUrl: associateBreakoutLocus.url,
1841
+ });
1828
1842
  this.breakoutLocusForHandleLater.splice(existIndex, 1);
1829
1843
  }
1830
1844
 
@@ -109,4 +109,5 @@ export interface Participant {
109
109
  status: ParticipantMediaStatus;
110
110
  type: string;
111
111
  url: ParticipantUrl;
112
+ isRemoved: boolean; // JS-SDK internal field to indicate in updates when the participant is removed
112
113
  }
@@ -39,6 +39,17 @@ export default class MembersCollection {
39
39
  return this.members;
40
40
  }
41
41
 
42
+ /**
43
+ * Removes a member from the collection
44
+ * @param {String} id
45
+ * @returns {void}
46
+ */
47
+ remove(id: string) {
48
+ if (this.members[id]) {
49
+ delete this.members[id];
50
+ }
51
+ }
52
+
42
53
  /**
43
54
  * @returns {void}
44
55
  * reset members
@@ -73,7 +73,11 @@ import {ServerRoleShape} from './types';
73
73
  * @memberof Members
74
74
  */
75
75
 
76
- type UpdatedMembers = {added: Array<Member>; updated: Array<Member>};
76
+ type UpdatedMembers = {
77
+ added: Array<Member>;
78
+ updated: Array<Member>;
79
+ removedIds?: Array<string>; // removed member ids
80
+ };
77
81
  /**
78
82
  * @class Members
79
83
  */
@@ -388,7 +392,11 @@ export default class Members extends StatelessWebexPlugin {
388
392
  * @private
389
393
  * @memberof Members
390
394
  */
391
- locusParticipantsUpdate(payload: {participants: object; isReplace?: boolean}) {
395
+ locusParticipantsUpdate(payload: {
396
+ participants: object;
397
+ isReplace?: boolean;
398
+ removedParticipantIds?: Array<string>;
399
+ }) {
392
400
  if (payload) {
393
401
  if (payload.isReplace) {
394
402
  this.clearMembers();
@@ -546,10 +554,22 @@ export default class Members extends StatelessWebexPlugin {
546
554
  private handleMembersUpdate(membersUpdate: UpdatedMembers) {
547
555
  this.constructMembers(membersUpdate.updated, true);
548
556
  this.constructMembers(membersUpdate.added, false);
557
+ this.removeMembers(membersUpdate.removedIds);
549
558
 
550
559
  return this.membersCollection.getAll();
551
560
  }
552
561
 
562
+ /**
563
+ * removes members from the collection
564
+ * @param {Array<string>} removedMembers removed members ids
565
+ * @returns {void}
566
+ */
567
+ private removeMembers(removedMembers: Array<string>) {
568
+ removedMembers.forEach((memberId) => {
569
+ this.membersCollection.remove(memberId);
570
+ });
571
+ }
572
+
553
573
  /**
554
574
  * set members to the member collection from each updated/added lists as passed in
555
575
  * @param {Array} list
@@ -599,6 +619,10 @@ export default class Members extends StatelessWebexPlugin {
599
619
  }
600
620
  const memberUpdate = this.update(payload.participants);
601
621
 
622
+ // this code depends on memberIds being the same as participantIds
623
+ // if MemberUtil.extractId() ever changes, this will need to be updated
624
+ memberUpdate.removedIds = payload.removedParticipantIds || [];
625
+
602
626
  return memberUpdate;
603
627
  }
604
628
 
@@ -846,12 +870,14 @@ export default class Members extends StatelessWebexPlugin {
846
870
  }
847
871
 
848
872
  /**
849
- * Cancels an SIP call to the associated meeting
850
- * @param {String} invitee
873
+ * Cancels an SIP/phone call to the associated meeting
874
+ * @param {Object} invitee
875
+ * @param {String} invitee.memberId - The memberId of the invitee
876
+ * @param {Boolean} [invitee.isInternalNumber] - When cancel phone invitation, if the number is internal
851
877
  * @returns {Promise}
852
878
  * @memberof Members
853
879
  */
854
- cancelSIPInvite(invitee: any) {
880
+ cancelInviteByMemberId(invitee: {memberId: string; isInternalNumber?: boolean}) {
855
881
  if (!this.locusUrl) {
856
882
  return Promise.reject(
857
883
  new ParameterError('The associated locus url for this meeting object must be defined.')
@@ -862,9 +888,9 @@ export default class Members extends StatelessWebexPlugin {
862
888
  new ParameterError('The invitee must be defined with a memberId property.')
863
889
  );
864
890
  }
865
- const options = MembersUtil.cancelSIPInviteOptions(invitee, this.locusUrl);
891
+ const options = MembersUtil.cancelInviteByMemberIdOptions(invitee, this.locusUrl);
866
892
 
867
- return this.membersRequest.cancelSIPInvite(options);
893
+ return this.membersRequest.cancelInviteByMemberId(options);
868
894
  }
869
895
 
870
896
  /**
@@ -285,14 +285,14 @@ export default class MembersRequest extends StatelessWebexPlugin {
285
285
  * @throws {Error} if the options are not valid and complete, must have invitee with memberId AND locusUrl
286
286
  * @memberof MembersRequest
287
287
  */
288
- cancelSIPInvite(options: any) {
288
+ cancelInviteByMemberId(options: any) {
289
289
  if (!options?.invitee?.memberId || !options?.locusUrl) {
290
290
  throw new ParameterError(
291
291
  'invitee must be passed and the associated locus url for this meeting object must be defined.'
292
292
  );
293
293
  }
294
294
 
295
- const requestParams = MembersUtil.generateCancelSIPInviteRequestParams(options);
295
+ const requestParams = MembersUtil.generateCancelInviteByMemberIdRequestParams(options);
296
296
 
297
297
  return this.locusDeltaRequest(requestParams);
298
298
  }
@@ -1,4 +1,5 @@
1
1
  import uuid from 'uuid';
2
+ import {has} from 'lodash';
2
3
  import {
3
4
  HTTP_VERBS,
4
5
  CONTROLS,
@@ -47,6 +48,9 @@ const MembersUtil = {
47
48
  address:
48
49
  options.invitee.emailAddress || options.invitee.email || options.invitee.phoneNumber,
49
50
  ...(options.invitee.roles ? {roles: options.invitee.roles} : {}),
51
+ ...(has(options.invitee, 'isInternalNumber')
52
+ ? {isInternalNumber: options.invitee.isInternalNumber}
53
+ : {}),
50
54
  },
51
55
  ],
52
56
  alertIfActive: options.alertIfActive,
@@ -107,6 +111,10 @@ const MembersUtil = {
107
111
  }
108
112
 
109
113
  if (invitee.phoneNumber) {
114
+ if (invitee.isInternalNumber) {
115
+ return !DIALER_REGEX.INTERNAL_NUMBER.test(invitee.phoneNumber);
116
+ }
117
+
110
118
  return !DIALER_REGEX.E164_FORMAT.test(invitee.phoneNumber);
111
119
  }
112
120
 
@@ -371,17 +379,20 @@ const MembersUtil = {
371
379
  return requestParams;
372
380
  },
373
381
 
374
- cancelSIPInviteOptions: (invitee, locusUrl) => ({
382
+ cancelInviteByMemberIdOptions: (invitee, locusUrl) => ({
375
383
  invitee,
376
384
  locusUrl,
377
385
  }),
378
386
 
379
- generateCancelSIPInviteRequestParams: (options) => {
387
+ generateCancelInviteByMemberIdRequestParams: (options) => {
388
+ const {memberId, isInternalNumber} = options.invitee;
389
+ const hasIsInternalNumberProp = has(options.invitee, 'isInternalNumber');
380
390
  const body = {
381
391
  actionType: _REMOVE_,
382
392
  invitees: [
383
393
  {
384
- address: options.invitee.memberId,
394
+ address: memberId,
395
+ ...(hasIsInternalNumberProp ? {isInternalNumber} : {}),
385
396
  },
386
397
  ],
387
398
  };
@@ -72,6 +72,7 @@ const BEHAVIORAL_METRICS = {
72
72
  MEETING_INFO_POLICY_ERROR: 'js_sdk_meeting_info_policy_error',
73
73
  LOCUS_DELTA_SYNC_FAILED: 'js_sdk_locus_delta_sync_failed',
74
74
  LOCUS_DELTA_OUT_OF_ORDER: 'js_sdk_locus_delta_ooo',
75
+ LOCUS_SYNC_HANDLING_FAILED: 'js_sdk_locus_sync_handling_failed',
75
76
  PERMISSION_TOKEN_REFRESH: 'js_sdk_permission_token_refresh',
76
77
  PERMISSION_TOKEN_REFRESH_ERROR: 'js_sdk_permission_token_refresh_error',
77
78
  TURN_DISCOVERY_LATENCY: 'js_sdk_turn_discovery_latency',
@@ -7,10 +7,20 @@ import {
7
7
  StreamState,
8
8
  } from '@webex/internal-media-core';
9
9
 
10
+ /**
11
+ * This class is used to manage the sendSlots for the given media types.
12
+ */
10
13
  export default class SendSlotManager {
11
14
  private readonly slots: Map<MediaType, SendSlot> = new Map();
12
15
  private readonly LoggerProxy: any;
16
+ private readonly sourceStateOverrides: Map<MediaType, StreamState> = new Map();
13
17
 
18
+ /**
19
+ * Constructor for SendSlotManager
20
+ *
21
+ * @param {any} LoggerProxy is used to log the messages
22
+ * @constructor
23
+ */
14
24
  constructor(LoggerProxy: any) {
15
25
  this.LoggerProxy = LoggerProxy;
16
26
  }
@@ -93,7 +103,7 @@ export default class SendSlotManager {
93
103
  public setSourceStateOverride(mediaType: MediaType, state: StreamState | null) {
94
104
  if (mediaType !== MediaType.VideoMain) {
95
105
  throw new Error(
96
- `sendSlotManager cannot set source state override which media type is ${mediaType}`
106
+ `Invalid media type '${mediaType}'. Source state overrides are only applicable to ${MediaType.VideoMain}.`
97
107
  );
98
108
  }
99
109
 
@@ -103,17 +113,39 @@ export default class SendSlotManager {
103
113
  throw new Error(`Slot for ${mediaType} does not exist`);
104
114
  }
105
115
 
116
+ const currentStateOverride = this.getSourceStateOverride(mediaType);
117
+ if (currentStateOverride === state) {
118
+ return;
119
+ }
120
+
106
121
  if (state) {
107
122
  slot.setSourceStateOverride(state);
123
+ this.sourceStateOverrides.set(mediaType, state);
108
124
  } else {
109
125
  slot.clearSourceStateOverride();
126
+ this.sourceStateOverrides.delete(mediaType);
110
127
  }
111
128
 
112
129
  this.LoggerProxy.logger.info(
113
- `SendSlotsManager->setSourceStateOverride#set source state override for ${mediaType} to ${state}`
130
+ `SendSlotManager->setSourceStateOverride#set source state override for ${mediaType} to ${state}`
114
131
  );
115
132
  }
116
133
 
134
+ /**
135
+ * Gets the source state override for the given media type.
136
+ * @param {MediaType} mediaType - The type of media to get the source state override for.
137
+ * @returns {StreamState | null} - The current source state override or null if not set.
138
+ */
139
+ private getSourceStateOverride(mediaType: MediaType): StreamState | null {
140
+ if (mediaType !== MediaType.VideoMain) {
141
+ throw new Error(
142
+ `Invalid media type '${mediaType}'. Source state overrides are only applicable to ${MediaType.VideoMain}.`
143
+ );
144
+ }
145
+
146
+ return this.sourceStateOverrides.get(mediaType) || null;
147
+ }
148
+
117
149
  /**
118
150
  * This method publishes the given stream to the sendSlot for the given mediaType
119
151
  * @param {MediaType} mediaType MediaType of the sendSlot to which a stream needs to be published (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
@@ -140,22 +140,14 @@ export default class Reachability extends EventsScope {
140
140
 
141
141
  /**
142
142
  * Checks if the given subnet is reachable
143
- * @param {string} mediaServerIp - media server ip
143
+ * @param {string} selectedSubnetFirstOctet - selected subnet first octet, e.g. "10" for "10.X.X.X"
144
144
  * @returns {boolean | null} true if reachable, false if not reachable, null if mediaServerIp is not provided
145
145
  * @public
146
146
  * @memberof Reachability
147
147
  */
148
- public isSubnetReachable(mediaServerIp?: string): boolean | null {
149
- if (!mediaServerIp) {
150
- LoggerProxy.logger.error(`Reachability:index#isSubnetReachable --> mediaServerIp is null`);
151
-
152
- return null;
153
- }
154
-
155
- const subnetFirstOctet = mediaServerIp.split('.')[0];
156
-
148
+ public isSubnetReachable(selectedSubnetFirstOctet: string): boolean | null {
157
149
  LoggerProxy.logger.info(
158
- `Reachability:index#isSubnetReachable --> Looking for subnet: ${subnetFirstOctet}.X.X.X`
150
+ `Reachability:index#isSubnetReachable --> Looking for subnet: ${selectedSubnetFirstOctet}.X.X.X`
159
151
  );
160
152
 
161
153
  const matchingReachedClusters = Object.values(this.clusterReachability).reduce(
@@ -167,7 +159,7 @@ export default class Reachability extends EventsScope {
167
159
  const subnet = reachedSubnetsArray[i];
168
160
  const reachedSubnetFirstOctet = subnet.split('.')[0];
169
161
 
170
- if (subnetFirstOctet === reachedSubnetFirstOctet) {
162
+ if (selectedSubnetFirstOctet === reachedSubnetFirstOctet) {
171
163
  acc.add(cluster.name);
172
164
  }
173
165
 
@@ -186,7 +178,7 @@ export default class Reachability extends EventsScope {
186
178
  );
187
179
 
188
180
  LoggerProxy.logger.info(
189
- `Reachability:index#isSubnetReachable --> Found ${matchingReachedClusters.size} clusters that use the subnet ${subnetFirstOctet}.X.X.X`
181
+ `Reachability:index#isSubnetReachable --> Found ${matchingReachedClusters.size} clusters that use the subnet ${selectedSubnetFirstOctet}.X.X.X`
190
182
  );
191
183
 
192
184
  return matchingReachedClusters.size > 0;
@@ -473,6 +473,40 @@ describe('plugin-meetings', () => {
473
473
  assert.equal(results, expected);
474
474
  });
475
475
  });
476
+
477
+ describe('canUpdatePollingQA()', () => {
478
+ beforeEach(() => {
479
+ sinon.stub(ControlsOptionsUtil, 'hasHints').returns(true);
480
+ });
481
+
482
+ it('should call hasHints() with proper hints when `enabled` is true', () => {
483
+ ControlsOptionsUtil.canUpdatePollingQA({properties: {enabled: true}}, []);
484
+
485
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
486
+ requiredHints: [DISPLAY_HINTS.ENABLE_ATTENDEE_START_POLLING_QA],
487
+ displayHints: [],
488
+ });
489
+ });
490
+
491
+ it('should call hasHints() with proper hints when `enabled` is false', () => {
492
+ ControlsOptionsUtil.canUpdatePollingQA({properties: {enabled: false}}, []);
493
+
494
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
495
+ requiredHints: [DISPLAY_HINTS.DISABLE_ATTENDEE_START_POLLING_QA],
496
+ displayHints: [],
497
+ });
498
+ });
499
+
500
+ it('should return the resolution of hasHints()', () => {
501
+ const expected = 'example-return-value';
502
+ ControlsOptionsUtil.hasHints.returns(expected);
503
+
504
+ const results = ControlsOptionsUtil.canUpdatePollingQA({properties: {}}, []);
505
+
506
+ assert.calledOnce(ControlsOptionsUtil.hasHints);
507
+ assert.equal(results, expected);
508
+ });
509
+ });
476
510
 
477
511
  describe('canUpdate()', () => {
478
512
  const displayHints = [];
@@ -486,6 +520,7 @@ describe('plugin-meetings', () => {
486
520
  ControlsOptionsUtil.canUpdateViewTheParticipantsList = sinon.stub().returns(true);
487
521
  ControlsOptionsUtil.canUpdateAnnotation = sinon.stub().returns(true);
488
522
  ControlsOptionsUtil.canUpdateRemoteDesktopControl = sinon.stub().returns(true);
523
+ ControlsOptionsUtil.canUpdatePollingQA = sinon.stub().returns(true);
489
524
  });
490
525
 
491
526
  it('should only call canUpdateAudio() if the scope is audio', () => {
@@ -621,6 +656,28 @@ describe('plugin-meetings', () => {
621
656
  control,
622
657
  displayHints
623
658
  );
659
+ assert.callCount(ControlsOptionsUtil.canUpdatePollingQA, 0);
660
+ assert.isTrue(results);
661
+ });
662
+
663
+ it('should only call canUpdatePollingQA() if the scope is pollingQA', () => {
664
+ const control = {scope: 'pollingQA'};
665
+
666
+ const results = ControlsOptionsUtil.canUpdate(control, displayHints);
667
+
668
+ assert.callCount(ControlsOptionsUtil.canUpdateAudio, 0);
669
+ assert.callCount(ControlsOptionsUtil.canUpdateRaiseHand, 0);
670
+ assert.callCount(ControlsOptionsUtil.canUpdateReactions, 0);
671
+ assert.callCount(ControlsOptionsUtil.canUpdateShareControl, 0);
672
+ assert.callCount(ControlsOptionsUtil.canUpdateVideo, 0);
673
+ assert.callCount(ControlsOptionsUtil.canUpdateViewTheParticipantsList, 0);
674
+ assert.callCount(ControlsOptionsUtil.canUpdateAnnotation, 0);
675
+ assert.callCount(ControlsOptionsUtil.canUpdateRemoteDesktopControl, 0);
676
+ assert.calledWith(
677
+ ControlsOptionsUtil.canUpdatePollingQA,
678
+ control,
679
+ displayHints
680
+ );
624
681
  assert.isTrue(results);
625
682
  });
626
683
 
@@ -637,6 +694,7 @@ describe('plugin-meetings', () => {
637
694
  assert.callCount(ControlsOptionsUtil.canUpdateViewTheParticipantsList, 0);
638
695
  assert.callCount(ControlsOptionsUtil.canUpdateAnnotation, 0);
639
696
  assert.callCount(ControlsOptionsUtil.canUpdateRemoteDesktopControl, 0);
697
+ assert.callCount(ControlsOptionsUtil.canUpdatePollingQA, 0);
640
698
  assert.isFalse(results);
641
699
  });
642
700
  });