@webex/plugin-meetings 2.60.0 → 2.60.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (535) hide show
  1. package/README.md +46 -8
  2. package/dist/annotation/annotation.types.d.ts +42 -0
  3. package/dist/annotation/annotation.types.js +7 -0
  4. package/dist/annotation/annotation.types.js.map +1 -0
  5. package/dist/annotation/constants.d.ts +31 -0
  6. package/dist/annotation/constants.js +41 -0
  7. package/dist/annotation/constants.js.map +1 -0
  8. package/dist/annotation/index.d.ts +117 -0
  9. package/dist/annotation/index.js +357 -0
  10. package/dist/annotation/index.js.map +1 -0
  11. package/dist/breakouts/breakout.d.ts +8 -0
  12. package/dist/breakouts/breakout.js +215 -0
  13. package/dist/breakouts/breakout.js.map +1 -0
  14. package/dist/breakouts/collection.d.ts +5 -0
  15. package/dist/breakouts/collection.js +22 -0
  16. package/dist/breakouts/collection.js.map +1 -0
  17. package/dist/breakouts/edit-lock-error.d.ts +15 -0
  18. package/dist/breakouts/edit-lock-error.js +51 -0
  19. package/dist/breakouts/edit-lock-error.js.map +1 -0
  20. package/dist/breakouts/events.d.ts +8 -0
  21. package/dist/breakouts/events.js +44 -0
  22. package/dist/breakouts/events.js.map +1 -0
  23. package/dist/breakouts/index.d.ts +5 -0
  24. package/dist/breakouts/index.js +1047 -0
  25. package/dist/breakouts/index.js.map +1 -0
  26. package/dist/breakouts/request.d.ts +22 -0
  27. package/dist/breakouts/request.js +77 -0
  28. package/dist/breakouts/request.js.map +1 -0
  29. package/dist/breakouts/utils.d.ts +15 -0
  30. package/dist/breakouts/utils.js +64 -0
  31. package/dist/breakouts/utils.js.map +1 -0
  32. package/dist/common/browser-detection.js +2 -3
  33. package/dist/common/browser-detection.js.map +1 -1
  34. package/dist/common/collection.js +3 -4
  35. package/dist/common/collection.js.map +1 -1
  36. package/dist/common/config.js +1 -2
  37. package/dist/common/config.js.map +1 -1
  38. package/dist/common/errors/captcha-error.js +1 -2
  39. package/dist/common/errors/captcha-error.js.map +1 -1
  40. package/dist/common/errors/intent-to-join.js +1 -2
  41. package/dist/common/errors/intent-to-join.js.map +1 -1
  42. package/dist/common/errors/join-meeting.js +1 -2
  43. package/dist/common/errors/join-meeting.js.map +1 -1
  44. package/dist/common/errors/media.js +1 -2
  45. package/dist/common/errors/media.js.map +1 -1
  46. package/dist/common/errors/no-meeting-info.d.ts +14 -0
  47. package/dist/common/errors/no-meeting-info.js +50 -0
  48. package/dist/common/errors/no-meeting-info.js.map +1 -0
  49. package/dist/common/errors/parameter.js +3 -4
  50. package/dist/common/errors/parameter.js.map +1 -1
  51. package/dist/common/errors/password-error.js +1 -2
  52. package/dist/common/errors/password-error.js.map +1 -1
  53. package/dist/common/errors/permission.js +1 -2
  54. package/dist/common/errors/permission.js.map +1 -1
  55. package/dist/common/errors/{reclaim-host-role-error.js → reclaim-host-role-errors.js} +7 -11
  56. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  57. package/dist/common/errors/reconnection-in-progress.js +1 -2
  58. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  59. package/dist/common/errors/reconnection.js +1 -2
  60. package/dist/common/errors/reconnection.js.map +1 -1
  61. package/dist/common/errors/stats.js +1 -2
  62. package/dist/common/errors/stats.js.map +1 -1
  63. package/dist/common/errors/webex-errors.d.ts +20 -8
  64. package/dist/common/errors/webex-errors.js +48 -28
  65. package/dist/common/errors/webex-errors.js.map +1 -1
  66. package/dist/common/errors/webex-meetings-error.js +1 -2
  67. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  68. package/dist/common/events/events-scope.js +1 -2
  69. package/dist/common/events/events-scope.js.map +1 -1
  70. package/dist/common/events/events.js +1 -2
  71. package/dist/common/events/events.js.map +1 -1
  72. package/dist/common/events/trigger-proxy.js +1 -2
  73. package/dist/common/events/trigger-proxy.js.map +1 -1
  74. package/dist/common/events/util.js +1 -2
  75. package/dist/common/events/util.js.map +1 -1
  76. package/dist/common/logs/logger-config.js +1 -2
  77. package/dist/common/logs/logger-config.js.map +1 -1
  78. package/dist/common/logs/logger-proxy.js +2 -3
  79. package/dist/common/logs/logger-proxy.js.map +1 -1
  80. package/dist/common/logs/request.d.ts +3 -1
  81. package/dist/common/logs/request.js +8 -5
  82. package/dist/common/logs/request.js.map +1 -1
  83. package/dist/common/queue.d.ts +9 -7
  84. package/dist/common/queue.js +22 -9
  85. package/dist/common/queue.js.map +1 -1
  86. package/dist/config.d.ts +6 -7
  87. package/dist/config.js +8 -10
  88. package/dist/config.js.map +1 -1
  89. package/dist/constants.d.ts +217 -97
  90. package/dist/constants.js +416 -441
  91. package/dist/constants.js.map +1 -1
  92. package/dist/controls-options-manager/constants.js +3 -6
  93. package/dist/controls-options-manager/constants.js.map +1 -1
  94. package/dist/controls-options-manager/enums.d.ts +11 -1
  95. package/dist/controls-options-manager/enums.js +15 -6
  96. package/dist/controls-options-manager/enums.js.map +1 -1
  97. package/dist/controls-options-manager/index.d.ts +17 -1
  98. package/dist/controls-options-manager/index.js +127 -38
  99. package/dist/controls-options-manager/index.js.map +1 -1
  100. package/dist/controls-options-manager/types.d.ts +43 -0
  101. package/dist/controls-options-manager/types.js +7 -0
  102. package/dist/controls-options-manager/types.js.map +1 -0
  103. package/dist/controls-options-manager/util.d.ts +1 -7
  104. package/dist/controls-options-manager/util.js +309 -19
  105. package/dist/controls-options-manager/util.js.map +1 -1
  106. package/dist/index.d.ts +6 -3
  107. package/dist/index.js +121 -5
  108. package/dist/index.js.map +1 -1
  109. package/dist/interceptors/index.d.ts +2 -0
  110. package/dist/interceptors/index.js +15 -0
  111. package/dist/interceptors/index.js.map +1 -0
  112. package/dist/interceptors/locusRetry.d.ts +27 -0
  113. package/dist/interceptors/locusRetry.js +94 -0
  114. package/dist/interceptors/locusRetry.js.map +1 -0
  115. package/dist/interpretation/collection.d.ts +5 -0
  116. package/dist/interpretation/collection.js +22 -0
  117. package/dist/interpretation/collection.js.map +1 -0
  118. package/dist/interpretation/index.d.ts +5 -0
  119. package/dist/interpretation/index.js +365 -0
  120. package/dist/interpretation/index.js.map +1 -0
  121. package/dist/interpretation/siLanguage.d.ts +5 -0
  122. package/dist/interpretation/siLanguage.js +24 -0
  123. package/dist/interpretation/siLanguage.js.map +1 -0
  124. package/dist/locus-info/controlsUtils.js +100 -11
  125. package/dist/locus-info/controlsUtils.js.map +1 -1
  126. package/dist/locus-info/embeddedAppsUtils.js +3 -4
  127. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  128. package/dist/locus-info/fullState.js +1 -2
  129. package/dist/locus-info/fullState.js.map +1 -1
  130. package/dist/locus-info/hostUtils.js +1 -2
  131. package/dist/locus-info/hostUtils.js.map +1 -1
  132. package/dist/locus-info/index.d.ts +57 -4
  133. package/dist/locus-info/index.js +425 -84
  134. package/dist/locus-info/index.js.map +1 -1
  135. package/dist/locus-info/infoUtils.js +13 -5
  136. package/dist/locus-info/infoUtils.js.map +1 -1
  137. package/dist/locus-info/mediaSharesUtils.js +58 -3
  138. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  139. package/dist/locus-info/parser.d.ts +66 -6
  140. package/dist/locus-info/parser.js +253 -80
  141. package/dist/locus-info/parser.js.map +1 -1
  142. package/dist/locus-info/selfUtils.js +97 -13
  143. package/dist/locus-info/selfUtils.js.map +1 -1
  144. package/dist/media/index.d.ts +2 -0
  145. package/dist/media/index.js +107 -319
  146. package/dist/media/index.js.map +1 -1
  147. package/dist/media/properties.d.ts +38 -53
  148. package/dist/media/properties.js +96 -153
  149. package/dist/media/properties.js.map +1 -1
  150. package/dist/media/util.js +1 -22
  151. package/dist/media/util.js.map +1 -1
  152. package/dist/mediaQualityMetrics/config.d.ts +234 -230
  153. package/dist/mediaQualityMetrics/config.js +302 -498
  154. package/dist/mediaQualityMetrics/config.js.map +1 -1
  155. package/dist/meeting/in-meeting-actions.d.ts +88 -0
  156. package/dist/meeting/in-meeting-actions.js +94 -3
  157. package/dist/meeting/in-meeting-actions.js.map +1 -1
  158. package/dist/meeting/index.d.ts +591 -494
  159. package/dist/meeting/index.js +4732 -2990
  160. package/dist/meeting/index.js.map +1 -1
  161. package/dist/meeting/locusMediaRequest.d.ts +74 -0
  162. package/dist/meeting/locusMediaRequest.js +291 -0
  163. package/dist/meeting/locusMediaRequest.js.map +1 -0
  164. package/dist/meeting/muteState.d.ts +93 -25
  165. package/dist/meeting/muteState.js +224 -133
  166. package/dist/meeting/muteState.js.map +1 -1
  167. package/dist/meeting/request.d.ts +82 -47
  168. package/dist/meeting/request.js +297 -199
  169. package/dist/meeting/request.js.map +1 -1
  170. package/dist/meeting/request.type.d.ts +11 -0
  171. package/dist/meeting/request.type.js +7 -0
  172. package/dist/meeting/request.type.js.map +1 -0
  173. package/dist/meeting/state.js +1 -2
  174. package/dist/meeting/state.js.map +1 -1
  175. package/dist/meeting/util.d.ts +102 -1
  176. package/dist/meeting/util.js +605 -435
  177. package/dist/meeting/util.js.map +1 -1
  178. package/dist/meeting-info/collection.js +3 -4
  179. package/dist/meeting-info/collection.js.map +1 -1
  180. package/dist/meeting-info/index.d.ts +13 -1
  181. package/dist/meeting-info/index.js +74 -7
  182. package/dist/meeting-info/index.js.map +1 -1
  183. package/dist/meeting-info/meeting-info-v2.d.ts +31 -1
  184. package/dist/meeting-info/meeting-info-v2.js +200 -63
  185. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  186. package/dist/meeting-info/request.js +1 -2
  187. package/dist/meeting-info/request.js.map +1 -1
  188. package/dist/meeting-info/util.js +2 -3
  189. package/dist/meeting-info/util.js.map +1 -1
  190. package/dist/meeting-info/utilv2.js +39 -41
  191. package/dist/meeting-info/utilv2.js.map +1 -1
  192. package/dist/meetings/collection.d.ts +17 -0
  193. package/dist/meetings/collection.js +42 -4
  194. package/dist/meetings/collection.js.map +1 -1
  195. package/dist/meetings/index.d.ts +93 -21
  196. package/dist/meetings/index.js +490 -127
  197. package/dist/meetings/index.js.map +1 -1
  198. package/dist/meetings/meetings.types.d.ts +4 -0
  199. package/dist/meetings/meetings.types.js +7 -0
  200. package/dist/meetings/meetings.types.js.map +1 -0
  201. package/dist/meetings/request.js +4 -3
  202. package/dist/meetings/request.js.map +1 -1
  203. package/dist/meetings/util.js +107 -6
  204. package/dist/meetings/util.js.map +1 -1
  205. package/dist/member/index.d.ts +13 -1
  206. package/dist/member/index.js +45 -2
  207. package/dist/member/index.js.map +1 -1
  208. package/dist/member/member.types.js +3 -4
  209. package/dist/member/member.types.js.map +1 -1
  210. package/dist/member/types.d.ts +32 -0
  211. package/dist/member/types.js +23 -0
  212. package/dist/member/types.js.map +1 -0
  213. package/dist/member/util.js +120 -29
  214. package/dist/member/util.js.map +1 -1
  215. package/dist/members/collection.d.ts +5 -0
  216. package/dist/members/collection.js +11 -2
  217. package/dist/members/collection.js.map +1 -1
  218. package/dist/members/index.d.ts +56 -11
  219. package/dist/members/index.js +174 -47
  220. package/dist/members/index.js.map +1 -1
  221. package/dist/members/request.d.ts +67 -11
  222. package/dist/members/request.js +102 -54
  223. package/dist/members/request.js.map +1 -1
  224. package/dist/members/types.js +3 -4
  225. package/dist/members/types.js.map +1 -1
  226. package/dist/members/util.d.ts +214 -1
  227. package/dist/members/util.js +327 -284
  228. package/dist/members/util.js.map +1 -1
  229. package/dist/metrics/constants.d.ts +15 -6
  230. package/dist/metrics/constants.js +17 -9
  231. package/dist/metrics/constants.js.map +1 -1
  232. package/dist/metrics/index.d.ts +4 -111
  233. package/dist/metrics/index.js +4 -452
  234. package/dist/metrics/index.js.map +1 -1
  235. package/dist/multistream/mediaRequestManager.d.ts +118 -0
  236. package/dist/multistream/mediaRequestManager.js +344 -0
  237. package/dist/multistream/mediaRequestManager.js.map +1 -0
  238. package/dist/multistream/receiveSlot.d.ts +68 -0
  239. package/dist/multistream/receiveSlot.js +200 -0
  240. package/dist/multistream/receiveSlot.js.map +1 -0
  241. package/dist/multistream/receiveSlotManager.d.ts +56 -0
  242. package/dist/multistream/receiveSlotManager.js +174 -0
  243. package/dist/multistream/receiveSlotManager.js.map +1 -0
  244. package/dist/multistream/remoteMedia.d.ts +72 -0
  245. package/dist/multistream/remoteMedia.js +268 -0
  246. package/dist/multistream/remoteMedia.js.map +1 -0
  247. package/dist/multistream/remoteMediaGroup.d.ts +47 -0
  248. package/dist/multistream/remoteMediaGroup.js +267 -0
  249. package/dist/multistream/remoteMediaGroup.js.map +1 -0
  250. package/dist/multistream/remoteMediaManager.d.ts +285 -0
  251. package/dist/multistream/remoteMediaManager.js +1211 -0
  252. package/dist/multistream/remoteMediaManager.js.map +1 -0
  253. package/dist/multistream/sendSlotManager.d.ts +61 -0
  254. package/dist/multistream/sendSlotManager.js +236 -0
  255. package/dist/multistream/sendSlotManager.js.map +1 -0
  256. package/dist/networkQualityMonitor/index.js +5 -4
  257. package/dist/networkQualityMonitor/index.js.map +1 -1
  258. package/dist/personal-meeting-room/index.js +2 -3
  259. package/dist/personal-meeting-room/index.js.map +1 -1
  260. package/dist/personal-meeting-room/request.js +2 -3
  261. package/dist/personal-meeting-room/request.js.map +1 -1
  262. package/dist/personal-meeting-room/util.js +1 -2
  263. package/dist/personal-meeting-room/util.js.map +1 -1
  264. package/dist/reachability/clusterReachability.d.ts +109 -0
  265. package/dist/reachability/clusterReachability.js +357 -0
  266. package/dist/reachability/clusterReachability.js.map +1 -0
  267. package/dist/reachability/index.d.ts +61 -95
  268. package/dist/reachability/index.js +300 -393
  269. package/dist/reachability/index.js.map +1 -1
  270. package/dist/reachability/request.d.ts +7 -3
  271. package/dist/reachability/request.js +18 -10
  272. package/dist/reachability/request.js.map +1 -1
  273. package/dist/reachability/util.d.ts +8 -0
  274. package/dist/reachability/util.js +29 -0
  275. package/dist/reachability/util.js.map +1 -0
  276. package/dist/reactions/constants.d.ts +3 -0
  277. package/dist/reactions/constants.js +12 -0
  278. package/dist/reactions/constants.js.map +1 -0
  279. package/dist/reactions/reactions.d.ts +2 -2
  280. package/dist/reactions/reactions.js +4 -6
  281. package/dist/reactions/reactions.js.map +1 -1
  282. package/dist/reactions/reactions.type.d.ts +23 -3
  283. package/dist/reactions/reactions.type.js +21 -23
  284. package/dist/reactions/reactions.type.js.map +1 -1
  285. package/dist/reconnection-manager/index.d.ts +32 -8
  286. package/dist/reconnection-manager/index.js +282 -231
  287. package/dist/reconnection-manager/index.js.map +1 -1
  288. package/dist/recording-controller/enums.js +4 -5
  289. package/dist/recording-controller/enums.js.map +1 -1
  290. package/dist/recording-controller/index.d.ts +15 -1
  291. package/dist/recording-controller/index.js +57 -46
  292. package/dist/recording-controller/index.js.map +1 -1
  293. package/dist/recording-controller/util.d.ts +5 -4
  294. package/dist/recording-controller/util.js +10 -10
  295. package/dist/recording-controller/util.js.map +1 -1
  296. package/dist/roap/index.d.ts +9 -47
  297. package/dist/roap/index.js +101 -235
  298. package/dist/roap/index.js.map +1 -1
  299. package/dist/roap/request.d.ts +18 -12
  300. package/dist/roap/request.js +126 -180
  301. package/dist/roap/request.js.map +1 -1
  302. package/dist/roap/turnDiscovery.d.ts +27 -16
  303. package/dist/roap/turnDiscovery.js +115 -105
  304. package/dist/roap/turnDiscovery.js.map +1 -1
  305. package/dist/rtcMetrics/constants.d.ts +4 -0
  306. package/dist/rtcMetrics/constants.js +11 -0
  307. package/dist/rtcMetrics/constants.js.map +1 -0
  308. package/dist/rtcMetrics/index.d.ts +54 -0
  309. package/dist/rtcMetrics/index.js +140 -0
  310. package/dist/rtcMetrics/index.js.map +1 -0
  311. package/dist/statsAnalyzer/global.d.ts +1 -83
  312. package/dist/statsAnalyzer/global.js +2 -85
  313. package/dist/statsAnalyzer/global.js.map +1 -1
  314. package/dist/statsAnalyzer/index.d.ts +50 -30
  315. package/dist/statsAnalyzer/index.js +435 -510
  316. package/dist/statsAnalyzer/index.js.map +1 -1
  317. package/dist/statsAnalyzer/mqaUtil.d.ts +8 -6
  318. package/dist/statsAnalyzer/mqaUtil.js +120 -83
  319. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  320. package/dist/transcription/index.js +1 -2
  321. package/dist/transcription/index.js.map +1 -1
  322. package/dist/webinar/collection.d.ts +16 -0
  323. package/dist/webinar/collection.js +43 -0
  324. package/dist/webinar/collection.js.map +1 -0
  325. package/dist/webinar/index.d.ts +5 -0
  326. package/dist/webinar/index.js +68 -0
  327. package/dist/webinar/index.js.map +1 -0
  328. package/package.json +38 -26
  329. package/src/annotation/annotation.types.ts +50 -0
  330. package/src/annotation/constants.ts +36 -0
  331. package/src/annotation/index.ts +328 -0
  332. package/src/breakouts/README.md +220 -0
  333. package/src/breakouts/breakout.ts +188 -0
  334. package/src/breakouts/collection.ts +19 -0
  335. package/src/breakouts/edit-lock-error.ts +25 -0
  336. package/src/breakouts/events.ts +56 -0
  337. package/src/breakouts/index.ts +925 -0
  338. package/src/breakouts/request.ts +55 -0
  339. package/src/breakouts/utils.ts +57 -0
  340. package/src/common/errors/no-meeting-info.ts +24 -0
  341. package/src/common/errors/webex-errors.ts +36 -12
  342. package/src/common/logs/logger-proxy.ts +1 -1
  343. package/src/common/logs/request.ts +5 -1
  344. package/src/common/queue.ts +22 -8
  345. package/src/config.ts +6 -7
  346. package/src/constants.ts +244 -97
  347. package/src/controls-options-manager/enums.ts +12 -0
  348. package/src/controls-options-manager/index.ts +116 -21
  349. package/src/controls-options-manager/types.ts +59 -0
  350. package/src/controls-options-manager/util.ts +294 -14
  351. package/src/index.ts +44 -0
  352. package/src/interceptors/index.ts +3 -0
  353. package/src/interceptors/locusRetry.ts +67 -0
  354. package/src/interpretation/README.md +60 -0
  355. package/src/interpretation/collection.ts +19 -0
  356. package/src/interpretation/index.ts +332 -0
  357. package/src/interpretation/siLanguage.ts +18 -0
  358. package/src/locus-info/controlsUtils.ts +110 -0
  359. package/src/locus-info/index.ts +449 -61
  360. package/src/locus-info/infoUtils.ts +14 -2
  361. package/src/locus-info/mediaSharesUtils.ts +64 -0
  362. package/src/locus-info/parser.ts +258 -47
  363. package/src/locus-info/selfUtils.ts +85 -2
  364. package/src/media/index.ts +153 -370
  365. package/src/media/properties.ts +106 -136
  366. package/src/media/util.ts +0 -21
  367. package/src/mediaQualityMetrics/config.ts +244 -377
  368. package/src/meeting/in-meeting-actions.ts +176 -0
  369. package/src/meeting/index.ts +3944 -2489
  370. package/src/meeting/locusMediaRequest.ts +313 -0
  371. package/src/meeting/muteState.ts +224 -138
  372. package/src/meeting/request.ts +207 -127
  373. package/src/meeting/request.type.ts +13 -0
  374. package/src/meeting/util.ts +590 -423
  375. package/src/meeting-info/index.ts +81 -8
  376. package/src/meeting-info/meeting-info-v2.ts +163 -13
  377. package/src/meeting-info/util.ts +1 -1
  378. package/src/meeting-info/utilv2.ts +28 -28
  379. package/src/meetings/collection.ts +33 -0
  380. package/src/meetings/index.ts +487 -126
  381. package/src/meetings/meetings.types.ts +12 -0
  382. package/src/meetings/request.ts +2 -0
  383. package/src/meetings/util.ts +116 -5
  384. package/src/member/index.ts +43 -1
  385. package/src/member/types.ts +38 -0
  386. package/src/member/util.ts +125 -28
  387. package/src/members/collection.ts +8 -0
  388. package/src/members/index.ts +187 -52
  389. package/src/members/request.ts +87 -27
  390. package/src/members/util.ts +332 -291
  391. package/src/metrics/constants.ts +15 -6
  392. package/src/metrics/index.ts +1 -471
  393. package/src/multistream/mediaRequestManager.ts +440 -0
  394. package/src/multistream/receiveSlot.ts +184 -0
  395. package/src/multistream/receiveSlotManager.ts +166 -0
  396. package/src/multistream/remoteMedia.ts +254 -0
  397. package/src/multistream/remoteMediaGroup.ts +284 -0
  398. package/src/multistream/remoteMediaManager.ts +1145 -0
  399. package/src/multistream/sendSlotManager.ts +170 -0
  400. package/src/networkQualityMonitor/index.ts +6 -6
  401. package/src/reachability/clusterReachability.ts +320 -0
  402. package/src/reachability/index.ts +243 -347
  403. package/src/reachability/request.ts +17 -8
  404. package/src/reachability/util.ts +24 -0
  405. package/src/reactions/constants.ts +4 -0
  406. package/src/reactions/reactions.ts +4 -4
  407. package/src/reactions/reactions.type.ts +30 -4
  408. package/src/reconnection-manager/index.ts +168 -156
  409. package/src/recording-controller/index.ts +20 -3
  410. package/src/recording-controller/util.ts +26 -9
  411. package/src/roap/index.ts +98 -241
  412. package/src/roap/request.ts +74 -148
  413. package/src/roap/turnDiscovery.ts +62 -56
  414. package/src/rtcMetrics/constants.ts +3 -0
  415. package/src/rtcMetrics/index.ts +124 -0
  416. package/src/statsAnalyzer/global.ts +1 -84
  417. package/src/statsAnalyzer/index.ts +477 -643
  418. package/src/statsAnalyzer/mqaUtil.ts +115 -114
  419. package/src/webinar/collection.ts +31 -0
  420. package/src/webinar/index.ts +62 -0
  421. package/test/integration/spec/converged-space-meetings.js +233 -0
  422. package/test/integration/spec/journey.js +320 -264
  423. package/test/integration/spec/space-meeting.js +77 -4
  424. package/test/unit/spec/annotation/index.ts +418 -0
  425. package/test/unit/spec/breakouts/breakout.ts +237 -0
  426. package/test/unit/spec/breakouts/collection.ts +15 -0
  427. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  428. package/test/unit/spec/breakouts/events.ts +89 -0
  429. package/test/unit/spec/breakouts/index.ts +1790 -0
  430. package/test/unit/spec/breakouts/request.ts +104 -0
  431. package/test/unit/spec/breakouts/utils.js +72 -0
  432. package/test/unit/spec/common/queue.js +31 -2
  433. package/test/unit/spec/controls-options-manager/index.js +163 -0
  434. package/test/unit/spec/controls-options-manager/util.js +576 -60
  435. package/test/unit/spec/fixture/locus.js +1 -0
  436. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  437. package/test/unit/spec/interpretation/collection.ts +15 -0
  438. package/test/unit/spec/interpretation/index.ts +589 -0
  439. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  440. package/test/unit/spec/locus-info/controlsUtils.js +323 -30
  441. package/test/unit/spec/locus-info/index.js +1390 -16
  442. package/test/unit/spec/locus-info/infoUtils.js +54 -16
  443. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  444. package/test/unit/spec/locus-info/lib/selfConstant.js +48 -0
  445. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  446. package/test/unit/spec/locus-info/parser.js +116 -35
  447. package/test/unit/spec/locus-info/selfUtils.js +275 -0
  448. package/test/unit/spec/media/index.ts +290 -0
  449. package/test/unit/spec/media/properties.ts +75 -84
  450. package/test/unit/spec/meeting/in-meeting-actions.ts +86 -0
  451. package/test/unit/spec/meeting/index.js +8187 -2769
  452. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  453. package/test/unit/spec/meeting/muteState.js +409 -213
  454. package/test/unit/spec/meeting/request.js +512 -42
  455. package/test/unit/spec/meeting/utils.js +741 -24
  456. package/test/unit/spec/meeting-info/index.js +300 -0
  457. package/test/unit/spec/meeting-info/meetinginfov2.js +527 -5
  458. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  459. package/test/unit/spec/meetings/collection.js +26 -0
  460. package/test/unit/spec/meetings/index.js +1313 -243
  461. package/test/unit/spec/meetings/utils.js +202 -2
  462. package/test/unit/spec/member/index.js +32 -9
  463. package/test/unit/spec/member/util.js +499 -61
  464. package/test/unit/spec/members/index.js +394 -5
  465. package/test/unit/spec/members/request.js +206 -27
  466. package/test/unit/spec/members/utils.js +173 -38
  467. package/test/unit/spec/metrics/index.js +1 -50
  468. package/test/unit/spec/multistream/mediaRequestManager.ts +1418 -0
  469. package/test/unit/spec/multistream/receiveSlot.ts +163 -0
  470. package/test/unit/spec/multistream/receiveSlotManager.ts +203 -0
  471. package/test/unit/spec/multistream/remoteMedia.ts +255 -0
  472. package/test/unit/spec/multistream/remoteMediaGroup.ts +662 -0
  473. package/test/unit/spec/multistream/remoteMediaManager.ts +1924 -0
  474. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  475. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  476. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  477. package/test/unit/spec/reachability/index.ts +531 -24
  478. package/test/unit/spec/reachability/request.js +68 -0
  479. package/test/unit/spec/reachability/util.ts +40 -0
  480. package/test/unit/spec/reconnection-manager/index.js +162 -24
  481. package/test/unit/spec/recording-controller/index.js +293 -218
  482. package/test/unit/spec/recording-controller/util.js +223 -96
  483. package/test/unit/spec/roap/index.ts +200 -76
  484. package/test/unit/spec/roap/request.ts +255 -0
  485. package/test/unit/spec/roap/turnDiscovery.ts +86 -48
  486. package/test/unit/spec/rtcMetrics/index.ts +93 -0
  487. package/test/unit/spec/stats-analyzer/index.js +261 -167
  488. package/test/unit/spec/webinar/collection.ts +13 -0
  489. package/test/unit/spec/webinar/index.ts +60 -0
  490. package/test/utils/constants.js +9 -0
  491. package/test/utils/integrationTestUtils.js +46 -0
  492. package/test/utils/testUtils.js +0 -45
  493. package/test/utils/webex-config.js +4 -0
  494. package/test/utils/webex-test-users.js +7 -3
  495. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  496. package/dist/meeting/effectsState.d.ts +0 -42
  497. package/dist/meeting/effectsState.js +0 -260
  498. package/dist/meeting/effectsState.js.map +0 -1
  499. package/dist/metrics/config.d.ts +0 -169
  500. package/dist/metrics/config.js +0 -289
  501. package/dist/metrics/config.js.map +0 -1
  502. package/dist/peer-connection-manager/index.d.ts +0 -6
  503. package/dist/peer-connection-manager/index.js +0 -671
  504. package/dist/peer-connection-manager/index.js.map +0 -1
  505. package/dist/peer-connection-manager/util.d.ts +0 -6
  506. package/dist/peer-connection-manager/util.js +0 -110
  507. package/dist/peer-connection-manager/util.js.map +0 -1
  508. package/dist/roap/collection.d.ts +0 -10
  509. package/dist/roap/collection.js +0 -63
  510. package/dist/roap/collection.js.map +0 -1
  511. package/dist/roap/handler.d.ts +0 -47
  512. package/dist/roap/handler.js +0 -279
  513. package/dist/roap/handler.js.map +0 -1
  514. package/dist/roap/state.d.ts +0 -9
  515. package/dist/roap/state.js +0 -127
  516. package/dist/roap/state.js.map +0 -1
  517. package/dist/roap/util.d.ts +0 -2
  518. package/dist/roap/util.js +0 -76
  519. package/dist/roap/util.js.map +0 -1
  520. package/src/index.js +0 -15
  521. package/src/meeting/effectsState.ts +0 -209
  522. package/src/metrics/config.ts +0 -485
  523. package/src/peer-connection-manager/index.ts +0 -847
  524. package/src/peer-connection-manager/util.ts +0 -119
  525. package/src/roap/collection.ts +0 -62
  526. package/src/roap/handler.ts +0 -294
  527. package/src/roap/state.ts +0 -156
  528. package/src/roap/util.ts +0 -100
  529. package/test/unit/spec/meeting/effectsState.js +0 -281
  530. package/test/unit/spec/peerconnection-manager/index.js +0 -218
  531. package/test/unit/spec/peerconnection-manager/utils.js +0 -49
  532. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -388
  533. package/test/unit/spec/roap/util.js +0 -30
  534. /package/dist/common/errors/{reclaim-host-role-error.d.ts → reclaim-host-role-errors.d.ts} +0 -0
  535. /package/src/common/errors/{reclaim-host-role-error.ts → reclaim-host-role-errors.ts} +0 -0
