@webex/plugin-meetings 3.0.0-beta.13 → 3.0.0-beta.131

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 (519) hide show
  1. package/README.md +45 -1
  2. package/UPGRADING.md +9 -9
  3. package/browsers.js +19 -24
  4. package/dist/annotation/annotation.types.js +7 -0
  5. package/dist/annotation/annotation.types.js.map +1 -0
  6. package/dist/annotation/constants.js +48 -0
  7. package/dist/annotation/constants.js.map +1 -0
  8. package/dist/annotation/index.js +355 -0
  9. package/dist/annotation/index.js.map +1 -0
  10. package/dist/breakouts/breakout.js +193 -0
  11. package/dist/breakouts/breakout.js.map +1 -0
  12. package/dist/breakouts/collection.js +23 -0
  13. package/dist/breakouts/collection.js.map +1 -0
  14. package/dist/breakouts/edit-lock-error.js +52 -0
  15. package/dist/breakouts/edit-lock-error.js.map +1 -0
  16. package/dist/breakouts/events.js +43 -0
  17. package/dist/breakouts/events.js.map +1 -0
  18. package/dist/breakouts/index.js +994 -0
  19. package/dist/breakouts/index.js.map +1 -0
  20. package/dist/breakouts/request.js +78 -0
  21. package/dist/breakouts/request.js.map +1 -0
  22. package/dist/breakouts/utils.js +67 -0
  23. package/dist/breakouts/utils.js.map +1 -0
  24. package/dist/common/browser-detection.js +1 -20
  25. package/dist/common/browser-detection.js.map +1 -1
  26. package/dist/common/collection.js +5 -20
  27. package/dist/common/collection.js.map +1 -1
  28. package/dist/common/config.js +0 -7
  29. package/dist/common/config.js.map +1 -1
  30. package/dist/common/errors/captcha-error.js +5 -26
  31. package/dist/common/errors/captcha-error.js.map +1 -1
  32. package/dist/common/errors/intent-to-join.js +5 -26
  33. package/dist/common/errors/intent-to-join.js.map +1 -1
  34. package/dist/common/errors/join-meeting.js +6 -27
  35. package/dist/common/errors/join-meeting.js.map +1 -1
  36. package/dist/common/errors/media.js +5 -26
  37. package/dist/common/errors/media.js.map +1 -1
  38. package/dist/common/errors/parameter.js +5 -33
  39. package/dist/common/errors/parameter.js.map +1 -1
  40. package/dist/common/errors/password-error.js +5 -26
  41. package/dist/common/errors/password-error.js.map +1 -1
  42. package/dist/common/errors/permission.js +4 -25
  43. package/dist/common/errors/permission.js.map +1 -1
  44. package/dist/common/errors/reconnection-in-progress.js +0 -17
  45. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  46. package/dist/common/errors/reconnection.js +5 -26
  47. package/dist/common/errors/reconnection.js.map +1 -1
  48. package/dist/common/errors/stats.js +5 -26
  49. package/dist/common/errors/stats.js.map +1 -1
  50. package/dist/common/errors/webex-errors.js +6 -41
  51. package/dist/common/errors/webex-errors.js.map +1 -1
  52. package/dist/common/errors/webex-meetings-error.js +1 -24
  53. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  54. package/dist/common/events/events-scope.js +0 -22
  55. package/dist/common/events/events-scope.js.map +1 -1
  56. package/dist/common/events/events.js +0 -23
  57. package/dist/common/events/events.js.map +1 -1
  58. package/dist/common/events/trigger-proxy.js +0 -12
  59. package/dist/common/events/trigger-proxy.js.map +1 -1
  60. package/dist/common/events/util.js +0 -15
  61. package/dist/common/events/util.js.map +1 -1
  62. package/dist/common/logs/logger-config.js +0 -4
  63. package/dist/common/logs/logger-config.js.map +1 -1
  64. package/dist/common/logs/logger-proxy.js +1 -8
  65. package/dist/common/logs/logger-proxy.js.map +1 -1
  66. package/dist/common/logs/request.js +35 -61
  67. package/dist/common/logs/request.js.map +1 -1
  68. package/dist/common/queue.js +4 -14
  69. package/dist/common/queue.js.map +1 -1
  70. package/dist/config.js +6 -6
  71. package/dist/config.js.map +1 -1
  72. package/dist/constants.js +203 -53
  73. package/dist/constants.js.map +1 -1
  74. package/dist/controls-options-manager/constants.js +14 -0
  75. package/dist/controls-options-manager/constants.js.map +1 -0
  76. package/dist/controls-options-manager/enums.js +27 -0
  77. package/dist/controls-options-manager/enums.js.map +1 -0
  78. package/dist/controls-options-manager/index.js +297 -0
  79. package/dist/controls-options-manager/index.js.map +1 -0
  80. package/dist/controls-options-manager/types.js +7 -0
  81. package/dist/controls-options-manager/types.js.map +1 -0
  82. package/dist/controls-options-manager/util.js +294 -0
  83. package/dist/controls-options-manager/util.js.map +1 -0
  84. package/dist/index.js +72 -17
  85. package/dist/index.js.map +1 -1
  86. package/dist/locus-info/controlsUtils.js +100 -29
  87. package/dist/locus-info/controlsUtils.js.map +1 -1
  88. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  89. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  90. package/dist/locus-info/fullState.js +0 -15
  91. package/dist/locus-info/fullState.js.map +1 -1
  92. package/dist/locus-info/hostUtils.js +4 -12
  93. package/dist/locus-info/hostUtils.js.map +1 -1
  94. package/dist/locus-info/index.js +406 -216
  95. package/dist/locus-info/index.js.map +1 -1
  96. package/dist/locus-info/infoUtils.js +0 -38
  97. package/dist/locus-info/infoUtils.js.map +1 -1
  98. package/dist/locus-info/mediaSharesUtils.js +54 -38
  99. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  100. package/dist/locus-info/parser.js +88 -123
  101. package/dist/locus-info/parser.js.map +1 -1
  102. package/dist/locus-info/selfUtils.js +105 -91
  103. package/dist/locus-info/selfUtils.js.map +1 -1
  104. package/dist/media/index.js +55 -165
  105. package/dist/media/index.js.map +1 -1
  106. package/dist/media/properties.js +71 -117
  107. package/dist/media/properties.js.map +1 -1
  108. package/dist/media/util.js +2 -9
  109. package/dist/media/util.js.map +1 -1
  110. package/dist/mediaQualityMetrics/config.js +505 -495
  111. package/dist/mediaQualityMetrics/config.js.map +1 -1
  112. package/dist/meeting/in-meeting-actions.js +77 -14
  113. package/dist/meeting/in-meeting-actions.js.map +1 -1
  114. package/dist/meeting/index.js +2603 -2462
  115. package/dist/meeting/index.js.map +1 -1
  116. package/dist/meeting/locusMediaRequest.js +291 -0
  117. package/dist/meeting/locusMediaRequest.js.map +1 -0
  118. package/dist/meeting/muteState.js +292 -138
  119. package/dist/meeting/muteState.js.map +1 -1
  120. package/dist/meeting/request.js +315 -336
  121. package/dist/meeting/request.js.map +1 -1
  122. package/dist/meeting/request.type.js +7 -0
  123. package/dist/meeting/request.type.js.map +1 -0
  124. package/dist/meeting/state.js +21 -31
  125. package/dist/meeting/state.js.map +1 -1
  126. package/dist/meeting/util.js +463 -583
  127. package/dist/meeting/util.js.map +1 -1
  128. package/dist/meeting-info/collection.js +3 -25
  129. package/dist/meeting-info/collection.js.map +1 -1
  130. package/dist/meeting-info/index.js +10 -33
  131. package/dist/meeting-info/index.js.map +1 -1
  132. package/dist/meeting-info/meeting-info-v2.js +305 -286
  133. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  134. package/dist/meeting-info/request.js +1 -16
  135. package/dist/meeting-info/request.js.map +1 -1
  136. package/dist/meeting-info/util.js +98 -183
  137. package/dist/meeting-info/util.js.map +1 -1
  138. package/dist/meeting-info/utilv2.js +156 -232
  139. package/dist/meeting-info/utilv2.js.map +1 -1
  140. package/dist/meetings/collection.js +24 -20
  141. package/dist/meetings/collection.js.map +1 -1
  142. package/dist/meetings/index.js +692 -593
  143. package/dist/meetings/index.js.map +1 -1
  144. package/dist/meetings/request.js +23 -42
  145. package/dist/meetings/request.js.map +1 -1
  146. package/dist/meetings/util.js +186 -155
  147. package/dist/meetings/util.js.map +1 -1
  148. package/dist/member/index.js +89 -88
  149. package/dist/member/index.js.map +1 -1
  150. package/dist/member/types.js +15 -0
  151. package/dist/member/types.js.map +1 -0
  152. package/dist/member/util.js +101 -69
  153. package/dist/member/util.js.map +1 -1
  154. package/dist/members/collection.js +12 -12
  155. package/dist/members/collection.js.map +1 -1
  156. package/dist/members/index.js +166 -205
  157. package/dist/members/index.js.map +1 -1
  158. package/dist/members/request.js +120 -85
  159. package/dist/members/request.js.map +1 -1
  160. package/dist/members/types.js +15 -0
  161. package/dist/members/types.js.map +1 -0
  162. package/dist/members/util.js +314 -260
  163. package/dist/members/util.js.map +1 -1
  164. package/dist/metrics/config.js +50 -16
  165. package/dist/metrics/config.js.map +1 -1
  166. package/dist/metrics/constants.js +4 -7
  167. package/dist/metrics/constants.js.map +1 -1
  168. package/dist/metrics/index.js +93 -162
  169. package/dist/metrics/index.js.map +1 -1
  170. package/dist/multistream/mediaRequestManager.js +167 -50
  171. package/dist/multistream/mediaRequestManager.js.map +1 -1
  172. package/dist/multistream/receiveSlot.js +58 -65
  173. package/dist/multistream/receiveSlot.js.map +1 -1
  174. package/dist/multistream/receiveSlotManager.js +74 -93
  175. package/dist/multistream/receiveSlotManager.js.map +1 -1
  176. package/dist/multistream/remoteMedia.js +55 -74
  177. package/dist/multistream/remoteMedia.js.map +1 -1
  178. package/dist/multistream/remoteMediaGroup.js +6 -40
  179. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  180. package/dist/multistream/remoteMediaManager.js +466 -442
  181. package/dist/multistream/remoteMediaManager.js.map +1 -1
  182. package/dist/networkQualityMonitor/index.js +32 -59
  183. package/dist/networkQualityMonitor/index.js.map +1 -1
  184. package/dist/personal-meeting-room/index.js +10 -45
  185. package/dist/personal-meeting-room/index.js.map +1 -1
  186. package/dist/personal-meeting-room/request.js +2 -33
  187. package/dist/personal-meeting-room/request.js.map +1 -1
  188. package/dist/personal-meeting-room/util.js +0 -13
  189. package/dist/personal-meeting-room/util.js.map +1 -1
  190. package/dist/reachability/index.js +190 -199
  191. package/dist/reachability/index.js.map +1 -1
  192. package/dist/reachability/request.js +14 -23
  193. package/dist/reachability/request.js.map +1 -1
  194. package/dist/reactions/constants.js +13 -0
  195. package/dist/reactions/constants.js.map +1 -0
  196. package/dist/reactions/reactions.js +2 -4
  197. package/dist/reactions/reactions.js.map +1 -1
  198. package/dist/reactions/reactions.type.js +19 -23
  199. package/dist/reactions/reactions.type.js.map +1 -1
  200. package/dist/reconnection-manager/index.js +326 -465
  201. package/dist/reconnection-manager/index.js.map +1 -1
  202. package/dist/recording-controller/enums.js +17 -0
  203. package/dist/recording-controller/enums.js.map +1 -0
  204. package/dist/recording-controller/index.js +343 -0
  205. package/dist/recording-controller/index.js.map +1 -0
  206. package/dist/recording-controller/util.js +63 -0
  207. package/dist/recording-controller/util.js.map +1 -0
  208. package/dist/roap/index.js +31 -75
  209. package/dist/roap/index.js.map +1 -1
  210. package/dist/roap/request.js +129 -136
  211. package/dist/roap/request.js.map +1 -1
  212. package/dist/roap/turnDiscovery.js +143 -103
  213. package/dist/roap/turnDiscovery.js.map +1 -1
  214. package/dist/statsAnalyzer/global.js +1 -95
  215. package/dist/statsAnalyzer/global.js.map +1 -1
  216. package/dist/statsAnalyzer/index.js +369 -461
  217. package/dist/statsAnalyzer/index.js.map +1 -1
  218. package/dist/statsAnalyzer/mqaUtil.js +144 -94
  219. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  220. package/dist/transcription/index.js +13 -45
  221. package/dist/transcription/index.js.map +1 -1
  222. package/dist/types/annotation/annotation.types.d.ts +35 -0
  223. package/dist/types/annotation/constants.d.ts +31 -0
  224. package/dist/types/annotation/index.d.ts +124 -0
  225. package/dist/types/breakouts/breakout.d.ts +8 -0
  226. package/dist/types/breakouts/collection.d.ts +5 -0
  227. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  228. package/dist/types/breakouts/events.d.ts +2 -0
  229. package/dist/types/breakouts/index.d.ts +5 -0
  230. package/dist/types/breakouts/request.d.ts +22 -0
  231. package/dist/types/breakouts/utils.d.ts +15 -0
  232. package/dist/types/common/browser-detection.d.ts +9 -0
  233. package/dist/types/common/collection.d.ts +48 -0
  234. package/dist/types/common/config.d.ts +2 -0
  235. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  236. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  237. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  238. package/dist/types/common/errors/media.d.ts +15 -0
  239. package/dist/types/common/errors/parameter.d.ts +15 -0
  240. package/dist/types/common/errors/password-error.d.ts +15 -0
  241. package/dist/types/common/errors/permission.d.ts +14 -0
  242. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  243. package/dist/types/common/errors/reconnection.d.ts +15 -0
  244. package/dist/types/common/errors/stats.d.ts +15 -0
  245. package/dist/types/common/errors/webex-errors.d.ts +69 -0
  246. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  247. package/dist/types/common/events/events-scope.d.ts +17 -0
  248. package/dist/types/common/events/events.d.ts +12 -0
  249. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  250. package/dist/types/common/events/util.d.ts +2 -0
  251. package/dist/types/common/logs/logger-config.d.ts +2 -0
  252. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  253. package/dist/types/common/logs/request.d.ts +34 -0
  254. package/dist/types/common/queue.d.ts +32 -0
  255. package/dist/types/config.d.ts +78 -0
  256. package/dist/types/constants.d.ts +993 -0
  257. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  258. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  259. package/dist/types/controls-options-manager/index.d.ts +136 -0
  260. package/dist/types/controls-options-manager/types.d.ts +43 -0
  261. package/dist/types/controls-options-manager/util.d.ts +1 -0
  262. package/dist/types/index.d.ts +7 -0
  263. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  264. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  265. package/dist/types/locus-info/fullState.d.ts +2 -0
  266. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  267. package/dist/types/locus-info/index.d.ts +315 -0
  268. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  269. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  270. package/dist/types/locus-info/parser.d.ts +212 -0
  271. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  272. package/dist/types/media/index.d.ts +34 -0
  273. package/dist/types/media/properties.d.ts +108 -0
  274. package/dist/types/media/util.d.ts +2 -0
  275. package/dist/types/mediaQualityMetrics/config.d.ts +365 -0
  276. package/dist/types/meeting/in-meeting-actions.d.ts +147 -0
  277. package/dist/types/meeting/index.d.ts +1762 -0
  278. package/dist/types/meeting/locusMediaRequest.d.ts +70 -0
  279. package/dist/types/meeting/muteState.d.ts +186 -0
  280. package/dist/types/meeting/request.d.ts +269 -0
  281. package/dist/types/meeting/request.type.d.ts +11 -0
  282. package/dist/types/meeting/state.d.ts +9 -0
  283. package/dist/types/meeting/util.d.ts +76 -0
  284. package/dist/types/meeting-info/collection.d.ts +20 -0
  285. package/dist/types/meeting-info/index.d.ts +57 -0
  286. package/dist/types/meeting-info/meeting-info-v2.d.ts +122 -0
  287. package/dist/types/meeting-info/request.d.ts +22 -0
  288. package/dist/types/meeting-info/util.d.ts +2 -0
  289. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  290. package/dist/types/meetings/collection.d.ts +31 -0
  291. package/dist/types/meetings/index.d.ts +345 -0
  292. package/dist/types/meetings/request.d.ts +27 -0
  293. package/dist/types/meetings/util.d.ts +18 -0
  294. package/dist/types/member/index.d.ts +157 -0
  295. package/dist/types/member/types.d.ts +21 -0
  296. package/dist/types/member/util.d.ts +2 -0
  297. package/dist/types/members/collection.d.ts +29 -0
  298. package/dist/types/members/index.d.ts +353 -0
  299. package/dist/types/members/request.d.ts +114 -0
  300. package/dist/types/members/types.d.ts +24 -0
  301. package/dist/types/members/util.d.ts +210 -0
  302. package/dist/types/metrics/config.d.ts +195 -0
  303. package/dist/types/metrics/constants.d.ts +55 -0
  304. package/dist/types/metrics/index.d.ts +169 -0
  305. package/dist/types/multistream/mediaRequestManager.d.ts +101 -0
  306. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  307. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  308. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  309. package/dist/types/multistream/remoteMediaGroup.d.ts +47 -0
  310. package/dist/types/multistream/remoteMediaManager.d.ts +263 -0
  311. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  312. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  313. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  314. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  315. package/dist/types/reachability/index.d.ts +152 -0
  316. package/dist/types/reachability/request.d.ts +37 -0
  317. package/dist/types/reactions/constants.d.ts +3 -0
  318. package/dist/types/reactions/reactions.d.ts +4 -0
  319. package/dist/types/reactions/reactions.type.d.ts +52 -0
  320. package/dist/types/reconnection-manager/index.d.ts +126 -0
  321. package/dist/types/recording-controller/enums.d.ts +7 -0
  322. package/dist/types/recording-controller/index.d.ts +193 -0
  323. package/dist/types/recording-controller/util.d.ts +13 -0
  324. package/dist/types/roap/index.d.ts +77 -0
  325. package/dist/types/roap/request.d.ts +36 -0
  326. package/dist/types/roap/turnDiscovery.d.ts +91 -0
  327. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  328. package/dist/types/statsAnalyzer/index.d.ts +200 -0
  329. package/dist/types/statsAnalyzer/mqaUtil.d.ts +24 -0
  330. package/dist/types/transcription/index.d.ts +64 -0
  331. package/internal-README.md +7 -6
  332. package/package.json +28 -21
  333. package/src/annotation/annotation.types.ts +42 -0
  334. package/src/annotation/constants.ts +36 -0
  335. package/src/annotation/index.ts +339 -0
  336. package/src/breakouts/README.md +220 -0
  337. package/src/breakouts/breakout.ts +163 -0
  338. package/src/breakouts/collection.ts +19 -0
  339. package/src/breakouts/edit-lock-error.ts +25 -0
  340. package/src/breakouts/events.ts +37 -0
  341. package/src/breakouts/index.ts +860 -0
  342. package/src/breakouts/request.ts +55 -0
  343. package/src/breakouts/utils.ts +57 -0
  344. package/src/common/browser-detection.ts +9 -6
  345. package/src/common/collection.ts +3 -1
  346. package/src/common/errors/captcha-error.ts +6 -6
  347. package/src/common/errors/intent-to-join.ts +6 -6
  348. package/src/common/errors/join-meeting.ts +12 -8
  349. package/src/common/errors/media.ts +6 -6
  350. package/src/common/errors/parameter.ts +9 -6
  351. package/src/common/errors/password-error.ts +6 -6
  352. package/src/common/errors/permission.ts +5 -5
  353. package/src/common/errors/reconnection.ts +6 -6
  354. package/src/common/errors/stats.ts +6 -6
  355. package/src/common/errors/webex-errors.ts +7 -5
  356. package/src/common/errors/webex-meetings-error.ts +1 -1
  357. package/src/common/events/events-scope.ts +5 -1
  358. package/src/common/events/events.ts +5 -1
  359. package/src/common/events/trigger-proxy.ts +8 -3
  360. package/src/common/events/util.ts +1 -2
  361. package/src/common/logs/logger-proxy.ts +21 -10
  362. package/src/common/logs/request.ts +11 -8
  363. package/src/config.ts +16 -12
  364. package/src/constants.ts +153 -7
  365. package/src/controls-options-manager/constants.ts +5 -0
  366. package/src/controls-options-manager/enums.ts +18 -0
  367. package/src/controls-options-manager/index.ts +278 -0
  368. package/src/controls-options-manager/types.ts +59 -0
  369. package/src/controls-options-manager/util.ts +281 -0
  370. package/src/index.ts +33 -0
  371. package/src/locus-info/controlsUtils.ts +142 -24
  372. package/src/locus-info/fullState.ts +15 -11
  373. package/src/locus-info/hostUtils.ts +4 -3
  374. package/src/locus-info/index.ts +346 -55
  375. package/src/locus-info/infoUtils.ts +12 -4
  376. package/src/locus-info/mediaSharesUtils.ts +52 -4
  377. package/src/locus-info/parser.ts +46 -68
  378. package/src/locus-info/selfUtils.ts +195 -56
  379. package/src/media/index.ts +139 -196
  380. package/src/media/properties.ts +43 -36
  381. package/src/media/util.ts +1 -1
  382. package/src/mediaQualityMetrics/config.ts +380 -378
  383. package/src/meeting/in-meeting-actions.ts +159 -3
  384. package/src/meeting/index.ts +2803 -1584
  385. package/src/meeting/locusMediaRequest.ts +309 -0
  386. package/src/meeting/muteState.ts +290 -72
  387. package/src/meeting/request.ts +247 -178
  388. package/src/meeting/request.type.ts +13 -0
  389. package/src/meeting/state.ts +45 -30
  390. package/src/meeting/util.ts +445 -395
  391. package/src/meeting-info/collection.ts +2 -1
  392. package/src/meeting-info/index.ts +32 -30
  393. package/src/meeting-info/meeting-info-v2.ts +235 -116
  394. package/src/meeting-info/request.ts +9 -3
  395. package/src/meeting-info/util.ts +54 -46
  396. package/src/meeting-info/utilv2.ts +71 -55
  397. package/src/meetings/collection.ts +21 -1
  398. package/src/meetings/index.ts +772 -437
  399. package/src/meetings/request.ts +29 -25
  400. package/src/meetings/util.ts +132 -33
  401. package/src/member/index.ts +95 -49
  402. package/src/member/types.ts +24 -0
  403. package/src/member/util.ts +106 -13
  404. package/src/members/collection.ts +8 -1
  405. package/src/members/index.ts +288 -130
  406. package/src/members/request.ts +144 -31
  407. package/src/members/types.ts +28 -0
  408. package/src/members/util.ts +316 -235
  409. package/src/metrics/config.ts +302 -90
  410. package/src/metrics/constants.ts +2 -6
  411. package/src/metrics/index.ts +124 -95
  412. package/src/multistream/mediaRequestManager.ts +203 -45
  413. package/src/multistream/receiveSlot.ts +69 -26
  414. package/src/multistream/receiveSlotManager.ts +62 -38
  415. package/src/multistream/remoteMedia.ts +30 -4
  416. package/src/multistream/remoteMediaGroup.ts +4 -3
  417. package/src/multistream/remoteMediaManager.ts +230 -66
  418. package/src/networkQualityMonitor/index.ts +24 -27
  419. package/src/personal-meeting-room/index.ts +12 -16
  420. package/src/personal-meeting-room/request.ts +10 -3
  421. package/src/personal-meeting-room/util.ts +3 -3
  422. package/src/reachability/index.ts +131 -79
  423. package/src/reachability/request.ts +43 -34
  424. package/src/reactions/constants.ts +4 -0
  425. package/src/reactions/reactions.ts +8 -8
  426. package/src/reactions/reactions.type.ts +31 -5
  427. package/src/reconnection-manager/index.ts +193 -111
  428. package/src/recording-controller/enums.ts +8 -0
  429. package/src/recording-controller/index.ts +315 -0
  430. package/src/recording-controller/util.ts +58 -0
  431. package/src/roap/index.ts +53 -53
  432. package/src/roap/request.ts +77 -64
  433. package/src/roap/turnDiscovery.ts +101 -48
  434. package/src/statsAnalyzer/global.ts +8 -104
  435. package/src/statsAnalyzer/index.ts +624 -376
  436. package/src/statsAnalyzer/mqaUtil.ts +203 -90
  437. package/src/transcription/index.ts +34 -32
  438. package/test/integration/spec/converged-space-meetings.js +177 -0
  439. package/test/integration/spec/journey.js +670 -466
  440. package/test/integration/spec/space-meeting.js +320 -204
  441. package/test/integration/spec/transcription.js +7 -8
  442. package/test/unit/spec/annotation/index.ts +433 -0
  443. package/test/unit/spec/breakouts/breakout.ts +203 -0
  444. package/test/unit/spec/breakouts/collection.ts +15 -0
  445. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  446. package/test/unit/spec/breakouts/events.ts +77 -0
  447. package/test/unit/spec/breakouts/index.ts +1609 -0
  448. package/test/unit/spec/breakouts/request.ts +104 -0
  449. package/test/unit/spec/breakouts/utils.js +72 -0
  450. package/test/unit/spec/common/browser-detection.js +9 -28
  451. package/test/unit/spec/controls-options-manager/index.js +287 -0
  452. package/test/unit/spec/controls-options-manager/util.js +504 -0
  453. package/test/unit/spec/fixture/locus.js +93 -90
  454. package/test/unit/spec/locus-info/controlsUtils.js +305 -32
  455. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  456. package/test/unit/spec/locus-info/index.js +636 -5
  457. package/test/unit/spec/locus-info/infoUtils.js +26 -33
  458. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  459. package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
  460. package/test/unit/spec/locus-info/mediaSharesUtils.ts +22 -0
  461. package/test/unit/spec/locus-info/parser.js +3 -9
  462. package/test/unit/spec/locus-info/selfConstant.js +110 -103
  463. package/test/unit/spec/locus-info/selfUtils.js +252 -12
  464. package/test/unit/spec/media/index.ts +104 -8
  465. package/test/unit/spec/media/properties.ts +9 -9
  466. package/test/unit/spec/meeting/in-meeting-actions.ts +76 -3
  467. package/test/unit/spec/meeting/index.js +3112 -921
  468. package/test/unit/spec/meeting/locusMediaRequest.ts +436 -0
  469. package/test/unit/spec/meeting/muteState.js +421 -94
  470. package/test/unit/spec/meeting/request.js +421 -79
  471. package/test/unit/spec/meeting/utils.js +326 -189
  472. package/test/unit/spec/meeting-info/meetinginfov2.js +481 -76
  473. package/test/unit/spec/meeting-info/request.js +7 -9
  474. package/test/unit/spec/meeting-info/util.js +11 -12
  475. package/test/unit/spec/meeting-info/utilv2.js +131 -74
  476. package/test/unit/spec/meetings/collection.js +15 -1
  477. package/test/unit/spec/meetings/index.js +1126 -328
  478. package/test/unit/spec/meetings/utils.js +220 -14
  479. package/test/unit/spec/member/index.js +24 -1
  480. package/test/unit/spec/member/util.js +383 -32
  481. package/test/unit/spec/members/index.js +424 -55
  482. package/test/unit/spec/members/request.js +228 -40
  483. package/test/unit/spec/members/utils.js +191 -4
  484. package/test/unit/spec/metrics/index.js +113 -20
  485. package/test/unit/spec/multistream/mediaRequestManager.ts +650 -105
  486. package/test/unit/spec/multistream/receiveSlot.ts +76 -17
  487. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  488. package/test/unit/spec/multistream/remoteMedia.ts +32 -2
  489. package/test/unit/spec/multistream/remoteMediaGroup.ts +5 -5
  490. package/test/unit/spec/multistream/remoteMediaManager.ts +549 -65
  491. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  492. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  493. package/test/unit/spec/reachability/index.ts +176 -27
  494. package/test/unit/spec/reachability/request.js +66 -0
  495. package/test/unit/spec/reconnection-manager/index.js +62 -31
  496. package/test/unit/spec/recording-controller/index.js +231 -0
  497. package/test/unit/spec/recording-controller/util.js +102 -0
  498. package/test/unit/spec/roap/index.ts +19 -49
  499. package/test/unit/spec/roap/request.ts +187 -0
  500. package/test/unit/spec/roap/turnDiscovery.ts +92 -50
  501. package/test/unit/spec/stats-analyzer/index.js +116 -60
  502. package/test/utils/cmr.js +44 -42
  503. package/test/utils/constants.js +9 -0
  504. package/test/utils/integrationTestUtils.js +64 -0
  505. package/test/utils/testUtils.js +63 -99
  506. package/test/utils/webex-config.js +22 -18
  507. package/test/utils/webex-test-users.js +57 -50
  508. package/tsconfig.json +6 -0
  509. package/dist/media/internal-media-core-wrapper.js +0 -22
  510. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  511. package/dist/meeting/effectsState.js +0 -334
  512. package/dist/meeting/effectsState.js.map +0 -1
  513. package/dist/multistream/multistreamMedia.js +0 -116
  514. package/dist/multistream/multistreamMedia.js.map +0 -1
  515. package/src/index.js +0 -15
  516. package/src/media/internal-media-core-wrapper.ts +0 -9
  517. package/src/meeting/effectsState.ts +0 -211
  518. package/src/multistream/multistreamMedia.ts +0 -92
  519. package/test/unit/spec/meeting/effectsState.js +0 -291
