@webex/plugin-meetings 3.0.0-beta.14 → 3.0.0-beta.140

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