@@ -1,9 +1,7 @@
1
- import {isEmpty} from 'lodash';
1
+ import {LocalCameraStream, LocalMicrophoneStream} from '@webex/media-helpers';
2
2
 
3
+ import {cloneDeep} from 'lodash';
3
4
  import {MeetingNotActiveError, UserNotJoinedError} from '../common/errors/webex-errors';
4
- import Metrics from '../metrics';
5
- import {eventType, trigger} from '../metrics/config';
6
- import Media from '../media';
7
5
  import LoggerProxy from '../common/logs/logger-proxy';
8
6
  import {
9
7
  INTENT_TO_JOIN,
@@ -13,518 +11,687 @@ import {
13
11
  PASSWORD_STATUS,
14
12
  DISPLAY_HINTS,
15
13
  FULL_STATE,
14
+ SELF_POLICY,
15
+ EVENT_TRIGGERS,
16
+ IP_VERSION,
16
17
  } from '../constants';
18
+ import BrowserDetection from '../common/browser-detection';
17
19
  import IntentToJoinError from '../common/errors/intent-to-join';
18
20
  import JoinMeetingError from '../common/errors/join-meeting';
19
21
  import ParameterError from '../common/errors/parameter';
20
22
  import PermissionError from '../common/errors/permission';
21
23
  import PasswordError from '../common/errors/password-error';
22
24
  import CaptchaError from '../common/errors/captcha-error';
25
+ import Trigger from '../common/events/trigger-proxy';
26
+
27
+ const MeetingUtil = {
28
+ parseLocusJoin: (response) => {
29
+ const parsed: any = {};
30
+
31
+ // First todo: add check for existance
32
+ parsed.locus = response.body.locus;
33
+ parsed.mediaConnections = response.body.mediaConnections;
34
+ parsed.locusUrl = parsed.locus.url;
35
+ parsed.locusId = parsed.locus.url.split('/').pop();
36
+ parsed.selfId = parsed.locus.self.id;
37
+
38
+ // we need mediaId before making roap calls
39
+ parsed.mediaConnections.forEach((mediaConnection) => {
40
+ if (mediaConnection.mediaId) {
41
+ parsed.mediaId = mediaConnection.mediaId;
42
+ }
43
+ });
23
44
 
24
- const MeetingUtil: any = {};
25
-
26
- MeetingUtil.parseLocusJoin = (response) => {
27
- const parsed: any = {};
45
+ return parsed;
46
+ },
28
47
 
29
- // First todo: add check for existance
30
- parsed.locus = response.body.locus;
31
- parsed.mediaConnections = response.body.mediaConnections;
32
- parsed.locusUrl = parsed.locus.url;
33
- parsed.locusId = parsed.locus.url.split('/').pop();
34
- parsed.selfId = parsed.locus.self.id;
48
+ remoteUpdateAudioVideo: (meeting, audioMuted?: boolean, videoMuted?: boolean) => {
49
+ const webex = meeting.getWebexObject();
50
+ if (!meeting) {
51
+ return Promise.reject(new ParameterError('You need a meeting object.'));
52
+ }
35
53
 
36
- // we need mediaId before making roap calls
37
- parsed.mediaConnections.forEach((mediaConnection) => {
38
- if (mediaConnection.mediaId) {
39
- parsed.mediaId = mediaConnection.mediaId;
54
+ if (!meeting.locusMediaRequest) {
55
+ return Promise.reject(
56
+ new ParameterError(
57
+ 'You need a meeting with a media connection, call Meeting.addMedia() first.'
58
+ )
59
+ );
40
60
  }
41
- });
42
61
 
43
- return parsed;
44
- };
62
+ // @ts-ignore
63
+ webex.internal.newMetrics.submitClientEvent({
64
+ name: 'client.locus.media.request',
65
+ options: {meetingId: meeting.id},
66
+ });
45
67
 
46
- MeetingUtil.remoteUpdateAudioVideo = (audioMuted, videoMuted, meeting) => {
47
- if (!meeting) {
48
- return Promise.reject(new ParameterError('You need a meeting object.'));
49
- }
50
- const localMedias = Media.generateLocalMedias(meeting.mediaId, audioMuted, videoMuted);
68
+ return meeting.locusMediaRequest
69
+ .send({
70
+ type: 'LocalMute',
71
+ selfUrl: meeting.selfUrl,
72
+ mediaId: meeting.mediaId,
73
+ sequence: meeting.locusInfo.sequence,
74
+ muteOptions: {
75
+ audioMuted,
76
+ videoMuted,
77
+ },
78
+ })
79
+ .then((response) => {
80
+ // @ts-ignore
81
+ webex.internal.newMetrics.submitClientEvent({
82
+ name: 'client.locus.media.response',
83
+ options: {meetingId: meeting.id},
84
+ });
51
85
 
52
- if (isEmpty(localMedias)) {
53
- return Promise.reject(
54
- new ParameterError('You need a media id on the meeting to change remote audio.')
55
- );
56
- }
86
+ return response?.body?.locus;
87
+ });
88
+ },
57
89
 
58
- Metrics.postEvent({event: eventType.MEDIA_REQUEST, meeting});
90
+ hasOwner: (info) => info && info.owner,
59
91
 
60
- return meeting.meetingRequest
61
- .remoteAudioVideoToggle({
62
- locusUrl: meeting.locusUrl,
63
- selfId: meeting.selfId,
64
- localMedias,
65
- deviceUrl: meeting.deviceUrl,
66
- correlationId: meeting.correlationId,
67
- })
68
- .then((response) => {
69
- Metrics.postEvent({event: eventType.MEDIA_RESPONSE, meeting});
92
+ isOwnerSelf: (owner, selfId) => owner === selfId,
70
93
 
71
- return response.body.locus;
72
- });
73
- };
94
+ isPinOrGuest: (err) => err?.body?.errorCode && INTENT_TO_JOIN.includes(err.body.errorCode),
74
95
 
75
- MeetingUtil.hasOwner = (info) => info && info.owner;
96
+ /**
97
+ * Returns the current state of knowledge about whether we are on an ipv4-only or ipv6-only or mixed (ipv4 and ipv6) network.
98
+ * The return value matches the possible values of "ipver" parameter used by the backend APIs.
99
+ *
100
+ * @param {Object} webex webex instance
101
+ * @returns {IP_VERSION|undefined} ipver value to be passed to the backend APIs or undefined if we should not pass any value to the backend
102
+ */
103
+ getIpVersion(webex: any): IP_VERSION | undefined {
104
+ const {supportsIpV4, supportsIpV6} = webex.internal.device.ipNetworkDetector;
76
105
 
77
- MeetingUtil.isOwnerSelf = (owner, selfId) => owner === selfId;
106
+ if (BrowserDetection().isBrowser('firefox')) {
107
+ // our ipv6 solution relies on FQDN ICE candidates, but Firefox doesn't support them,
108
+ // see https://bugzilla.mozilla.org/show_bug.cgi?id=1713128
109
+ // so for Firefox we don't want the backend to activate the "ipv6 feature"
110
+ return undefined;
111
+ }
78
112
 
79
- MeetingUtil.isPinOrGuest = (err) =>
80
- err?.body?.errorCode && INTENT_TO_JOIN.includes(err.body.errorCode);
113
+ if (supportsIpV4 && supportsIpV6) {
114
+ return IP_VERSION.ipv4_and_ipv6;
115
+ }
81
116
 
82
- MeetingUtil.joinMeeting = (meeting, options) => {
83
- if (!meeting) {
84
- return Promise.reject(new ParameterError('You need a meeting object.'));
85
- }
117
+ if (supportsIpV4) {
118
+ return IP_VERSION.only_ipv4;
119
+ }
86
120
 
87
- Metrics.postEvent({event: eventType.LOCUS_JOIN_REQUEST, meeting});
121
+ if (supportsIpV6) {
122
+ return IP_VERSION.only_ipv6;
123
+ }
88
124
 
89
- // eslint-disable-next-line no-warning-comments
90
- // TODO: check if the meeting is in JOINING state
91
- // if Joining state termintate the request as user might click multiple times
92
- return meeting.meetingRequest
93
- .joinMeeting({
94
- inviteeAddress: meeting.meetingJoinUrl || meeting.sipUri,
95
- meetingNumber: meeting.meetingNumber,
96
- deviceUrl: meeting.deviceUrl,
97
- locusUrl: meeting.locusUrl,
98
- correlationId: meeting.correlationId,
99
- roapMessage: options.roapMessage,
100
- permissionToken: meeting.permissionToken,
101
- resourceId: options.resourceId || null,
102
- moderator: options.moderator,
103
- pin: options.pin,
104
- moveToResource: options.moveToResource,
105
- preferTranscoding: options.preferTranscoding,
106
- asResourceOccupant: options.asResourceOccupant,
107
- })
108
- .then((res) => {
109
- Metrics.postEvent({
110
- event: eventType.LOCUS_JOIN_RESPONSE,
111
- meeting,
112
- data: {
113
- trigger: trigger.LOCI_UPDATE,
114
- locus: res.body.locus,
115
- mediaConnections: res.body.mediaConnections,
116
- trackingId: res.headers.trackingid,
117
- },
118
- });
125
+ return IP_VERSION.unknown;
126
+ },
127
+
128
+ joinMeeting: (meeting, options) => {
129
+ if (!meeting) {
130
+ return Promise.reject(new ParameterError('You need a meeting object.'));
131
+ }
132
+ const webex = meeting.getWebexObject();
119
133
 
120
- return MeetingUtil.parseLocusJoin(res);
134
+ // @ts-ignore
135
+ webex.internal.newMetrics.submitClientEvent({
136
+ name: 'client.locus.join.request',
137
+ options: {meetingId: meeting.id},
121
138
  });
122
- };
123
139
 
124
- MeetingUtil.cleanUp = (meeting) => {
125
- // make sure we send last metrics before we close the peerconnection
126
- const stopStatsAnalyzer = meeting.statsAnalyzer
127
- ? meeting.statsAnalyzer.stopAnalyzer()
128
- : Promise.resolve();
129
-
130
- return stopStatsAnalyzer
131
- .then(() => meeting.closeLocalStream())
132
- .then(() => meeting.closeLocalShare())
133
- .then(() => meeting.closeRemoteTracks())
134
- .then(() => meeting.closePeerConnections())
135
- .then(() => {
136
- meeting.unsetLocalVideoTrack();
137
- meeting.unsetLocalShareTrack();
138
- meeting.unsetRemoteTracks();
139
- meeting.unsetPeerConnections();
140
- meeting.reconnectionManager.cleanUp();
141
- })
142
- .then(() => meeting.roap.stop(meeting.correlationId, meeting.roapSeq))
143
- .then(() => meeting.stopKeepAlive());
144
- };
140
+ // eslint-disable-next-line no-warning-comments
141
+ // TODO: check if the meeting is in JOINING state
142
+ // if Joining state termintate the request as user might click multiple times
143
+ return meeting.meetingRequest
144
+ .joinMeeting({
145
+ inviteeAddress: meeting.meetingJoinUrl || meeting.sipUri,
146
+ meetingNumber: meeting.meetingNumber,
147
+ deviceUrl: meeting.deviceUrl,
148
+ locusUrl: meeting.locusUrl,
149
+ locusClusterUrl: meeting.meetingInfo?.locusClusterUrl,
150
+ correlationId: meeting.correlationId,
151
+ roapMessage: options.roapMessage,
152
+ permissionToken: meeting.permissionToken,
153
+ resourceId: options.resourceId || null,
154
+ moderator: options.moderator,
155
+ pin: options.pin,
156
+ moveToResource: options.moveToResource,
157
+ preferTranscoding: !meeting.isMultistream,
158
+ asResourceOccupant: options.asResourceOccupant,
159
+ breakoutsSupported: options.breakoutsSupported,
160
+ locale: options.locale,
161
+ deviceCapabilities: options.deviceCapabilities,
162
+ liveAnnotationSupported: options.liveAnnotationSupported,
163
+ ipVersion: MeetingUtil.getIpVersion(meeting.getWebexObject()),
164
+ })
165
+ .then((res) => {
166
+ // @ts-ignore
167
+ webex.internal.newMetrics.submitClientEvent({
168
+ name: 'client.locus.join.response',
169
+ payload: {
170
+ trigger: 'loci-update',
171
+ identifiers: {
172
+ trackingId: res.headers.trackingid,
173
+ },
174
+ },
175
+ options: {
176
+ meetingId: meeting.id,
177
+ mediaConnections: res.body.mediaConnections,
178
+ },
179
+ });
145
180
 
146
- MeetingUtil.disconnectPhoneAudio = (meeting, phoneUrl) => {
147
- if (meeting.meetingState === FULL_STATE.INACTIVE) {
148
- return Promise.reject(new MeetingNotActiveError());
149
- }
150
-
151
- const options = {
152
- locusUrl: meeting.locusUrl,
153
- selfId: meeting.selfId,
154
- correlationId: meeting.correlationId,
155
- phoneUrl,
156
- };
157
-
158
- return meeting.meetingRequest
159
- .disconnectPhoneAudio(options)
160
- .then((response) => {
161
- if (response?.body?.locus) {
162
- meeting.locusInfo.onFullLocus(response.body.locus);
163
- }
164
- })
165
- .catch((err) => {
181
+ return MeetingUtil.parseLocusJoin(res);
182
+ });
183
+ },
184
+
185
+ cleanUp: (meeting) => {
186
+ meeting.breakouts.cleanUp();
187
+ meeting.simultaneousInterpretation.cleanUp();
188
+
189
+ // make sure we send last metrics before we close the peerconnection
190
+ const stopStatsAnalyzer = meeting.statsAnalyzer
191
+ ? meeting.statsAnalyzer.stopAnalyzer()
192
+ : Promise.resolve();
193
+
194
+ return stopStatsAnalyzer
195
+ .then(() => meeting.closeRemoteStreams())
196
+ .then(() => meeting.closePeerConnections())
197
+ .then(() => {
198
+ meeting.cleanupLocalStreams();
199
+ meeting.unsetRemoteStreams();
200
+ meeting.unsetPeerConnections();
201
+ meeting.reconnectionManager.cleanUp();
202
+ })
203
+ .then(() => meeting.stopKeepAlive())
204
+ .then(() => meeting.updateLLMConnection());
205
+ },
206
+
207
+ disconnectPhoneAudio: (meeting, phoneUrl) => {
208
+ if (meeting.meetingState === FULL_STATE.INACTIVE) {
209
+ return Promise.reject(new MeetingNotActiveError());
210
+ }
211
+
212
+ const options = {
213
+ locusUrl: meeting.locusUrl,
214
+ selfId: meeting.selfId,
215
+ correlationId: meeting.correlationId,
216
+ phoneUrl,
217
+ };
218
+
219
+ return meeting.meetingRequest.disconnectPhoneAudio(options).catch((err) => {
166
220
  LoggerProxy.logger.error(
167
221
  `Meeting:util#disconnectPhoneAudio --> An error occured while disconnecting phone audio in meeting ${meeting.id}, error: ${err}`
168
222
  );
169
223
 
170
224
  return Promise.reject(err);
171
225
  });
172
- };
173
-
174
- // by default will leave on meeting's resourceId
175
- // if you explicity want it not to leave on resource id, pass
176
- // {resourceId: null}
177
- // TODO: chris, you can modify this however you want
178
- MeetingUtil.leaveMeeting = (meeting, options: any = {}) => {
179
- if (meeting.meetingState === FULL_STATE.INACTIVE) {
180
- // TODO: clean up if the meeting is already inactive
181
- return Promise.reject(new MeetingNotActiveError());
182
- }
183
-
184
- if (MeetingUtil.isUserInLeftState(meeting.locusInfo)) {
185
- return Promise.reject(new UserNotJoinedError());
186
- }
187
-
188
- const defaultOptions = {
189
- locusUrl: meeting.locusUrl,
190
- selfId: meeting.selfId,
191
- correlationId: meeting.correlationId,
192
- resourceId: meeting.resourceId,
193
- deviceUrl: meeting.deviceUrl,
194
- };
195
-
196
- const leaveOptions = {...defaultOptions, ...options};
197
-
198
- return meeting.meetingRequest
199
- .leaveMeeting(leaveOptions)
200
- .then((response) => {
201
- if (response && response.body && response.body.locus) {
202
- // && !options.moveMeeting) {
203
- meeting.locusInfo.onFullLocus(response.body.locus);
204
- }
205
-
206
- return Promise.resolve();
207
- })
208
- .then(() => {
209
- if (options.moveMeeting) {
210
- return Promise.resolve();
211
- }
226
+ },
227
+
228
+ /**
229
+ * Returns options for leaving a meeting.
230
+ * @param {any} meeting
231
+ * @param {any} options
232
+ * @returns {any} leave options
233
+ */
234
+ prepareLeaveMeetingOptions: (meeting, options: any = {}) => {
235
+ const defaultOptions = {
236
+ locusUrl: meeting.locusUrl,
237
+ selfId: meeting.selfId,
238
+ correlationId: meeting.correlationId,
239
+ resourceId: meeting.resourceId,
240
+ deviceUrl: meeting.deviceUrl,
241
+ };
242
+
243
+ return {...defaultOptions, ...options};
244
+ },
245
+
246
+ // by default will leave on meeting's resourceId
247
+ // if you explicity want it not to leave on resource id, pass
248
+ // {resourceId: null}
249
+ // TODO: chris, you can modify this however you want
250
+ leaveMeeting: (meeting, options: any = {}) => {
251
+ if (meeting.meetingState === FULL_STATE.INACTIVE) {
252
+ // TODO: clean up if the meeting is already inactive
253
+ return Promise.reject(new MeetingNotActiveError());
254
+ }
212
255
 
213
- return MeetingUtil.cleanUp(meeting);
214
- })
215
- .catch((err) => {
216
- // TODO: If the meeting state comes as LEFT or INACTIVE as response then
217
- // 1) on leave clean up the meeting or simply do a sync on the meeting
218
- // 2) If the error says meeting is inactive then destroy the meeting object
219
- LoggerProxy.logger.error(
220
- `Meeting:util#leaveMeeting --> An error occured while trying to leave meeting with an id of ${meeting.id}, error: ${err}`
221
- );
256
+ if (MeetingUtil.isUserInLeftState(meeting.locusInfo)) {
257
+ return Promise.reject(new UserNotJoinedError());
258
+ }
222
259
 
223
- return Promise.reject(err);
224
- });
225
- };
226
- MeetingUtil.declineMeeting = (meeting, reason) =>
227
- meeting.meetingRequest.declineMeeting({
228
- locusUrl: meeting.locusUrl,
229
- deviceUrl: meeting.deviceUrl,
230
- reason,
231
- });
260
+ const leaveOptions = MeetingUtil.prepareLeaveMeetingOptions(meeting, options);
261
+
262
+ return meeting.meetingRequest
263
+ .leaveMeeting(leaveOptions)
264
+ .then(() => {
265
+ if (options.moveMeeting) {
266
+ return Promise.resolve();
267
+ }
268
+
269
+ return MeetingUtil.cleanUp(meeting);
270
+ })
271
+ .catch((err) => {
272
+ // TODO: If the meeting state comes as LEFT or INACTIVE as response then
273
+ // 1) on leave clean up the meeting or simply do a sync on the meeting
274
+ // 2) If the error says meeting is inactive then destroy the meeting object
275
+ LoggerProxy.logger.error(
276
+ `Meeting:util#leaveMeeting --> An error occured while trying to leave meeting with an id of ${meeting.id}, error: ${err}`
277
+ );
232
278
 
233
- MeetingUtil.isUserInLeftState = (locusInfo) => locusInfo.parsedLocus?.self?.state === _LEFT_;
279
+ return Promise.reject(err);
280
+ });
281
+ },
282
+ declineMeeting: (meeting, reason) =>
283
+ meeting.meetingRequest.declineMeeting({
284
+ locusUrl: meeting.locusUrl,
285
+ deviceUrl: meeting.deviceUrl,
286
+ reason,
287
+ }),
234
288
 
235
- MeetingUtil.isUserInIdleState = (locusInfo) => locusInfo.parsedLocus?.self?.state === _IDLE_;
289
+ isUserInLeftState: (locusInfo) => locusInfo.parsedLocus?.self?.state === _LEFT_,
236
290
 
237
- MeetingUtil.isUserInJoinedState = (locusInfo) => locusInfo.parsedLocus?.self?.state === _JOINED_;
291
+ isUserInIdleState: (locusInfo) => locusInfo.parsedLocus?.self?.state === _IDLE_,
238
292
 
239
- MeetingUtil.isMediaEstablished = (currentMediaStatus) =>
240
- currentMediaStatus &&
241
- (currentMediaStatus.audio || currentMediaStatus.video || currentMediaStatus.share);
293
+ isUserInJoinedState: (locusInfo) => locusInfo.parsedLocus?.self?.state === _JOINED_,
242
294
 
243
- MeetingUtil.joinMeetingOptions = (meeting, options: any = {}) => {
244
- meeting.resourceId = meeting.resourceId || options.resourceId;
295
+ isMediaEstablished: (currentMediaStatus) =>
296
+ currentMediaStatus &&
297
+ (currentMediaStatus.audio || currentMediaStatus.video || currentMediaStatus.share),
245
298
 
246
- if (meeting.requiredCaptcha) {
247
- return Promise.reject(new CaptchaError());
248
- }
249
- if (meeting.passwordStatus === PASSWORD_STATUS.REQUIRED) {
250
- return Promise.reject(new PasswordError());
251
- }
299
+ joinMeetingOptions: (meeting, options: any = {}) => {
300
+ const webex = meeting.getWebexObject();
252
301
 
253
- if (options.pin) {
254
- Metrics.postEvent({
255
- event: eventType.PIN_COLLECTED,
256
- meeting,
257
- });
258
- }
259
-
260
- // normal join meeting, scenario A, D
261
- return MeetingUtil.joinMeeting(meeting, options)
262
- .then((response) => {
263
- meeting.setLocus(response);
264
-
265
- return Promise.resolve(response);
266
- })
267
- .catch((err) => {
268
- // joining a claimed PMR that is not my own, scenario B
269
- if (MeetingUtil.isPinOrGuest(err)) {
270
- Metrics.postEvent({
271
- event: eventType.PIN_PROMPT,
272
- meeting,
273
- });
302
+ meeting.resourceId = meeting.resourceId || options.resourceId;
274
303
 
275
- // request host pin or non host for unclaimed PMR, start of Scenario C
276
- // see https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-Lobby-and--IVR-Feature
277
- return Promise.reject(new IntentToJoinError('Error Joining Meeting', err));
278
- }
279
- LoggerProxy.logger.error('Meeting:util#joinMeetingOptions --> Error joining the call, ', err);
304
+ if (meeting.requiredCaptcha) {
305
+ return Promise.reject(new CaptchaError());
306
+ }
307
+ if (meeting.passwordStatus === PASSWORD_STATUS.REQUIRED) {
308
+ return Promise.reject(new PasswordError());
309
+ }
280
310
 
281
- return Promise.reject(new JoinMeetingError(options, 'Error Joining Meeting', err));
282
- });
283
- };
311
+ if (options.pin) {
312
+ // @ts-ignore
313
+ webex.internal.newMetrics.submitClientEvent({
314
+ name: 'client.pin.collected',
315
+ options: {
316
+ meetingId: meeting.id,
317
+ },
318
+ });
319
+ }
284
320
 
285
- MeetingUtil.updateTransceiver = (options, meetingOptions) => {
286
- const {
287
- type,
288
- sendTrack,
289
- receiveTrack,
290
- track,
291
- transceiver,
292
- peerConnection,
293
- previousMediaDirection,
294
- } = options;
295
-
296
- if (
297
- (sendTrack !== undefined && sendTrack !== previousMediaDirection.sendTrack) ||
298
- (receiveTrack !== undefined && receiveTrack !== previousMediaDirection.receiveTrack)
299
- ) {
300
- return Media.updateTransceiver(
301
- {
302
- meetingId: meetingOptions.meeting.id,
303
- remoteQualityLevel: meetingOptions.mediaProperties.remoteQualityLevel,
304
- enableRtx: meetingOptions.meeting.config.enableRtx,
305
- enableExtmap: meetingOptions.meeting.config.enableExtmap,
306
- },
307
- peerConnection,
308
- transceiver,
309
- {
310
- track,
311
- type,
312
- receiveTrack,
313
- sendTrack,
314
- }
315
- )
316
- .then(() =>
317
- meetingOptions.meeting.roap.sendRoapMediaRequest({
318
- sdp: meetingOptions.mediaProperties.peerConnection.sdp,
319
- roapSeq: meetingOptions.meeting.roapSeq,
320
- meeting: meetingOptions.meeting, // or can pass meeting ID
321
- })
322
- )
323
- .catch((e) => {
321
+ // normal join meeting, scenario A, D
322
+ return MeetingUtil.joinMeeting(meeting, options)
323
+ .then((response) => {
324
+ meeting.setLocus(response);
325
+
326
+ return Promise.resolve(response);
327
+ })
328
+ .catch((err) => {
329
+ // joining a claimed PMR that is not my own, scenario B
330
+ if (MeetingUtil.isPinOrGuest(err)) {
331
+ // @ts-ignore
332
+ webex.internal.newMetrics.submitClientEvent({
333
+ name: 'client.pin.prompt',
334
+ options: {
335
+ meetingId: meeting.id,
336
+ },
337
+ });
338
+
339
+ // request host pin or non host for unclaimed PMR, start of Scenario C
340
+ // see https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-Lobby-and--IVR-Feature
341
+ return Promise.reject(new IntentToJoinError('Error Joining Meeting', err));
342
+ }
324
343
  LoggerProxy.logger.error(
325
- `Meeting:util#updateTransceiver --> Error updating the ${type} streams with error: ${e}`
344
+ 'Meeting:util#joinMeetingOptions --> Error joining the call, ',
345
+ err
326
346
  );
347
+
348
+ return Promise.reject(new JoinMeetingError(options, 'Error Joining Meeting', err));
327
349
  });
328
- }
329
- if (track) {
330
- transceiver.sender.replaceTrack(track);
350
+ },
351
+
352
+ /**
353
+ * Returns request options for leaving a meeting.
354
+ * @param {any} meeting
355
+ * @param {any} options
356
+ * @returns {any} request options
357
+ */
358
+ buildLeaveFetchRequestOptions: (meeting, options: any = {}) => {
359
+ const leaveOptions = MeetingUtil.prepareLeaveMeetingOptions(meeting, options);
360
+
361
+ return meeting.meetingRequest.buildLeaveMeetingRequestOptions(leaveOptions);
362
+ },
363
+
364
+ getTrack: (stream) => {
365
+ let audioTrack = null;
366
+ let videoTrack = null;
367
+ let audioTracks = null;
368
+ let videoTracks = null;
369
+
370
+ if (!stream) {
371
+ return {audioTrack: null, videoTrack: null};
372
+ }
373
+ if (stream.getAudioTracks) {
374
+ audioTracks = stream.getAudioTracks();
375
+ }
376
+ if (stream.getVideoTracks) {
377
+ videoTracks = stream.getVideoTracks();
378
+ }
331
379
 
332
- return Promise.resolve();
333
- }
380
+ if (audioTracks && audioTracks.length > 0) {
381
+ [audioTrack] = audioTracks;
382
+ }
334
383
 
335
- return Promise.reject(new ParameterError('update Failed: please pass valid parameter'));
336
- };
384
+ if (videoTracks && videoTracks.length > 0) {
385
+ [videoTrack] = videoTracks;
386
+ }
337
387
 
338
- MeetingUtil.validateOptions = (options) => {
339
- const {sendVideo, sendAudio, sendShare, localStream, localShare} = options;
388
+ return {audioTrack, videoTrack};
389
+ },
340
390
 
341
- if (sendVideo && !MeetingUtil.getTrack(localStream).videoTrack) {
342
- return Promise.reject(new ParameterError('please pass valid video streams'));
343
- }
391
+ getModeratorFromLocusInfo: (locusInfo) =>
392
+ locusInfo &&
393
+ locusInfo.parsedLocus &&
394
+ locusInfo.parsedLocus.info &&
395
+ locusInfo.parsedLocus.info &&
396
+ locusInfo.parsedLocus.info.moderator,
344
397
 
345
- if (sendAudio && !MeetingUtil.getTrack(localStream).audioTrack) {
346
- return Promise.reject(new ParameterError('please pass valid audio streams'));
347
- }
398
+ getPolicyFromLocusInfo: (locusInfo) =>
399
+ locusInfo &&
400
+ locusInfo.parsedLocus &&
401
+ locusInfo.parsedLocus.info &&
402
+ locusInfo.parsedLocus.info &&
403
+ locusInfo.parsedLocus.info.policy,
348
404
 
349
- if (sendShare && !MeetingUtil.getTrack(localShare).videoTrack) {
350
- return Promise.reject(new ParameterError('please pass valid share streams'));
351
- }
405
+ getUserDisplayHintsFromLocusInfo: (locusInfo) =>
406
+ locusInfo?.parsedLocus?.info?.userDisplayHints || [],
352
407
 
353
- return Promise.resolve();
354
- };
408
+ canInviteNewParticipants: (displayHints) => displayHints.includes(DISPLAY_HINTS.ADD_GUEST),
355
409
 
356
- MeetingUtil.getTrack = (stream) => {
357
- let audioTrack = null;
358
- let videoTrack = null;
359
- let audioTracks = null;
360
- let videoTracks = null;
361
-
362
- if (!stream) {
363
- return {audioTrack: null, videoTrack: null};
364
- }
365
- if (stream.getAudioTracks) {
366
- audioTracks = stream.getAudioTracks();
367
- }
368
- if (stream.getVideoTracks) {
369
- videoTracks = stream.getVideoTracks();
370
- }
371
-
372
- if (audioTracks && audioTracks.length > 0) {
373
- [audioTrack] = audioTracks;
374
- }
375
-
376
- if (videoTracks && videoTracks.length > 0) {
377
- [videoTrack] = videoTracks;
378
- }
379
-
380
- return {audioTrack, videoTrack};
381
- };
410
+ canAdmitParticipant: (displayHints) =>
411
+ displayHints.includes(DISPLAY_HINTS.ROSTER_WAITING_TO_JOIN),
382
412
 
383
- MeetingUtil.getModeratorFromLocusInfo = (locusInfo) =>
384
- locusInfo &&
385
- locusInfo.parsedLocus &&
386
- locusInfo.parsedLocus.info &&
387
- locusInfo.parsedLocus.info &&
388
- locusInfo.parsedLocus.info.moderator;
413
+ canUserLock: (displayHints) =>
414
+ displayHints.includes(DISPLAY_HINTS.LOCK_CONTROL_LOCK) &&
415
+ displayHints.includes(DISPLAY_HINTS.LOCK_STATUS_UNLOCKED),
389
416
 
390
- MeetingUtil.getPolicyFromLocusInfo = (locusInfo) =>
391
- locusInfo &&
392
- locusInfo.parsedLocus &&
393
- locusInfo.parsedLocus.info &&
394
- locusInfo.parsedLocus.info &&
395
- locusInfo.parsedLocus.info.policy;
417
+ canUserUnlock: (displayHints) =>
418
+ displayHints.includes(DISPLAY_HINTS.LOCK_CONTROL_UNLOCK) &&
419
+ displayHints.includes(DISPLAY_HINTS.LOCK_STATUS_LOCKED),
396
420
 
397
- MeetingUtil.getUserDisplayHintsFromLocusInfo = (locusInfo) =>
398
- locusInfo?.parsedLocus?.info?.userDisplayHints || [];
421
+ canUserRaiseHand: (displayHints) => displayHints.includes(DISPLAY_HINTS.RAISE_HAND),
399
422
 
400
- MeetingUtil.canInviteNewParticipants = (displayHints) =>
401
- displayHints.includes(DISPLAY_HINTS.ADD_GUEST);
423
+ canUserLowerAllHands: (displayHints) => displayHints.includes(DISPLAY_HINTS.LOWER_ALL_HANDS),
402
424
 
403
- MeetingUtil.canAdmitParticipant = (displayHints) =>
404
- displayHints.includes(DISPLAY_HINTS.ROSTER_WAITING_TO_JOIN);
425
+ canUserLowerSomeoneElsesHand: (displayHints) =>
426
+ displayHints.includes(DISPLAY_HINTS.LOWER_SOMEONE_ELSES_HAND),
405
427
 
406
- MeetingUtil.canUserLock = (displayHints) =>
407
- displayHints.includes(DISPLAY_HINTS.LOCK_CONTROL_LOCK) &&
408
- displayHints.includes(DISPLAY_HINTS.LOCK_STATUS_UNLOCKED);
428
+ bothLeaveAndEndMeetingAvailable: (displayHints) =>
429
+ displayHints.includes(DISPLAY_HINTS.LEAVE_TRANSFER_HOST_END_MEETING) ||
430
+ displayHints.includes(DISPLAY_HINTS.LEAVE_END_MEETING),
409
431
 
410
- MeetingUtil.canUserUnlock = (displayHints) =>
411
- displayHints.includes(DISPLAY_HINTS.LOCK_CONTROL_UNLOCK) &&
412
- displayHints.includes(DISPLAY_HINTS.LOCK_STATUS_LOCKED);
432
+ canManageBreakout: (displayHints) => displayHints.includes(DISPLAY_HINTS.BREAKOUT_MANAGEMENT),
433
+ canBroadcastMessageToBreakout: (displayHints, policies = {}) =>
434
+ displayHints.includes(DISPLAY_HINTS.BROADCAST_MESSAGE_TO_BREAKOUT) &&
435
+ !!policies[SELF_POLICY.SUPPORT_BROADCAST_MESSAGE],
413
436
 
414
- MeetingUtil.canUserRaiseHand = (displayHints) => displayHints.includes(DISPLAY_HINTS.RAISE_HAND);
437
+ isSuppressBreakoutSupport: (displayHints) =>
438
+ displayHints.includes(DISPLAY_HINTS.UCF_SUPPRESS_BREAKOUTS_SUPPORT),
415
439
 
416
- MeetingUtil.canUserLowerAllHands = (displayHints) =>
417
- displayHints.includes(DISPLAY_HINTS.LOWER_ALL_HANDS);
440
+ canAdmitLobbyToBreakout: (displayHints) =>
441
+ !displayHints.includes(DISPLAY_HINTS.DISABLE_LOBBY_TO_BREAKOUT),
418
442
 
419
- MeetingUtil.canUserLowerSomeoneElsesHand = (displayHints) =>
420
- displayHints.includes(DISPLAY_HINTS.LOWER_SOMEONE_ELSES_HAND);
443
+ isBreakoutPreassignmentsEnabled: (displayHints) =>
444
+ !displayHints.includes(DISPLAY_HINTS.DISABLE_BREAKOUT_PREASSIGNMENTS),
421
445
 
422
- MeetingUtil.bothLeaveAndEndMeetingAvailable = (displayHints) =>
423
- displayHints.includes(DISPLAY_HINTS.LEAVE_TRANSFER_HOST_END_MEETING) ||
424
- displayHints.includes(DISPLAY_HINTS.LEAVE_END_MEETING);
446
+ canUserAskForHelp: (displayHints) => !displayHints.includes(DISPLAY_HINTS.DISABLE_ASK_FOR_HELP),
425
447
 
426
- MeetingUtil.lockMeeting = (actions, request, locusUrl) => {
427
- if (actions && actions.canLock) {
428
- return request.lockMeeting({locusUrl, lock: true});
429
- }
448
+ lockMeeting: (actions, request, locusUrl) => {
449
+ if (actions && actions.canLock) {
450
+ return request.lockMeeting({locusUrl, lock: true});
451
+ }
430
452
 
431
- return Promise.reject(new PermissionError('Lock not allowed, due to joined property.'));
432
- };
453
+ return Promise.reject(new PermissionError('Lock not allowed, due to joined property.'));
454
+ },
455
+
456
+ unlockMeeting: (actions, request, locusUrl) => {
457
+ if (actions && actions.canUnlock) {
458
+ return request.lockMeeting({locusUrl, lock: false});
459
+ }
433
460
 
434
- MeetingUtil.unlockMeeting = (actions, request, locusUrl) => {
435
- if (actions && actions.canUnlock) {
436
- return request.lockMeeting({locusUrl, lock: false});
437
- }
461
+ return Promise.reject(new PermissionError('Unlock not allowed, due to joined property.'));
462
+ },
438
463
 
439
- return Promise.reject(new PermissionError('Unlock not allowed, due to joined property.'));
440
- };
464
+ handleAudioLogging: (audioStream?: LocalMicrophoneStream) => {
465
+ const LOG_HEADER = 'MeetingUtil#handleAudioLogging -->';
441
466
 
442
- MeetingUtil.handleAudioLogging = (audioTrack) => {
443
- const LOG_HEADER = 'MeetingUtil#handleAudioLogging -->';
467
+ if (audioStream) {
468
+ const settings = audioStream.getSettings();
469
+ const {deviceId} = settings;
444
470
 
445
- if (audioTrack) {
446
- const settings = audioTrack.getSettings();
447
- const {deviceId} = settings;
471
+ LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${deviceId}`);
472
+ LoggerProxy.logger.log(LOG_HEADER, 'settings =', JSON.stringify(settings));
473
+ }
474
+ },
448
475
 
449
- LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${deviceId}`);
450
- LoggerProxy.logger.log(LOG_HEADER, 'settings =', JSON.stringify(settings));
451
- }
452
- };
476
+ handleVideoLogging: (videoStream?: LocalCameraStream) => {
477
+ const LOG_HEADER = 'MeetingUtil#handleVideoLogging -->';
478
+
479
+ if (videoStream) {
480
+ const settings = videoStream.getSettings();
481
+ const {deviceId} = settings;
453
482
 
454
- MeetingUtil.handleVideoLogging = (videoTrack) => {
455
- const LOG_HEADER = 'MeetingUtil#handleVideoLogging -->';
483
+ LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${deviceId}`);
484
+ LoggerProxy.logger.log(LOG_HEADER, 'settings =', JSON.stringify(settings));
485
+ }
486
+ },
456
487
 
457
- if (videoTrack) {
458
- const settings = videoTrack.getSettings();
459
- const {deviceId} = settings;
488
+ handleDeviceLogging: (devices = []) => {
489
+ const LOG_HEADER = 'MeetingUtil#handleDeviceLogging -->';
460
490
 
461
- LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${deviceId}`);
462
- LoggerProxy.logger.log(LOG_HEADER, 'settings =', JSON.stringify(settings));
463
- }
464
- };
491
+ devices.forEach((device) => {
492
+ LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${device.deviceId}`);
493
+ LoggerProxy.logger.log(LOG_HEADER, 'settings', JSON.stringify(device));
494
+ });
495
+ },
465
496
 
466
- MeetingUtil.handleDeviceLogging = (devices = []) => {
467
- const LOG_HEADER = 'MeetingUtil#handleDeviceLogging -->';
497
+ endMeetingForAll: (meeting) => {
498
+ if (meeting.meetingState === FULL_STATE.INACTIVE) {
499
+ return Promise.reject(new MeetingNotActiveError());
500
+ }
468
501
 
469
- devices.forEach((device) => {
470
- LoggerProxy.logger.log(LOG_HEADER, `deviceId = ${device.deviceId}`);
471
- LoggerProxy.logger.log(LOG_HEADER, 'settings', JSON.stringify(device));
472
- });
473
- };
502
+ const endOptions = {
503
+ locusUrl: meeting.locusUrl,
504
+ };
505
+
506
+ return meeting.meetingRequest
507
+ .endMeetingForAll(endOptions)
508
+ .then(() => MeetingUtil.cleanUp(meeting))
509
+ .catch((err) => {
510
+ LoggerProxy.logger.error(
511
+ `Meeting:util#endMeetingForAll An error occured while trying to end meeting for all with an id of ${meeting.id}, error: ${err}`
512
+ );
513
+
514
+ return Promise.reject(err);
515
+ });
516
+ },
517
+
518
+ canEnableClosedCaption: (displayHints) => displayHints.includes(DISPLAY_HINTS.CAPTION_START),
519
+
520
+ isSaveTranscriptsEnabled: (displayHints) =>
521
+ displayHints.includes(DISPLAY_HINTS.SAVE_TRANSCRIPTS_ENABLED),
522
+
523
+ canStartTranscribing: (displayHints) =>
524
+ displayHints.includes(DISPLAY_HINTS.TRANSCRIPTION_CONTROL_START),
525
+
526
+ canStopTranscribing: (displayHints) =>
527
+ displayHints.includes(DISPLAY_HINTS.TRANSCRIPTION_CONTROL_STOP),
528
+
529
+ isClosedCaptionActive: (displayHints) =>
530
+ displayHints.includes(DISPLAY_HINTS.CAPTION_STATUS_ACTIVE),
531
+
532
+ isWebexAssistantActive: (displayHints) =>
533
+ displayHints.includes(DISPLAY_HINTS.WEBEX_ASSISTANT_STATUS_ACTIVE),
534
+
535
+ canViewCaptionPanel: (displayHints) => displayHints.includes(DISPLAY_HINTS.ENABLE_CAPTION_PANEL),
536
+
537
+ isRealTimeTranslationEnabled: (displayHints) =>
538
+ displayHints.includes(DISPLAY_HINTS.DISPLAY_REAL_TIME_TRANSLATION),
539
+
540
+ canSelectSpokenLanguages: (displayHints) =>
541
+ displayHints.includes(DISPLAY_HINTS.DISPLAY_NON_ENGLISH_ASR),
542
+
543
+ waitingForOthersToJoin: (displayHints) => displayHints.includes(DISPLAY_HINTS.WAITING_FOR_OTHERS),
544
+
545
+ canSendReactions: (originalValue, displayHints) => {
546
+ if (displayHints.includes(DISPLAY_HINTS.REACTIONS_ACTIVE)) {
547
+ return true;
548
+ }
549
+ if (displayHints.includes(DISPLAY_HINTS.REACTIONS_INACTIVE)) {
550
+ return false;
551
+ }
474
552
 
475
- MeetingUtil.endMeetingForAll = (meeting) => {
476
- if (meeting.meetingState === FULL_STATE.INACTIVE) {
477
- return Promise.reject(new MeetingNotActiveError());
478
- }
553
+ return originalValue;
554
+ },
555
+ canUserRenameSelfAndObserved: (displayHints) =>
556
+ displayHints.includes(DISPLAY_HINTS.CAN_RENAME_SELF_AND_OBSERVED),
479
557
 
480
- const endOptions = {
481
- locusUrl: meeting.locusUrl,
482
- };
558
+ canUserRenameOthers: (displayHints) => displayHints.includes(DISPLAY_HINTS.CAN_RENAME_OTHERS),
483
559
 
484
- return meeting.meetingRequest
485
- .endMeetingForAll(endOptions)
486
- .then((response) => {
487
- if (response && response.body && response.body.locus) {
488
- meeting.locusInfo.onFullLocus(response.body.locus);
560
+ canShareWhiteBoard: (displayHints) => displayHints.includes(DISPLAY_HINTS.SHARE_WHITEBOARD),
561
+
562
+ /**
563
+ * Adds the current locus sequence information to a request body
564
+ * @param {Object} meeting The meeting object
565
+ * @param {Object} requestBody The body of a request to locus
566
+ * @returns {void}
567
+ */
568
+ addSequence: (meeting, requestBody) => {
569
+ const sequence = meeting?.locusInfo?.sequence;
570
+
571
+ if (!sequence) {
572
+ return;
573
+ }
574
+
575
+ requestBody.sequence = sequence;
576
+ },
577
+
578
+ /**
579
+ * Updates the locus info for the meeting with the delta locus
580
+ * returned from requests that include the sequence information
581
+ * Returns the original response object
582
+ * @param {Object} meeting The meeting object
583
+ * @param {Object} response The response of the http request
584
+ * @returns {Object}
585
+ */
586
+ updateLocusWithDelta: (meeting, response) => {
587
+ if (!meeting) {
588
+ return response;
589
+ }
590
+
591
+ const locus = response?.body?.locus;
592
+
593
+ if (locus) {
594
+ meeting.locusInfo.handleLocusDelta(locus, meeting);
595
+ }
596
+
597
+ return response;
598
+ },
599
+
600
+ generateBuildLocusDeltaRequestOptions: (originalMeeting) => {
601
+ const meetingRef = new WeakRef(originalMeeting);
602
+
603
+ const buildLocusDeltaRequestOptions = (originalOptions) => {
604
+ const meeting = meetingRef.deref();
605
+
606
+ if (!meeting) {
607
+ return originalOptions;
489
608
  }
490
609
 
491
- return Promise.resolve();
492
- })
493
- .then(() => MeetingUtil.cleanUp(meeting))
494
- .catch((err) => {
495
- LoggerProxy.logger.error(
496
- `Meeting:util#endMeetingForAll An error occured while trying to end meeting for all with an id of ${meeting.id}, error: ${err}`
497
- );
610
+ const options = cloneDeep(originalOptions);
498
611
 
499
- return Promise.reject(err);
500
- });
501
- };
612
+ if (!options.body) {
613
+ options.body = {};
614
+ }
502
615
 
503
- MeetingUtil.canEnableClosedCaption = (displayHints) =>
504
- displayHints.includes(DISPLAY_HINTS.CAPTION_START);
616
+ MeetingUtil.addSequence(meeting, options.body);
505
617
 
506
- MeetingUtil.canStartTranscribing = (displayHints) =>
507
- displayHints.includes(DISPLAY_HINTS.TRANSCRIPTION_CONTROL_START);
618
+ return options;
619
+ };
508
620
 
509
- MeetingUtil.canStopTranscribing = (displayHints) =>
510
- displayHints.includes(DISPLAY_HINTS.TRANSCRIPTION_CONTROL_STOP);
621
+ return buildLocusDeltaRequestOptions;
622
+ },
511
623
 
512
- MeetingUtil.isClosedCaptionActive = (displayHints) =>
513
- displayHints.includes(DISPLAY_HINTS.CAPTION_STATUS_ACTIVE);
624
+ generateLocusDeltaRequest: (originalMeeting) => {
625
+ const meetingRef = new WeakRef(originalMeeting);
514
626
 
515
- MeetingUtil.isWebexAssistantActive = (displayHints) =>
516
- displayHints.includes(DISPLAY_HINTS.WEBEX_ASSISTANT_STATUS_ACTIVE);
627
+ const buildLocusDeltaRequestOptions =
628
+ MeetingUtil.generateBuildLocusDeltaRequestOptions(originalMeeting);
517
629
 
518
- MeetingUtil.canViewCaptionPanel = (displayHints) =>
519
- displayHints.includes(DISPLAY_HINTS.ENABLE_CAPTION_PANEL);
630
+ const locusDeltaRequest = (originalOptions) => {
631
+ const meeting = meetingRef.deref();
520
632
 
521
- MeetingUtil.isRealTimeTranslationEnabled = (displayHints) =>
522
- displayHints.includes(DISPLAY_HINTS.DISPLAY_REAL_TIME_TRANSLATION);
633
+ if (!meeting) {
634
+ return Promise.resolve();
635
+ }
523
636
 
524
- MeetingUtil.canSelectSpokenLanguages = (displayHints) =>
525
- displayHints.includes(DISPLAY_HINTS.DISPLAY_NON_ENGLISH_ASR);
637
+ const options = buildLocusDeltaRequestOptions(originalOptions);
526
638
 
527
- MeetingUtil.waitingForOthersToJoin = (displayHints) =>
528
- displayHints.includes(DISPLAY_HINTS.WAITING_FOR_OTHERS);
639
+ return meeting
640
+ .request(options)
641
+ .then((response) => MeetingUtil.updateLocusWithDelta(meeting, response));
642
+ };
643
+
644
+ return locusDeltaRequest;
645
+ },
646
+
647
+ selfSupportsFeature: (feature: SELF_POLICY, userPolicies: Record<SELF_POLICY, boolean>) => {
648
+ if (!userPolicies) {
649
+ return true;
650
+ }
651
+
652
+ return userPolicies[feature];
653
+ },
654
+
655
+ parseInterpretationInfo: (meeting, meetingInfo) => {
656
+ if (!meeting || !meetingInfo) {
657
+ return;
658
+ }
659
+ const siInfo = meetingInfo.simultaneousInterpretation;
660
+ meeting.simultaneousInterpretation.updateMeetingSIEnabled(
661
+ !!meetingInfo.turnOnSimultaneousInterpretation,
662
+ !!siInfo?.currentSIInterpreter
663
+ );
664
+ const hostSIEnabled = !!(
665
+ meetingInfo.turnOnSimultaneousInterpretation &&
666
+ meetingInfo?.meetingSiteSetting?.enableHostInterpreterControlSI
667
+ );
668
+ meeting.simultaneousInterpretation.updateHostSIEnabled(hostSIEnabled);
669
+
670
+ function renameKey(obj, oldKey, newKey) {
671
+ if (oldKey in obj) {
672
+ obj[newKey] = obj[oldKey];
673
+ delete obj[oldKey];
674
+ }
675
+ }
676
+ if (siInfo) {
677
+ const lanuagesInfo = cloneDeep(siInfo.siLanguages);
678
+ for (const language of lanuagesInfo) {
679
+ renameKey(language, 'languageCode', 'languageName');
680
+ renameKey(language, 'languageGroupId', 'languageCode');
681
+ }
682
+ if (!meeting.simultaneousInterpretation?.siLanguages?.length) {
683
+ meeting.simultaneousInterpretation.updateInterpretation({siLanguages: lanuagesInfo});
684
+ }
685
+ }
686
+ Trigger.trigger(
687
+ meeting,
688
+ {
689
+ file: 'meeting/util',
690
+ function: 'parseInterpretationInfo',
691
+ },
692
+ EVENT_TRIGGERS.MEETING_INTERPRETATION_UPDATE
693
+ );
694
+ },
695
+ };
529
696
 
530
697
  export default MeetingUtil;