@@ -1,8 +1,12 @@
1
+ /* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
2
+
1
3
  import '@webex/internal-plugin-mercury';
2
4
  import '@webex/internal-plugin-conversation';
3
5
  // @ts-ignore
4
6
  import {WebexPlugin} from '@webex/webex-core';
5
- import {MediaConnection as MC} from '@webex/internal-media-core';
7
+ import {setLogger} from '@webex/internal-media-core';
8
+
9
+ import * as mediaHelpersModule from '@webex/media-helpers';
6
10
 
7
11
  import 'webrtc-adapter';
8
12
 
@@ -37,7 +41,11 @@ import {
37
41
  _ID_,
38
42
  MEETING_REMOVED_REASON,
39
43
  _CONVERSATION_URL_,
40
- CONVERSATION_URL
44
+ CONVERSATION_URL,
45
+ MEETINGNUMBER,
46
+ BREAKOUTS,
47
+ _JOINED_,
48
+ _MOVED_,
41
49
  } from '../constants';
42
50
  import BEHAVIORAL_METRICS from '../metrics/constants';
43
51
  import MeetingInfo from '../meeting-info';
@@ -45,12 +53,13 @@ import MeetingInfoV2 from '../meeting-info/meeting-info-v2';
45
53
  import Meeting from '../meeting';
46
54
  import PersonalMeetingRoom from '../personal-meeting-room';
47
55
  import Reachability from '../reachability';
48
- import Request from '../meetings/request';
56
+ import Request from './request';
49
57
  import PasswordError from '../common/errors/password-error';
50
58
  import CaptchaError from '../common/errors/captcha-error';
51
59
 
52
60
  import MeetingCollection from './collection';
53
61
  import MeetingsUtil from './util';
62
+ import PermissionError from '../common/errors/permission';
54
63
 
55
64
  let mediaLogger;
56
65
 
@@ -80,21 +89,21 @@ class MediaLogger {
80
89
  }
81
90
  }
82
91
  /**
83
- * Meetings Ready Event
84
- * Emitted when the meetings instance on webex is ready
85
- * @event meetings:ready
86
- * @instance
87
- * @memberof Meetings
88
- */
92
+ * Meetings Ready Event
93
+ * Emitted when the meetings instance on webex is ready
94
+ * @event meetings:ready
95
+ * @instance
96
+ * @memberof Meetings
97
+ */
89
98
 
90
99
  /**
91
- * Meetings Network Disconnected Event
92
- * Emitted when the meetings instance is disconnected from
93
- * the internal mercury server
94
- * @event network:disconnected
95
- * @instance
96
- * @memberof Meetings
97
- */
100
+ * Meetings Network Disconnected Event
101
+ * Emitted when the meetings instance is disconnected from
102
+ * the internal mercury server
103
+ * @event network:disconnected
104
+ * @instance
105
+ * @memberof Meetings
106
+ */
98
107
 
99
108
  /**
100
109
  * Meetings Registered Event
@@ -105,32 +114,32 @@ class MediaLogger {
105
114
  */
106
115
 
107
116
  /**
108
- * Meeting Removed Event
109
- * Emitted when a meeting was removed from the cache of meetings
110
- * @event meeting:removed
111
- * @instance
112
- * @type {Object}
113
- * @property {String} meetingId the removed meeting
114
- * @property {Object} response the server response
115
- * @property {String} type what type of meeting it was
116
- * @memberof Meetings
117
- */
117
+ * Meeting Removed Event
118
+ * Emitted when a meeting was removed from the cache of meetings
119
+ * @event meeting:removed
120
+ * @instance
121
+ * @type {Object}
122
+ * @property {String} meetingId the removed meeting
123
+ * @property {Object} response the server response
124
+ * @property {String} type what type of meeting it was
125
+ * @memberof Meetings
126
+ */
118
127
 
119
128
  /**
120
- * Meeting Added Event
121
- * Emitted when a meeting was added to the cache of meetings
122
- * @event meeting:added
123
- * @instance
124
- * @type {Object}
125
- * @property {String} meetingId the added meeting
126
- * @property {String} type what type of meeting it was
127
- * @memberof Meetings
128
- */
129
+ * Meeting Added Event
130
+ * Emitted when a meeting was added to the cache of meetings
131
+ * @event meeting:added
132
+ * @instance
133
+ * @type {Object}
134
+ * @property {String} meetingId the added meeting
135
+ * @property {String} type what type of meeting it was
136
+ * @memberof Meetings
137
+ */
129
138
 
130
139
  /**
131
- * Maintain a cache of meetings and sync with services.
132
- * @class
133
- */
140
+ * Maintain a cache of meetings and sync with services.
141
+ * @class
142
+ */
134
143
  export default class Meetings extends WebexPlugin {
135
144
  loggerRequest: any;
136
145
  media: any;
@@ -142,120 +151,272 @@ export default class Meetings extends WebexPlugin {
142
151
  request: any;
143
152
  geoHintInfo: any;
144
153
  meetingInfo: any;
145
-
154
+ mediaHelpers: any;
155
+ breakoutLocusForHandleLater: any;
146
156
  namespace = MEETINGS;
147
157
 
148
158
  /**
149
- * Initializes the Meetings Plugin
150
- * @constructor
151
- * @public
152
- * @memberof Meetings
153
- */
159
+ * Initializes the Meetings Plugin
160
+ * @constructor
161
+ * @public
162
+ * @memberof Meetings
163
+ */
154
164
  constructor(...args) {
155
165
  super(...args);
156
166
 
157
167
  /**
158
- * The Meetings request to interact with server
159
- * @instance
160
- * @type {Object}
161
- * @private
162
- * @memberof Meetings
163
- */
168
+ * The webrtc-core media helpers. This is a temporary solution required for the SDK sample app
169
+ * to be able to call media helper functions.
170
+ *
171
+ * @instance
172
+ * @type {Object}
173
+ * @private
174
+ * @memberof Meetings
175
+ */
176
+ this.mediaHelpers = mediaHelpersModule;
177
+
178
+ /**
179
+ * The Meetings request to interact with server
180
+ * @instance
181
+ * @type {Object}
182
+ * @private
183
+ * @memberof Meetings
184
+ */
164
185
  // @ts-ignore
165
186
  this.request = new Request({}, {parent: this.webex});
166
187
  /**
167
- * Log upload request helper
168
- * @instance
169
- * @type {Object}
170
- * @private
171
- * @memberof Meetings
172
- */
188
+ * Log upload request helper
189
+ * @instance
190
+ * @type {Object}
191
+ * @private
192
+ * @memberof Meetings
193
+ */
173
194
  // @ts-ignore
174
195
  this.loggerRequest = new LoggerRequest({webex: this.webex});
175
196
  this.meetingCollection = new MeetingCollection();
176
197
  /**
177
- * The PersonalMeetingRoom object to interact with server
178
- * @instance
179
- * @type {Object}
180
- * @public
181
- * @memberof Meetings
182
- */
198
+ * The PersonalMeetingRoom object to interact with server
199
+ * @instance
200
+ * @type {Object}
201
+ * @public
202
+ * @memberof Meetings
203
+ */
183
204
  this.personalMeetingRoom = null;
184
205
  /**
185
- * The Reachability object to interact with server, starts as null until {@link Meeting#setReachability} is called
186
- * starts as null
187
- * @instance
188
- * @type {Object}
189
- * @private
190
- * @memberof Meetings
191
- */
206
+ * The Reachability object to interact with server, starts as null until {@link Meeting#setReachability} is called
207
+ * starts as null
208
+ * @instance
209
+ * @type {Object}
210
+ * @private
211
+ * @memberof Meetings
212
+ */
192
213
  this.reachability = null;
193
214
 
194
215
  /**
195
- * If the meetings plugin has been registered and listening via {@link Meetings#register}
196
- * @instance
197
- * @type {Boolean}
198
- * @public
199
- * @memberof Meetings
200
- */
216
+ * If the meetings plugin has been registered and listening via {@link Meetings#register}
217
+ * @instance
218
+ * @type {Boolean}
219
+ * @public
220
+ * @memberof Meetings
221
+ */
201
222
  this.registered = false;
202
223
 
203
224
  /**
204
- * This values indicates the preferred webex site the user will start there meeting, getsits value from {@link Meetings#register}
205
- * @instance
206
- * @type {String}
207
- * @private
208
- * @memberof Meetings
209
- */
225
+ * This values indicates the preferred webex site the user will start there meeting, getsits value from {@link Meetings#register}
226
+ * @instance
227
+ * @type {String}
228
+ * @private
229
+ * @memberof Meetings
230
+ */
210
231
  this.preferredWebexSite = '';
211
232
 
212
233
  /**
213
- * The public interface for the internal Media util files. These are helpful to expose outside the context
214
- * of a meeting so that a user can access media without creating a meeting instance.
215
- * @instance
216
- * @type {Object}
217
- * @private
218
- * @memberof Meetings
219
- */
234
+ * The public interface for the internal Media util files. These are helpful to expose outside the context
235
+ * of a meeting so that a user can access media without creating a meeting instance.
236
+ * @instance
237
+ * @type {Object}
238
+ * @private
239
+ * @memberof Meetings
240
+ */
220
241
  this.media = {
221
242
  getUserMedia: Media.getUserMedia,
222
- getSupportedDevice: Media.getSupportedDevice
243
+ getSupportedDevice: Media.getSupportedDevice,
223
244
  };
224
245
 
225
246
  this.onReady();
226
247
  }
227
248
 
228
249
  /**
229
- * handle locus events and takes meeting actions with them as they come in
230
- * @param {Object} data a locus event
231
- * @param {String} data.locusUrl
232
- * @param {Object} data.locus
233
- * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
234
- * @param {String} data.eventType
235
- * @returns {undefined}
236
- * @private
237
- * @memberof Meetings
238
- */
239
- private handleLocusEvent(data: { locusUrl: string; locus: any }, useRandomDelayForInfo: boolean = false) {
240
- let meeting = null;
250
+ * check whether you need to handle this main session's locus data or not
251
+ * @param {Object} meeting current meeting data
252
+ * @param {Object} newLocus new locus data
253
+ * @returns {boolean}
254
+ * @private
255
+ * @memberof Meetings
256
+ */
257
+ private isNeedHandleMainLocus(meeting: any, newLocus: any) {
258
+ const breakoutUrl = newLocus.controls?.breakout?.url;
259
+ const breakoutLocus = this.meetingCollection.getActiveBreakoutLocus(breakoutUrl);
260
+
261
+ const isSelfJoined = newLocus?.self?.state === _JOINED_;
262
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
263
+ // @ts-ignore
264
+ const deviceFromNewLocus = MeetingsUtil.getThisDevice(newLocus, this.webex.internal.device.url);
265
+ const isNewLocusJoinThisDevice = MeetingsUtil.joinedOnThisDevice(
266
+ meeting,
267
+ newLocus,
268
+ // @ts-ignore
269
+ this.webex.internal.device.url
270
+ );
271
+ const isBreakoutLocusJoinThisDevice =
272
+ breakoutLocus?.joinedWith?.correlationId &&
273
+ breakoutLocus.joinedWith.correlationId === meeting?.correlationId;
241
274
 
275
+ if (isSelfJoined && isNewLocusJoinThisDevice) {
276
+ LoggerProxy.logger.log(
277
+ 'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
278
+ );
279
+ if (breakoutLocus?.joinedWith && deviceFromNewLocus) {
280
+ const breakoutReplaceAt =
281
+ breakoutLocus.joinedWith.replaces?.length > 0
282
+ ? breakoutLocus.joinedWith.replaces[0].replaceAt
283
+ : '';
284
+ const newLocusReplaceAt =
285
+ deviceFromNewLocus.replaces?.length > 0 ? deviceFromNewLocus.replaces[0].replaceAt : '';
286
+ if (breakoutReplaceAt && newLocusReplaceAt && breakoutReplaceAt > newLocusReplaceAt) {
287
+ LoggerProxy.logger.log(
288
+ `Meetings:index#isNeedHandleMainLocus --> this is expired main joined status locus_dto replacedAt ${newLocusReplaceAt} bo replacedAt ${breakoutReplaceAt}`
289
+ );
290
+
291
+ return false;
292
+ }
293
+ }
294
+
295
+ return true;
296
+ }
297
+ if (isBreakoutLocusJoinThisDevice) {
298
+ LoggerProxy.logger.log(
299
+ `Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: ${breakoutUrl}`
300
+ );
301
+
302
+ return false;
303
+ }
304
+ if (isSelfMoved && newLocus?.self?.removed) {
305
+ LoggerProxy.logger.log(
306
+ 'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status, not need to handle'
307
+ );
308
+
309
+ return false;
310
+ }
311
+ LoggerProxy.logger.log(
312
+ 'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
313
+ );
314
+
315
+ return true;
316
+ }
317
+
318
+ /**
319
+ * check whether you need to handle this locus data or not
320
+ * @param {Object} meeting old locus data
321
+ * @param {Object} newLocus new locus data
322
+ * @returns {boolean}
323
+ * @private
324
+ * @memberof Meetings
325
+ */
326
+ private isNeedHandleLocusDTO(meeting: any, newLocus: any) {
327
+ if (newLocus) {
328
+ const isNewLocusAsBreakout = MeetingsUtil.isBreakoutLocusDTO(newLocus);
329
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
330
+ if (!meeting) {
331
+ if (isNewLocusAsBreakout) {
332
+ LoggerProxy.logger.log(
333
+ `Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: ${newLocus.fullState?.active}`
334
+ );
335
+
336
+ return newLocus.self?.state === _JOINED_;
337
+ }
338
+
339
+ return this.isNeedHandleMainLocus(meeting, newLocus);
340
+ }
341
+ if (!isNewLocusAsBreakout) {
342
+ return this.isNeedHandleMainLocus(meeting, newLocus);
343
+ }
344
+
345
+ return !isSelfMoved;
346
+ }
347
+
348
+ return true;
349
+ }
350
+
351
+ /**
352
+ * get corresponding meeting object by locus data
353
+ * @param {Object} data a locus event
354
+ * @param {String} data.locusUrl
355
+ * @param {Object} data.locus
356
+ * @returns {Object}
357
+ * @private
358
+ * @memberof Meetings
359
+ */
360
+ getCorrespondingMeetingByLocus(data) {
242
361
  // getting meeting by correlationId. This will happen for the new event
243
362
  // Either the locus
244
363
  // TODO : Add check for the callBack Address
245
- meeting = this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
246
- // @ts-ignore
247
- this.meetingCollection.getByKey(CORRELATION_ID, MeetingsUtil.checkForCorrelationId(this.webex.internal.device.url, data.locus)) ||
248
- this.meetingCollection.getByKey(SIP_URI, data.locus.self && data.locus.self.callbackInfo && data.locus.self.callbackInfo.callbackAddress) ||
249
- (data.locus.info?.isUnifiedSpaceMeeting ? undefined : this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl));
364
+ return (
365
+ this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
366
+ // @ts-ignore
367
+ this.meetingCollection.getByKey(
368
+ CORRELATION_ID,
369
+ // @ts-ignore
370
+ MeetingsUtil.checkForCorrelationId(this.webex.internal.device.url, data.locus)
371
+ ) ||
372
+ this.meetingCollection.getByKey(
373
+ SIP_URI,
374
+ data.locus.self &&
375
+ data.locus.self.callbackInfo &&
376
+ data.locus.self.callbackInfo.callbackAddress
377
+ ) ||
378
+ (data.locus.info?.isUnifiedSpaceMeeting
379
+ ? undefined
380
+ : this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl)) ||
381
+ this.meetingCollection.getByKey(MEETINGNUMBER, data.locus?.info?.webExMeetingId)
382
+ );
383
+ }
384
+
385
+ /**
386
+ * handle locus events and takes meeting actions with them as they come in
387
+ * @param {Object} data a locus event
388
+ * @param {String} data.locusUrl
389
+ * @param {Object} data.locus
390
+ * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
391
+ * @param {String} data.eventType
392
+ * @returns {undefined}
393
+ * @private
394
+ * @memberof Meetings
395
+ */
396
+ private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
397
+ let meeting = this.getCorrespondingMeetingByLocus(data);
250
398
 
251
399
  // Special case when locus has got replaced, This only happend once if a replace locus exists
252
400
  // https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-changing-mid-call
253
401
 
254
402
  if (!meeting && data.locus?.replaces?.length > 0) {
255
403
  // Always the last element in the replace is the active one
256
- meeting = this.meetingCollection.getByKey(LOCUS_URL, data.locus.replaces[data.locus.replaces.length - 1].locusUrl);
404
+ meeting = this.meetingCollection.getByKey(
405
+ LOCUS_URL,
406
+ data.locus.replaces[data.locus.replaces.length - 1].locusUrl
407
+ );
408
+ }
409
+
410
+ if (meeting && !MeetingsUtil.isBreakoutLocusDTO(data.locus)) {
411
+ meeting.locusInfo.updateMainSessionLocusCache(data.locus);
257
412
  }
413
+ if (!this.isNeedHandleLocusDTO(meeting, data.locus)) {
414
+ LoggerProxy.logger.log(
415
+ `Meetings:index#handleLocusEvent --> doesn't need to process locus event`
416
+ );
258
417
 
418
+ return;
419
+ }
259
420
  if (!meeting) {
260
421
  // TODO: create meeting when we get a meeting object
261
422
  // const checkForEnded = (locus) => {
@@ -276,73 +437,93 @@ export default class Meetings extends WebexPlugin {
276
437
  // };
277
438
  // rather then locus object change to locus url
278
439
 
279
- if (data.locus && data.locus.fullState && data.locus.fullState.state === LOCUS.STATE.INACTIVE) {
440
+ if (
441
+ data.locus &&
442
+ data.locus.fullState &&
443
+ data.locus.fullState.state === LOCUS.STATE.INACTIVE
444
+ ) {
280
445
  // just ignore the event as its already ended and not active
281
- LoggerProxy.logger.warn('Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.');
446
+ LoggerProxy.logger.warn(
447
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
448
+ );
282
449
 
283
450
  return;
284
451
  }
285
452
 
286
-
287
453
  // When its wireless share or guest and user leaves the meeting we dont have to keep the meeting object
288
454
  // Any future events will be neglected
289
455
 
290
- if (data.locus && data.locus.self && (data.locus.self.state === _LEFT_ && data.locus.self.removed === true)) {
456
+ if (
457
+ data.locus &&
458
+ data.locus.self &&
459
+ data.locus.self.state === _LEFT_ &&
460
+ data.locus.self.removed === true
461
+ ) {
291
462
  // just ignore the event as its already ended and not active
292
- LoggerProxy.logger.warn('Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.');
463
+ LoggerProxy.logger.warn(
464
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
465
+ );
293
466
 
294
467
  return;
295
468
  }
296
469
 
297
- this.create(data.locus, _LOCUS_ID_, useRandomDelayForInfo).then((newMeeting) => {
298
- meeting = newMeeting;
299
-
300
- // It's a new meeting so initialize the locus data
301
- meeting.locusInfo.initialSetup(data.locus);
302
- }).catch((e) => {
303
- console.log(e);
304
- })
470
+ this.create(data.locus, _LOCUS_ID_, useRandomDelayForInfo)
471
+ .then((newMeeting) => {
472
+ meeting = newMeeting;
473
+
474
+ // It's a new meeting so initialize the locus data
475
+ meeting.locusInfo.initialSetup(data.locus);
476
+ this.checkHandleBreakoutLocus(data.locus);
477
+ })
478
+ .catch((e) => {
479
+ LoggerProxy.logger.error(e);
480
+ })
305
481
  .finally(() => {
306
482
  // There will be cases where locus event comes in gets created and deleted because its a 1:1 and meeting gets deleted
307
483
  // because the other user left so before sending 'added' event make sure it exists in the collection
308
484
 
309
485
  if (this.getMeetingByType(_ID_, meeting.id)) {
310
- Metrics.postEvent({event: eventType.REMOTE_STARTED, meeting, data: {trigger: trigger.MERCURY_EVENT}});
486
+ Metrics.postEvent({
487
+ event: eventType.REMOTE_STARTED,
488
+ meeting,
489
+ data: {trigger: trigger.MERCURY_EVENT},
490
+ });
311
491
  Trigger.trigger(
312
492
  this,
313
493
  {
314
494
  file: 'meetings',
315
- function: 'handleLocusEvent'
495
+ function: 'handleLocusEvent',
316
496
  },
317
497
  EVENT_TRIGGERS.MEETING_ADDED,
318
498
  {
319
499
  meeting,
320
- type: meeting.type === _MEETING_ ? _JOIN_ : _INCOMING_
500
+ type: meeting.type === _MEETING_ ? _JOIN_ : _INCOMING_,
321
501
  }
322
502
  );
323
- }
324
- else {
503
+ } else {
325
504
  // Meeting got added but was not found in the collection. It might have got destroyed
326
- LoggerProxy.logger.warn('Meetings:index#handleLocusEvent --> Created and destroyed meeting object before sending an event');
505
+ LoggerProxy.logger.warn(
506
+ 'Meetings:index#handleLocusEvent --> Created and destroyed meeting object before sending an event'
507
+ );
327
508
  }
328
509
  });
329
- }
330
- else {
510
+ } else {
331
511
  meeting.locusInfo.parse(meeting, data);
332
512
  }
333
513
  }
334
514
 
335
515
  /**
336
- * handles locus events through mercury that are not roap
337
- * @param {Object} envelope
338
- * @param {Object} envelope.data
339
- * @param {String} envelope.data.eventType
340
- * @returns {undefined}
341
- * @private
342
- * @memberof Meetings
343
- */
344
- private handleLocusMercury(envelope: { data: any }) {
516
+ * handles locus events through mercury that are not roap
517
+ * @param {Object} envelope
518
+ * @param {Object} envelope.data
519
+ * @param {String} envelope.data.eventType
520
+ * @returns {undefined}
521
+ * @private
522
+ * @memberof Meetings
523
+ */
524
+ private handleLocusMercury(envelope: {data: any}) {
345
525
  const {data} = envelope;
526
+ // eslint-disable-next-line @typescript-eslint/no-shadow
346
527
  const {eventType} = data;
347
528
 
348
529
  if (eventType && eventType !== LOCUSEVENT.MESSAGE_ROAP) {
@@ -350,31 +531,29 @@ export default class Meetings extends WebexPlugin {
350
531
  }
351
532
  }
352
533
 
353
-
354
534
  /**
355
- * handles mecury offline event
356
- * @returns {undefined}
357
- * @private
358
- * @memberof Meetings
359
- */
535
+ * handles mecury offline event
536
+ * @returns {undefined}
537
+ * @private
538
+ * @memberof Meetings
539
+ */
360
540
  private handleMercuryOffline() {
361
541
  Trigger.trigger(
362
542
  this,
363
543
  {
364
544
  file: 'meetings/index',
365
- function: 'handleMercuryOffline'
545
+ function: 'handleMercuryOffline',
366
546
  },
367
- EVENT_TRIGGERS.MEETINGS_NETWORK_DISCONNECTED,
547
+ EVENT_TRIGGERS.MEETINGS_NETWORK_DISCONNECTED
368
548
  );
369
549
  }
370
550
 
371
-
372
551
  /**
373
- * registers for locus and roap mercury events
374
- * @returns {undefined}
375
- * @private
376
- * @memberof Meetings
377
- */
552
+ * registers for locus and roap mercury events
553
+ * @returns {undefined}
554
+ * @private
555
+ * @memberof Meetings
556
+ */
378
557
  private listenForEvents() {
379
558
  // @ts-ignore
380
559
  this.webex.internal.mercury.on(LOCUSEVENT.LOCUS_MERCURY, (envelope) => {
@@ -397,11 +576,11 @@ export default class Meetings extends WebexPlugin {
397
576
  }
398
577
 
399
578
  /**
400
- * stops listening for locus and roap mercury events
401
- * @returns {undefined}
402
- * @private
403
- * @memberof Meetings
404
- */
579
+ * stops listening for locus and roap mercury events
580
+ * @returns {undefined}
581
+ * @private
582
+ * @memberof Meetings
583
+ */
405
584
  private stopListeningForEvents() {
406
585
  // @ts-ignore
407
586
  this.webex.internal.mercury.off(LOCUSEVENT.LOCUS_MERCURY);
@@ -412,10 +591,10 @@ export default class Meetings extends WebexPlugin {
412
591
  }
413
592
 
414
593
  /**
415
- * @returns {undefined}
416
- * @private
417
- * @memberof Meetings
418
- */
594
+ * @returns {undefined}
595
+ * @private
596
+ * @memberof Meetings
597
+ */
419
598
  private onReady() {
420
599
  // @ts-ignore
421
600
  this.webex.once(READY, () => {
@@ -427,7 +606,7 @@ export default class Meetings extends WebexPlugin {
427
606
  LoggerProxy.set(this.webex.logger);
428
607
 
429
608
  mediaLogger = new MediaLogger();
430
- MC.setLogger(mediaLogger);
609
+ setLogger(mediaLogger);
431
610
 
432
611
  /**
433
612
  * The MeetingInfo object to interact with server
@@ -437,15 +616,23 @@ export default class Meetings extends WebexPlugin {
437
616
  * @memberof Meetings
438
617
  */
439
618
  // @ts-ignore
440
- this.meetingInfo = this.config.experimental.enableUnifiedMeetings ? new MeetingInfoV2(this.webex) : new MeetingInfo(this.webex);
619
+ this.meetingInfo = this.config.experimental.enableUnifiedMeetings
620
+ ? // @ts-ignore
621
+ new MeetingInfoV2(this.webex)
622
+ : // @ts-ignore
623
+ new MeetingInfo(this.webex);
441
624
  // @ts-ignore
442
- this.personalMeetingRoom = new PersonalMeetingRoom({meetingInfo: this.meetingInfo}, {parent: this.webex});
625
+ this.personalMeetingRoom = new PersonalMeetingRoom(
626
+ {meetingInfo: this.meetingInfo},
627
+ // @ts-ignore
628
+ {parent: this.webex}
629
+ );
443
630
 
444
631
  Trigger.trigger(
445
632
  this,
446
633
  {
447
634
  file: 'meetings',
448
- function: 'onReady'
635
+ function: 'onReady',
449
636
  },
450
637
  EVENT_TRIGGERS.MEETINGS_READY
451
638
  );
@@ -457,12 +644,12 @@ export default class Meetings extends WebexPlugin {
457
644
  }
458
645
 
459
646
  /**
460
- * API to toggle unified meetings
461
- * @param {Boolean} changeState
462
- * @private
463
- * @memberof Meetings
464
- * @returns {undefined}
465
- */
647
+ * API to toggle unified meetings
648
+ * @param {Boolean} changeState
649
+ * @private
650
+ * @memberof Meetings
651
+ * @returns {undefined}
652
+ */
466
653
  private _toggleUnifiedMeetings(changeState: boolean) {
467
654
  if (typeof changeState !== 'boolean') {
468
655
  return;
@@ -477,12 +664,12 @@ export default class Meetings extends WebexPlugin {
477
664
  }
478
665
 
479
666
  /**
480
- * API to enable or disable TURN discovery
481
- * @param {Boolean} enable
482
- * @private
483
- * @memberof Meetings
484
- * @returns {undefined}
485
- */
667
+ * API to enable or disable TURN discovery
668
+ * @param {Boolean} enable
669
+ * @private
670
+ * @memberof Meetings
671
+ * @returns {undefined}
672
+ */
486
673
  private _toggleTurnDiscovery(enable: boolean) {
487
674
  if (typeof enable !== 'boolean') {
488
675
  return;
@@ -492,12 +679,12 @@ export default class Meetings extends WebexPlugin {
492
679
  }
493
680
 
494
681
  /**
495
- * API to toggle starting adhoc meeting
496
- * @param {Boolean} changeState
497
- * @private
498
- * @memberof Meetings
499
- * @returns {undefined}
500
- */
682
+ * API to toggle starting adhoc meeting
683
+ * @param {Boolean} changeState
684
+ * @private
685
+ * @memberof Meetings
686
+ * @returns {undefined}
687
+ */
501
688
  private _toggleAdhocMeetings(changeState: boolean) {
502
689
  if (typeof changeState !== 'boolean') {
503
690
  return;
@@ -510,24 +697,27 @@ export default class Meetings extends WebexPlugin {
510
697
  }
511
698
 
512
699
  /**
513
- * Explicitly sets up the meetings plugin by registering
514
- * the device, connecting to mercury, and listening for locus events.
515
- *
516
- * @returns {Promise}
517
- * @public
518
- * @memberof Meetings
519
- */
700
+ * Explicitly sets up the meetings plugin by registering
701
+ * the device, connecting to mercury, and listening for locus events.
702
+ *
703
+ * @returns {Promise}
704
+ * @public
705
+ * @memberof Meetings
706
+ */
520
707
  public register() {
521
708
  // @ts-ignore
522
709
  if (!this.webex.canAuthorize) {
523
- LoggerProxy.logger.error('Meetings:index#register --> ERROR, Unable to register, SDK cannot authorize');
710
+ LoggerProxy.logger.error(
711
+ 'Meetings:index#register --> ERROR, Unable to register, SDK cannot authorize'
712
+ );
524
713
 
525
714
  return Promise.reject(new Error('SDK cannot authorize'));
526
715
  }
527
716
 
528
-
529
717
  if (this.registered) {
530
- LoggerProxy.logger.info('Meetings:index#register --> INFO, Meetings plugin already registered');
718
+ LoggerProxy.logger.info(
719
+ 'Meetings:index#register --> INFO, Meetings plugin already registered'
720
+ );
531
721
 
532
722
  return Promise.resolve();
533
723
  }
@@ -539,88 +729,97 @@ export default class Meetings extends WebexPlugin {
539
729
  LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
540
730
  }),
541
731
  // @ts-ignore
542
- this.webex.internal.device.register()
543
- // @ts-ignore
544
- .then(() => LoggerProxy.logger.info(`Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`))
732
+ this.webex.internal.device
733
+ .register()
734
+ // @ts-ignore
735
+ .then(() =>
736
+ LoggerProxy.logger.info(
737
+ // @ts-ignore
738
+ `Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
739
+ )
740
+ )
545
741
  // @ts-ignore
546
742
  .then(() => this.webex.internal.mercury.connect()),
547
- MeetingsUtil.checkH264Support.call(this)
548
- ]).then(() => {
549
- this.listenForEvents();
550
- Trigger.trigger(
551
- this,
552
- {
553
- file: 'meetings',
554
- function: 'register'
555
- },
556
- EVENT_TRIGGERS.MEETINGS_REGISTERED
557
- );
558
- this.registered = true;
559
- Metrics.sendBehavioralMetric(
560
- BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_SUCCESS,
561
- );
562
- })
563
- .catch((error) => {
564
- LoggerProxy.logger.error(`Meetings:index#register --> ERROR, Unable to register, ${error.message}`);
565
-
566
- Metrics.sendBehavioralMetric(
567
- BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_FAILED,
743
+ MeetingsUtil.checkH264Support.call(this),
744
+ ])
745
+ .then(() => {
746
+ this.listenForEvents();
747
+ Trigger.trigger(
748
+ this,
568
749
  {
569
- reason: error.message,
570
- stack: error.stack
571
- }
750
+ file: 'meetings',
751
+ function: 'register',
752
+ },
753
+ EVENT_TRIGGERS.MEETINGS_REGISTERED
754
+ );
755
+ this.registered = true;
756
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_SUCCESS);
757
+ })
758
+ .catch((error) => {
759
+ LoggerProxy.logger.error(
760
+ `Meetings:index#register --> ERROR, Unable to register, ${error.message}`
572
761
  );
573
762
 
763
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_FAILED, {
764
+ reason: error.message,
765
+ stack: error.stack,
766
+ });
767
+
574
768
  return Promise.reject(error);
575
769
  });
576
770
  }
577
771
 
578
772
  /**
579
- * Explicitly tears down the meetings plugin by deregistering
580
- * the device, disconnecting from mercury, and stops listening to locus events
581
- *
582
- * @returns {Promise}
583
- * @public
584
- * @memberof Meetings
585
- */
773
+ * Explicitly tears down the meetings plugin by deregistering
774
+ * the device, disconnecting from mercury, and stops listening to locus events
775
+ *
776
+ * @returns {Promise}
777
+ * @public
778
+ * @memberof Meetings
779
+ */
586
780
  unregister() {
587
781
  if (!this.registered) {
588
- LoggerProxy.logger.info('Meetings:index#unregister --> INFO, Meetings plugin already unregistered');
782
+ LoggerProxy.logger.info(
783
+ 'Meetings:index#unregister --> INFO, Meetings plugin already unregistered'
784
+ );
589
785
 
590
786
  return Promise.resolve();
591
787
  }
592
788
 
593
789
  this.stopListeningForEvents();
594
790
 
595
- // @ts-ignore
596
- return this.webex.internal.mercury.disconnect()
597
- // @ts-ignore
598
- .then(() => this.webex.internal.device.unregister())
599
- .then(() => {
600
- Trigger.trigger(
601
- this,
602
- {
603
- file: 'meetings',
604
- function: 'unregister'
605
- },
606
- EVENT_TRIGGERS.MEETINGS_UNREGISTERED
607
- );
608
- this.registered = false;
609
- });
791
+ return (
792
+ // @ts-ignore
793
+ this.webex.internal.mercury
794
+ .disconnect()
795
+ // @ts-ignore
796
+ .then(() => this.webex.internal.device.unregister())
797
+ .then(() => {
798
+ Trigger.trigger(
799
+ this,
800
+ {
801
+ file: 'meetings',
802
+ function: 'unregister',
803
+ },
804
+ EVENT_TRIGGERS.MEETINGS_UNREGISTERED
805
+ );
806
+ this.registered = false;
807
+ })
808
+ );
610
809
  }
611
810
 
612
811
  /**
613
- * Uploads logs to the webex services for tracking
614
- * @param {Object} [options={}]
615
- * @param {String} [options.callStart] Call Start Time
616
- * @param {String} [options.feedbackId] ID used for tracking
617
- * @param {String} [options.locusId]
618
- * @param {String} [options.correlationId]
619
- * @param {String} [options.meetingId] webex meeting ID
620
- * @param {String} [options.userId] userId
621
- * @param {String} [options.orgId] org id
622
- * @returns {String} feedback ID logs were submitted under
623
- */
812
+ * Uploads logs to the webex services for tracking
813
+ * @param {Object} [options={}]
814
+ * @param {String} [options.callStart] Call Start Time
815
+ * @param {String} [options.feedbackId] ID used for tracking
816
+ * @param {String} [options.locusId]
817
+ * @param {String} [options.correlationId]
818
+ * @param {String} [options.meetingId] webex meeting ID
819
+ * @param {String} [options.userId] userId
820
+ * @param {String} [options.orgId] org id
821
+ * @returns {String} feedback ID logs were submitted under
822
+ */
624
823
  uploadLogs(
625
824
  options: {
626
825
  callStart?: string;
@@ -634,79 +833,83 @@ export default class Meetings extends WebexPlugin {
634
833
  ) {
635
834
  LoggerProxy.logger.info('Meetings:index#uploadLogs --> uploading logs');
636
835
 
637
- return this.loggerRequest.uploadLogs(options)
836
+ return this.loggerRequest
837
+ .uploadLogs(options)
638
838
  .then((uploadResult) => {
639
- LoggerProxy.logger.info('Meetings:index#uploadLogs --> Upload logs for meeting completed.', uploadResult);
839
+ LoggerProxy.logger.info(
840
+ 'Meetings:index#uploadLogs --> Upload logs for meeting completed.',
841
+ uploadResult
842
+ );
640
843
  Trigger.trigger(
641
844
  this,
642
845
  {
643
846
  file: 'meetings',
644
- function: 'uploadLogs'
847
+ function: 'uploadLogs',
645
848
  },
646
849
  EVENT_TRIGGERS.MEETING_LOG_UPLOAD_SUCCESS,
647
850
  {
648
851
  meetingId: options.meetingId,
649
- details: uploadResult
852
+ details: uploadResult,
650
853
  }
651
854
  );
652
855
 
653
856
  return uploadResult;
654
857
  })
655
858
  .catch((uploadError) => {
656
- LoggerProxy.logger.error('Meetings:index#uploadLogs --> Unable to upload logs for meeting', uploadError);
859
+ LoggerProxy.logger.error(
860
+ 'Meetings:index#uploadLogs --> Unable to upload logs for meeting',
861
+ uploadError
862
+ );
657
863
  Trigger.trigger(
658
864
  this,
659
865
  {
660
866
  file: 'meetings',
661
- function: 'uploadLogs'
867
+ function: 'uploadLogs',
662
868
  },
663
869
  EVENT_TRIGGERS.MEETING_LOG_UPLOAD_FAILURE,
664
870
  {
665
871
  meetingId: options.meetingId,
666
- reason: uploadError
872
+ reason: uploadError,
667
873
  }
668
874
  );
669
875
 
670
- Metrics.sendBehavioralMetric(
671
- BEHAVIORAL_METRICS.UPLOAD_LOGS_FAILURE,
672
- {
673
- // @ts-ignore - seems like typo
674
- meetingId: options.meetingsId,
675
- reason: uploadError.message,
676
- stack: uploadError.stack,
677
- code: uploadError.code
678
- }
679
- );
876
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_FAILURE, {
877
+ // @ts-ignore - seems like typo
878
+ meetingId: options.meetingsId,
879
+ reason: uploadError.message,
880
+ stack: uploadError.stack,
881
+ code: uploadError.code,
882
+ });
680
883
  });
681
884
  }
682
885
 
683
886
  /**
684
- * initializes the reachability instance for Meetings
685
- * @returns {undefined}
686
- * @public
687
- * @memberof Meetings
688
- */
887
+ * initializes the reachability instance for Meetings
888
+ * @returns {undefined}
889
+ * @public
890
+ * @memberof Meetings
891
+ */
689
892
  setReachability() {
690
893
  // @ts-ignore
691
894
  this.reachability = new Reachability(this.webex);
692
895
  }
693
896
 
694
897
  /**
695
- * gets the reachability instance for Meetings
696
- * @returns {Reachability}
697
- * @public
698
- * @memberof Meetings
699
- */
898
+ * gets the reachability instance for Meetings
899
+ * @returns {Reachability}
900
+ * @public
901
+ * @memberof Meetings
902
+ */
700
903
  getReachability() {
701
904
  return this.reachability;
702
905
  }
703
906
 
704
907
  /**
705
- * initializes and starts gathering reachability for Meetings
706
- * @returns {Promise}
707
- * @public
708
- * @memberof Meetings
709
- */
908
+ * initializes and starts gathering reachability for Meetings
909
+ * @returns {Promise}
910
+ * @public
911
+ * @memberof Meetings
912
+ */
710
913
  startReachability() {
711
914
  if (!this.reachability) {
712
915
  this.setReachability();
@@ -716,11 +919,11 @@ export default class Meetings extends WebexPlugin {
716
919
  }
717
920
 
718
921
  /**
719
- * Get geoHint for info for meetings
720
- * @returns {Promise}
721
- * @private
722
- * @memberof Meetings
723
- */
922
+ * Get geoHint for info for meetings
923
+ * @returns {Promise}
924
+ * @private
925
+ * @memberof Meetings
926
+ */
724
927
  getGeoHint() {
725
928
  return this.request.fetchGeoHint().then((res) => {
726
929
  this.geoHintInfo = res;
@@ -728,39 +931,62 @@ export default class Meetings extends WebexPlugin {
728
931
  }
729
932
 
730
933
  /**
731
- * Fetch user preferred webex site information
732
- * This also has other infomation about the user
733
- * @returns {Promise}
734
- * @private
735
- * @memberof Meetings
736
- */
934
+ * Fetch user preferred webex site information
935
+ * This also has other infomation about the user
936
+ * @returns {Promise}
937
+ * @private
938
+ * @memberof Meetings
939
+ */
737
940
  fetchUserPreferredWebexSite() {
738
941
  return this.request.getMeetingPreferences().then((res) => {
739
942
  if (res) {
740
943
  this.preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
741
944
  }
945
+
946
+ // fall back to getting the preferred site from the user information
947
+ if (!this.preferredWebexSite) {
948
+ // @ts-ignore
949
+ return this.webex.internal.user
950
+ .get()
951
+ .then((user) => {
952
+ const preferredWebexSite =
953
+ user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
954
+ if (preferredWebexSite) {
955
+ this.preferredWebexSite = preferredWebexSite;
956
+ } else {
957
+ throw new Error('site not found');
958
+ }
959
+ })
960
+ .catch(() => {
961
+ LoggerProxy.logger.error(
962
+ 'Failed to fetch preferred site from user - no site will be set'
963
+ );
964
+ });
965
+ }
966
+
967
+ return Promise.resolve();
742
968
  });
743
969
  }
744
970
 
745
971
  /**
746
- * gets the personal meeting room instance, for saved PMR values for this user
747
- * @returns {PersonalMeetingRoom}
748
- * @public
749
- * @memberof Meetings
750
- */
972
+ * gets the personal meeting room instance, for saved PMR values for this user
973
+ * @returns {PersonalMeetingRoom}
974
+ * @public
975
+ * @memberof Meetings
976
+ */
751
977
 
752
978
  getPersonalMeetingRoom() {
753
979
  return this.personalMeetingRoom;
754
980
  }
755
981
 
756
982
  /**
757
- * @param {Meeting} meeting
758
- * @param {Object} reason
759
- * @param {String} type
760
- * @returns {Undefined}
761
- * @private
762
- * @memberof Meetings
763
- */
983
+ * @param {Meeting} meeting
984
+ * @param {Object} reason
985
+ * @param {String} type
986
+ * @returns {Undefined}
987
+ * @private
988
+ * @memberof Meetings
989
+ */
764
990
  private destroy(meeting: Meeting, reason: object) {
765
991
  MeetingUtil.cleanUp(meeting);
766
992
  this.meetingCollection.delete(meeting.id);
@@ -768,68 +994,82 @@ export default class Meetings extends WebexPlugin {
768
994
  this,
769
995
  {
770
996
  file: 'meetings',
771
- function: 'destroy'
997
+ function: 'destroy',
772
998
  },
773
999
  EVENT_TRIGGERS.MEETING_REMOVED,
774
1000
  {
775
1001
  meetingId: meeting.id,
776
- reason
1002
+ reason,
777
1003
  }
778
1004
  );
779
1005
  }
780
1006
 
781
1007
  /**
782
- * Create a meeting.
783
- * @param {string} destination - sipURL, spaceId, phonenumber, or locus object}
784
- * @param {string} [type] - the optional specified type, such as locusId
785
- * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
786
- * @returns {Promise<Meeting>} A new Meeting.
787
- * @public
788
- * @memberof Meetings
789
- */
790
- public create(destination: string, type: string = null, useRandomDelayForInfo: boolean = false) {
1008
+ * Create a meeting.
1009
+ * @param {string} destination - sipURL, spaceId, phonenumber, or locus object}
1010
+ * @param {string} [type] - the optional specified type, such as locusId
1011
+ * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
1012
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1013
+ * @returns {Promise<Meeting>} A new Meeting.
1014
+ * @public
1015
+ * @memberof Meetings
1016
+ */
1017
+ public create(
1018
+ destination: string,
1019
+ type: string = null,
1020
+ useRandomDelayForInfo = false,
1021
+ infoExtraParams = {}
1022
+ ) {
791
1023
  // TODO: type should be from a dictionary
792
1024
 
793
1025
  // Validate meeting information based on the provided destination and
794
1026
  // type. This must be performed prior to determining if the meeting is
795
1027
  // found in the collection, as we mutate the destination for hydra person
796
1028
  // id values.
797
- return this.meetingInfo.fetchInfoOptions(destination, type)
798
- // Catch a failure to fetch info options.
799
- .catch((error) => {
800
- LoggerProxy.logger.info(`Meetings:index#create --> INFO, unable to determine info options: ${error.message}`);
801
- })
802
- .then((options: any = {}) => {
803
- // Normalize the destination.
804
- const targetDest = options.destination || destination;
805
-
806
- // check for the conversation URL then sip Url
807
- let meeting = null;
808
-
809
- if (type === _CONVERSATION_URL_ || options.type === _CONVERSATION_URL_) {
810
- const foundMeeting = this.meetingCollection.getByKey(CONVERSATION_URL, targetDest);
811
-
812
- if (foundMeeting) {
813
- const foundMeetingIsNotCalendarMeeting = !foundMeeting.locusInfo.scheduledMeeting;
814
-
815
- // If the found meeting is not a calendar meeting, return that meeting.
816
- // This allows for the creation of instant-meetings when calendar meetings are present.
817
- if (foundMeetingIsNotCalendarMeeting) {
818
- meeting = foundMeeting;
1029
+ return (
1030
+ this.meetingInfo
1031
+ .fetchInfoOptions(destination, type)
1032
+ // Catch a failure to fetch info options.
1033
+ .catch((error) => {
1034
+ LoggerProxy.logger.info(
1035
+ `Meetings:index#create --> INFO, unable to determine info options: ${error.message}`
1036
+ );
1037
+ })
1038
+ .then((options: any = {}) => {
1039
+ // Normalize the destination.
1040
+ const targetDest = options.destination || destination;
1041
+
1042
+ // check for the conversation URL then sip Url
1043
+ let meeting = null;
1044
+
1045
+ if (type === _CONVERSATION_URL_ || options.type === _CONVERSATION_URL_) {
1046
+ const foundMeeting = this.meetingCollection.getByKey(CONVERSATION_URL, targetDest);
1047
+
1048
+ if (foundMeeting) {
1049
+ const foundMeetingIsNotCalendarMeeting = !foundMeeting.locusInfo.scheduledMeeting;
1050
+
1051
+ // If the found meeting is not a calendar meeting, return that meeting.
1052
+ // This allows for the creation of instant-meetings when calendar meetings are present.
1053
+ if (foundMeetingIsNotCalendarMeeting) {
1054
+ meeting = foundMeeting;
1055
+ }
819
1056
  }
820
1057
  }
821
- }
822
1058
 
823
- // Attempt to collect the meeting if it exists.
824
- if (!meeting) {
825
- meeting = this.meetingCollection.getByKey(SIP_URI, targetDest);
826
- }
1059
+ // Attempt to collect the meeting if it exists.
1060
+ if (!meeting) {
1061
+ meeting = this.meetingCollection.getByKey(SIP_URI, targetDest);
1062
+ }
827
1063
 
828
- // Validate if a meeting was found.
829
- if (!meeting) {
830
- // Create a meeting based on the normalized destination and type.
831
- return this.createMeeting(targetDest, type, useRandomDelayForInfo)
832
- .then((createdMeeting: any) => {
1064
+ // Validate if a meeting was found.
1065
+ if (!meeting) {
1066
+ // Create a meeting based on the normalized destination and type.
1067
+ return this.createMeeting(
1068
+ targetDest,
1069
+ type,
1070
+ useRandomDelayForInfo,
1071
+ infoExtraParams
1072
+ ).then((createdMeeting: any) => {
833
1073
  // If the meeting was successfully created.
834
1074
  if (createdMeeting && createdMeeting.on) {
835
1075
  // Create a destruction event for the meeting.
@@ -841,10 +1081,9 @@ export default class Meetings extends WebexPlugin {
841
1081
  correlationId: createdMeeting.correlationId,
842
1082
  feedbackId: createdMeeting.correlationId,
843
1083
  locusId: createdMeeting.locusId,
844
- meetingId: createdMeeting.locusInfo?.info?.webExMeetingId
1084
+ meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
845
1085
  }).then(() => this.destroy(createdMeeting, payload.reason));
846
- }
847
- else {
1086
+ } else {
848
1087
  this.destroy(createdMeeting, payload.reason);
849
1088
  }
850
1089
  });
@@ -857,34 +1096,42 @@ export default class Meetings extends WebexPlugin {
857
1096
  correlationId: meetingInstance.correlationId,
858
1097
  feedbackId: meetingInstance.correlationId,
859
1098
  locusId: meetingInstance.locusId,
860
- meetingId: meetingInstance.locusInfo?.info?.webExMeetingId
1099
+ meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
861
1100
  });
862
1101
  }
863
1102
  });
864
- }
865
- else {
866
- LoggerProxy.logger.error(`Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`);
1103
+ } else {
1104
+ LoggerProxy.logger.error(
1105
+ `Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
1106
+ );
867
1107
  }
868
1108
 
869
1109
  // Return the newly created meeting.
870
1110
  return Promise.resolve(createdMeeting);
871
1111
  });
872
- }
1112
+ }
873
1113
 
874
- // Return the existing meeting.
875
- return Promise.resolve(meeting);
876
- });
1114
+ // Return the existing meeting.
1115
+ return Promise.resolve(meeting);
1116
+ })
1117
+ );
877
1118
  }
878
1119
 
879
1120
  /**
880
- * @param {String} destination see create()
881
- * @param {String} type see create()
882
- * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
883
- * @returns {Promise} a new meeting instance complete with meeting info and destination
884
- * @private
885
- * @memberof Meetings
886
- */
887
- private async createMeeting(destination: any, type: string = null, useRandomDelayForInfo: boolean = false) {
1121
+ * @param {String} destination see create()
1122
+ * @param {String} type see create()
1123
+ * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
1124
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1125
+ * @returns {Promise} a new meeting instance complete with meeting info and destination
1126
+ * @private
1127
+ * @memberof Meetings
1128
+ */
1129
+ private async createMeeting(
1130
+ destination: any,
1131
+ type: string = null,
1132
+ useRandomDelayForInfo = false,
1133
+ infoExtraParams = {}
1134
+ ) {
888
1135
  const meeting = new Meeting(
889
1136
  {
890
1137
  // @ts-ignore
@@ -900,7 +1147,7 @@ export default class Meetings extends WebexPlugin {
900
1147
  },
901
1148
  {
902
1149
  // @ts-ignore
903
- parent: this.webex
1150
+ parent: this.webex,
904
1151
  }
905
1152
  );
906
1153
 
@@ -918,7 +1165,10 @@ export default class Meetings extends WebexPlugin {
918
1165
  const startTimeDate = new Date(startTime);
919
1166
  const startTimeDatestamp = startTimeDate.getTime();
920
1167
  const timeToStart = startTimeDatestamp - Date.now();
921
- const maxWaitingTime = Math.max(Math.min(timeToStart, MAX_RANDOM_DELAY_FOR_MEETING_INFO), 0);
1168
+ const maxWaitingTime = Math.max(
1169
+ Math.min(timeToStart, MAX_RANDOM_DELAY_FOR_MEETING_INFO),
1170
+ 0
1171
+ );
922
1172
 
923
1173
  waitingTime = Math.round(Math.random() * maxWaitingTime);
924
1174
  }
@@ -927,22 +1177,32 @@ export default class Meetings extends WebexPlugin {
927
1177
  const {enableUnifiedMeetings} = this.config.experimental;
928
1178
 
929
1179
  if (enableUnifiedMeetings && !isMeetingActive && useRandomDelayForInfo && waitingTime > 0) {
930
- meeting.fetchMeetingInfoTimeoutId = setTimeout(() => meeting.fetchMeetingInfo({}), waitingTime);
1180
+ meeting.fetchMeetingInfoTimeoutId = setTimeout(
1181
+ () => meeting.fetchMeetingInfo({extraParams: infoExtraParams}),
1182
+ waitingTime
1183
+ );
931
1184
  meeting.parseMeetingInfo(undefined, destination);
1185
+ } else {
1186
+ await meeting.fetchMeetingInfo({extraParams: infoExtraParams});
932
1187
  }
933
- else {
934
- await meeting.fetchMeetingInfo({});
935
- }
936
- }
937
- catch (err) {
938
- if (!(err instanceof CaptchaError) && !(err instanceof PasswordError)) {
1188
+ } catch (err) {
1189
+ if (
1190
+ !(err instanceof CaptchaError) &&
1191
+ !(err instanceof PasswordError) &&
1192
+ !(err instanceof PermissionError)
1193
+ ) {
939
1194
  // if there is no meeting info we assume its a 1:1 call or wireless share
940
- LoggerProxy.logger.info(`Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`);
941
- LoggerProxy.logger.info('Meetings:index#createMeeting --> Info assuming this destination is a 1:1 or wireless share');
1195
+ LoggerProxy.logger.info(
1196
+ `Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
1197
+ );
1198
+ LoggerProxy.logger.info(
1199
+ 'Meetings:index#createMeeting --> Info assuming this destination is a 1:1 or wireless share'
1200
+ );
942
1201
  }
943
- LoggerProxy.logger.debug(`Meetings:index#createMeeting --> Debug ${err} fetching /meetingInfo for creation.`);
944
- }
945
- finally {
1202
+ LoggerProxy.logger.debug(
1203
+ `Meetings:index#createMeeting --> Debug ${err} fetching /meetingInfo for creation.`
1204
+ );
1205
+ } finally {
946
1206
  // For type LOCUS_ID we need to parse the locus object to get the information
947
1207
  // about the caller and callee
948
1208
  // Meeting Added event will be created in `handleLocusEvent`
@@ -960,12 +1220,12 @@ export default class Meetings extends WebexPlugin {
960
1220
  this,
961
1221
  {
962
1222
  file: 'meetings',
963
- function: 'createMeeting'
1223
+ function: 'createMeeting',
964
1224
  },
965
1225
  EVENT_TRIGGERS.MEETING_ADDED,
966
1226
  {
967
1227
  meeting,
968
- type: meetingAddedType
1228
+ type: meetingAddedType,
969
1229
  }
970
1230
  );
971
1231
  }
@@ -993,26 +1253,26 @@ export default class Meetings extends WebexPlugin {
993
1253
  }
994
1254
 
995
1255
  /**
996
- * get a specifc meeting given it's type matched to the value, i.e., locus url
997
- * @param {String} type
998
- * @param {Object} value
999
- * @returns {Meeting}
1000
- * @public
1001
- * @memberof Meetings
1002
- */
1256
+ * get a specifc meeting given it's type matched to the value, i.e., locus url
1257
+ * @param {String} type
1258
+ * @param {Object} value
1259
+ * @returns {Meeting}
1260
+ * @public
1261
+ * @memberof Meetings
1262
+ */
1003
1263
  public getMeetingByType(type: string, value: object) {
1004
1264
  return this.meetingCollection.getByKey(type, value);
1005
1265
  }
1006
1266
 
1007
1267
  /**
1008
- * Get all meetings.
1009
- * @param {object} options
1010
- * @param {object} options.startDate - get meetings after this start date
1011
- * @param {object} options.endDate - get meetings before this end date
1012
- * @returns {Object} All currently active meetings.
1013
- * @public
1014
- * @memberof Meetings
1015
- */
1268
+ * Get all meetings.
1269
+ * @param {object} options
1270
+ * @param {object} options.startDate - get meetings after this start date
1271
+ * @param {object} options.endDate - get meetings before this end date
1272
+ * @returns {Object} All currently active meetings.
1273
+ * @public
1274
+ * @memberof Meetings
1275
+ */
1016
1276
  public getAllMeetings(
1017
1277
  options: {
1018
1278
  startDate: object;
@@ -1025,57 +1285,132 @@ export default class Meetings extends WebexPlugin {
1025
1285
  }
1026
1286
 
1027
1287
  /**
1028
- * syncs all the meeting from server
1029
- * @returns {undefined}
1030
- * @public
1031
- * @memberof Meetings
1032
- */
1288
+ * syncs all the meeting from server
1289
+ * @returns {undefined}
1290
+ * @public
1291
+ * @memberof Meetings
1292
+ */
1033
1293
  public syncMeetings() {
1034
- return this.request.getActiveMeetings().then((locusArray) => {
1035
- const activeLocusUrl = [];
1036
-
1037
- if (locusArray?.loci && locusArray.loci.length > 0) {
1038
- locusArray.loci.forEach((locus) => {
1039
- activeLocusUrl.push(locus.url);
1040
- this.handleLocusEvent({
1041
- locus,
1042
- locusUrl: locus.url
1294
+ return this.request
1295
+ .getActiveMeetings()
1296
+ .then((locusArray) => {
1297
+ const activeLocusUrl = [];
1298
+
1299
+ if (locusArray?.loci && locusArray.loci.length > 0) {
1300
+ const lociToUpdate = this.sortLocusArrayToUpdate(locusArray.loci);
1301
+ lociToUpdate.forEach((locus) => {
1302
+ activeLocusUrl.push(locus.url);
1303
+ this.handleLocusEvent({
1304
+ locus,
1305
+ locusUrl: locus.url,
1306
+ });
1043
1307
  });
1044
- });
1045
- }
1046
- const meetingsCollection = this.meetingCollection.getAll();
1047
-
1048
- if (Object.keys(meetingsCollection).length > 0) {
1049
- // Some time the mercury event is missed after mercury reconnect
1050
- // if sync returns no locus then clear all the meetings
1051
- for (const meeting of Object.values(meetingsCollection)) {
1052
- // @ts-ignore
1053
- if (!activeLocusUrl.includes(meeting.locusUrl)) {
1054
- // destroy function also uploads logs
1308
+ }
1309
+ const meetingsCollection = this.meetingCollection.getAll();
1310
+
1311
+ if (Object.keys(meetingsCollection).length > 0) {
1312
+ // Some time the mercury event is missed after mercury reconnect
1313
+ // if sync returns no locus then clear all the meetings
1314
+ for (const meeting of Object.values(meetingsCollection)) {
1055
1315
  // @ts-ignore
1056
- this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1316
+ if (!activeLocusUrl.includes(meeting.locusUrl)) {
1317
+ // destroy function also uploads logs
1318
+ // @ts-ignore
1319
+ this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1320
+ }
1057
1321
  }
1058
1322
  }
1323
+ })
1324
+ .catch((error) => {
1325
+ LoggerProxy.logger.error(
1326
+ `Meetings:index#syncMeetings --> failed to sync meetings, ${error}`
1327
+ );
1328
+ throw new Error(error);
1329
+ });
1330
+ }
1331
+
1332
+ /**
1333
+ * sort out locus array for initial creating
1334
+ * @param {Array} loci original locus array
1335
+ * @returns {undefined}
1336
+ * @public
1337
+ * @memberof Meetings
1338
+ */
1339
+ sortLocusArrayToUpdate(loci: any[]) {
1340
+ const mainLoci = loci.filter((locus) => !MeetingsUtil.isBreakoutLocusDTO(locus));
1341
+ const breakoutLoci = loci.filter((locus) => MeetingsUtil.isValidBreakoutLocus(locus));
1342
+ this.breakoutLocusForHandleLater = [];
1343
+ const lociToUpdate = [...mainLoci];
1344
+ breakoutLoci.forEach((breakoutLocus) => {
1345
+ const associateMainLocus = mainLoci.find(
1346
+ (mainLocus) => mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url
1347
+ );
1348
+ const existCorrespondingMeeting = this.getCorrespondingMeetingByLocus({
1349
+ locus: breakoutLocus,
1350
+ locusUrl: breakoutLocus.url,
1351
+ });
1352
+
1353
+ if (associateMainLocus && !existCorrespondingMeeting) {
1354
+ // if exists both main session and breakout session locus of the same non-exist meeting, handle main locus first,
1355
+ // after meeting create with main locus, then handle the associate breakout locus.
1356
+ // if only handle breakout locus, will miss some date
1357
+ this.breakoutLocusForHandleLater.push(breakoutLocus);
1358
+ } else {
1359
+ lociToUpdate.push(breakoutLocus);
1059
1360
  }
1060
1361
  });
1362
+
1363
+ return lociToUpdate;
1061
1364
  }
1062
1365
 
1063
1366
  /**
1064
- * Get all scheduled meetings.
1065
- * @param {object} options
1066
- * @param {object} options.startDate - get meetings after this start date
1067
- * @param {object} options.endDate - get meetings before this end date
1068
- * @returns {Object} All scheduled meetings.
1069
- * @memberof Meetings
1070
- */
1367
+ * check breakout locus which waiting for main locus's meeting to be created, then handle the breakout locus
1368
+ * @param {Object} newCreatedLocus the locus which just create meeting object of it
1369
+ * @returns {undefined}
1370
+ * @public
1371
+ * @memberof Meetings
1372
+ */
1373
+ checkHandleBreakoutLocus(newCreatedLocus) {
1374
+ if (
1375
+ !newCreatedLocus ||
1376
+ !this.breakoutLocusForHandleLater ||
1377
+ !this.breakoutLocusForHandleLater.length
1378
+ ) {
1379
+ return;
1380
+ }
1381
+ if (MeetingsUtil.isBreakoutLocusDTO(newCreatedLocus)) {
1382
+ return;
1383
+ }
1384
+ const existIndex = this.breakoutLocusForHandleLater.findIndex(
1385
+ (breakoutLocus) =>
1386
+ breakoutLocus.controls?.breakout?.url === newCreatedLocus.controls?.breakout?.url
1387
+ );
1388
+
1389
+ if (existIndex < 0) {
1390
+ return;
1391
+ }
1392
+
1393
+ const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
1394
+ this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
1395
+ this.breakoutLocusForHandleLater.splice(existIndex, 1);
1396
+ }
1397
+
1398
+ /**
1399
+ * Get all scheduled meetings.
1400
+ * @param {object} options
1401
+ * @param {object} options.startDate - get meetings after this start date
1402
+ * @param {object} options.endDate - get meetings before this end date
1403
+ * @returns {Object} All scheduled meetings.
1404
+ * @memberof Meetings
1405
+ */
1071
1406
  getScheduledMeetings() {
1072
1407
  return this.meetingCollection.getAll({scheduled: true});
1073
1408
  }
1074
1409
 
1075
1410
  /**
1076
- * Get the logger instance for plugin-meetings
1077
- * @returns {Logger}
1078
- */
1411
+ * Get the logger instance for plugin-meetings
1412
+ * @returns {Logger}
1413
+ */
1079
1414
  getLogger() {
1080
1415
  return LoggerProxy.get();
1081
1416
  }