@webex/plugin-meetings 2.59.8 → 2.60.0-next.2

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 (528) hide show
  1. package/README.md +46 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +41 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +357 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +215 -0
  9. package/dist/breakouts/breakout.js.map +1 -0
  10. package/dist/breakouts/collection.js +22 -0
  11. package/dist/breakouts/collection.js.map +1 -0
  12. package/dist/breakouts/edit-lock-error.js +51 -0
  13. package/dist/breakouts/edit-lock-error.js.map +1 -0
  14. package/dist/breakouts/events.js +44 -0
  15. package/dist/breakouts/events.js.map +1 -0
  16. package/dist/breakouts/index.js +1047 -0
  17. package/dist/breakouts/index.js.map +1 -0
  18. package/dist/breakouts/request.js +77 -0
  19. package/dist/breakouts/request.js.map +1 -0
  20. package/dist/breakouts/utils.js +64 -0
  21. package/dist/breakouts/utils.js.map +1 -0
  22. package/dist/common/browser-detection.js +2 -3
  23. package/dist/common/browser-detection.js.map +1 -1
  24. package/dist/common/collection.js +3 -4
  25. package/dist/common/collection.js.map +1 -1
  26. package/dist/common/config.js +1 -2
  27. package/dist/common/config.js.map +1 -1
  28. package/dist/common/errors/captcha-error.js +1 -2
  29. package/dist/common/errors/captcha-error.js.map +1 -1
  30. package/dist/common/errors/intent-to-join.js +1 -2
  31. package/dist/common/errors/intent-to-join.js.map +1 -1
  32. package/dist/common/errors/join-meeting.js +1 -2
  33. package/dist/common/errors/join-meeting.js.map +1 -1
  34. package/dist/common/errors/media.js +1 -2
  35. package/dist/common/errors/media.js.map +1 -1
  36. package/dist/common/errors/no-meeting-info.js +50 -0
  37. package/dist/common/errors/no-meeting-info.js.map +1 -0
  38. package/dist/common/errors/parameter.js +3 -4
  39. package/dist/common/errors/parameter.js.map +1 -1
  40. package/dist/common/errors/password-error.js +1 -2
  41. package/dist/common/errors/password-error.js.map +1 -1
  42. package/dist/common/errors/permission.js +1 -2
  43. package/dist/common/errors/permission.js.map +1 -1
  44. package/dist/common/errors/reclaim-host-role-errors.js +154 -0
  45. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  46. package/dist/common/errors/reconnection-in-progress.js +1 -2
  47. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  48. package/dist/common/errors/reconnection.js +1 -2
  49. package/dist/common/errors/reconnection.js.map +1 -1
  50. package/dist/common/errors/stats.js +1 -2
  51. package/dist/common/errors/stats.js.map +1 -1
  52. package/dist/common/errors/webex-errors.js +48 -28
  53. package/dist/common/errors/webex-errors.js.map +1 -1
  54. package/dist/common/errors/webex-meetings-error.js +1 -2
  55. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  56. package/dist/common/events/events-scope.js +1 -2
  57. package/dist/common/events/events-scope.js.map +1 -1
  58. package/dist/common/events/events.js +1 -2
  59. package/dist/common/events/events.js.map +1 -1
  60. package/dist/common/events/trigger-proxy.js +1 -2
  61. package/dist/common/events/trigger-proxy.js.map +1 -1
  62. package/dist/common/events/util.js +1 -2
  63. package/dist/common/events/util.js.map +1 -1
  64. package/dist/common/logs/logger-config.js +1 -2
  65. package/dist/common/logs/logger-config.js.map +1 -1
  66. package/dist/common/logs/logger-proxy.js +2 -3
  67. package/dist/common/logs/logger-proxy.js.map +1 -1
  68. package/dist/common/logs/request.js +8 -5
  69. package/dist/common/logs/request.js.map +1 -1
  70. package/dist/common/queue.js +22 -9
  71. package/dist/common/queue.js.map +1 -1
  72. package/dist/config.js +8 -11
  73. package/dist/config.js.map +1 -1
  74. package/dist/constants.js +437 -435
  75. package/dist/constants.js.map +1 -1
  76. package/dist/controls-options-manager/constants.js +3 -6
  77. package/dist/controls-options-manager/constants.js.map +1 -1
  78. package/dist/controls-options-manager/enums.js +15 -6
  79. package/dist/controls-options-manager/enums.js.map +1 -1
  80. package/dist/controls-options-manager/index.js +127 -38
  81. package/dist/controls-options-manager/index.js.map +1 -1
  82. package/dist/controls-options-manager/types.js +7 -0
  83. package/dist/controls-options-manager/types.js.map +1 -0
  84. package/dist/controls-options-manager/util.js +309 -19
  85. package/dist/controls-options-manager/util.js.map +1 -1
  86. package/dist/index.js +116 -4
  87. package/dist/index.js.map +1 -1
  88. package/dist/interpretation/collection.js +22 -0
  89. package/dist/interpretation/collection.js.map +1 -0
  90. package/dist/interpretation/index.js +365 -0
  91. package/dist/interpretation/index.js.map +1 -0
  92. package/dist/interpretation/siLanguage.js +24 -0
  93. package/dist/interpretation/siLanguage.js.map +1 -0
  94. package/dist/locus-info/controlsUtils.js +100 -11
  95. package/dist/locus-info/controlsUtils.js.map +1 -1
  96. package/dist/locus-info/embeddedAppsUtils.js +3 -4
  97. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  98. package/dist/locus-info/fullState.js +1 -2
  99. package/dist/locus-info/fullState.js.map +1 -1
  100. package/dist/locus-info/hostUtils.js +1 -2
  101. package/dist/locus-info/hostUtils.js.map +1 -1
  102. package/dist/locus-info/index.js +425 -84
  103. package/dist/locus-info/index.js.map +1 -1
  104. package/dist/locus-info/infoUtils.js +13 -5
  105. package/dist/locus-info/infoUtils.js.map +1 -1
  106. package/dist/locus-info/mediaSharesUtils.js +58 -3
  107. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  108. package/dist/locus-info/parser.js +253 -80
  109. package/dist/locus-info/parser.js.map +1 -1
  110. package/dist/locus-info/selfUtils.js +97 -13
  111. package/dist/locus-info/selfUtils.js.map +1 -1
  112. package/dist/media/index.js +106 -319
  113. package/dist/media/index.js.map +1 -1
  114. package/dist/media/properties.js +96 -153
  115. package/dist/media/properties.js.map +1 -1
  116. package/dist/media/util.js +1 -22
  117. package/dist/media/util.js.map +1 -1
  118. package/dist/mediaQualityMetrics/config.js +498 -493
  119. package/dist/mediaQualityMetrics/config.js.map +1 -1
  120. package/dist/meeting/in-meeting-actions.js +92 -3
  121. package/dist/meeting/in-meeting-actions.js.map +1 -1
  122. package/dist/meeting/index.js +4628 -2971
  123. package/dist/meeting/index.js.map +1 -1
  124. package/dist/meeting/locusMediaRequest.js +291 -0
  125. package/dist/meeting/locusMediaRequest.js.map +1 -0
  126. package/dist/meeting/muteState.js +224 -133
  127. package/dist/meeting/muteState.js.map +1 -1
  128. package/dist/meeting/request.js +297 -199
  129. package/dist/meeting/request.js.map +1 -1
  130. package/dist/meeting/request.type.js +7 -0
  131. package/dist/meeting/request.type.js.map +1 -0
  132. package/dist/meeting/state.js +1 -2
  133. package/dist/meeting/state.js.map +1 -1
  134. package/dist/meeting/util.js +605 -435
  135. package/dist/meeting/util.js.map +1 -1
  136. package/dist/meeting-info/collection.js +3 -4
  137. package/dist/meeting-info/collection.js.map +1 -1
  138. package/dist/meeting-info/index.js +74 -7
  139. package/dist/meeting-info/index.js.map +1 -1
  140. package/dist/meeting-info/meeting-info-v2.js +200 -63
  141. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  142. package/dist/meeting-info/request.js +1 -2
  143. package/dist/meeting-info/request.js.map +1 -1
  144. package/dist/meeting-info/util.js +2 -3
  145. package/dist/meeting-info/util.js.map +1 -1
  146. package/dist/meeting-info/utilv2.js +39 -41
  147. package/dist/meeting-info/utilv2.js.map +1 -1
  148. package/dist/meetings/collection.js +42 -4
  149. package/dist/meetings/collection.js.map +1 -1
  150. package/dist/meetings/index.js +477 -123
  151. package/dist/meetings/index.js.map +1 -1
  152. package/dist/meetings/meetings.types.js +7 -0
  153. package/dist/meetings/meetings.types.js.map +1 -0
  154. package/dist/meetings/request.js +4 -3
  155. package/dist/meetings/request.js.map +1 -1
  156. package/dist/meetings/util.js +107 -6
  157. package/dist/meetings/util.js.map +1 -1
  158. package/dist/member/index.js +54 -2
  159. package/dist/member/index.js.map +1 -1
  160. package/dist/member/member.types.js +3 -4
  161. package/dist/member/member.types.js.map +1 -1
  162. package/dist/member/types.js +23 -0
  163. package/dist/member/types.js.map +1 -0
  164. package/dist/member/util.js +131 -29
  165. package/dist/member/util.js.map +1 -1
  166. package/dist/members/collection.js +11 -2
  167. package/dist/members/collection.js.map +1 -1
  168. package/dist/members/index.js +174 -10
  169. package/dist/members/index.js.map +1 -1
  170. package/dist/members/request.js +108 -41
  171. package/dist/members/request.js.map +1 -1
  172. package/dist/members/types.js +14 -0
  173. package/dist/members/types.js.map +1 -0
  174. package/dist/members/util.js +327 -234
  175. package/dist/members/util.js.map +1 -1
  176. package/dist/metrics/constants.js +15 -9
  177. package/dist/metrics/constants.js.map +1 -1
  178. package/dist/metrics/index.js +4 -452
  179. package/dist/metrics/index.js.map +1 -1
  180. package/dist/multistream/mediaRequestManager.js +344 -0
  181. package/dist/multistream/mediaRequestManager.js.map +1 -0
  182. package/dist/multistream/receiveSlot.js +200 -0
  183. package/dist/multistream/receiveSlot.js.map +1 -0
  184. package/dist/multistream/receiveSlotManager.js +174 -0
  185. package/dist/multistream/receiveSlotManager.js.map +1 -0
  186. package/dist/multistream/remoteMedia.js +268 -0
  187. package/dist/multistream/remoteMedia.js.map +1 -0
  188. package/dist/multistream/remoteMediaGroup.js +267 -0
  189. package/dist/multistream/remoteMediaGroup.js.map +1 -0
  190. package/dist/multistream/remoteMediaManager.js +1211 -0
  191. package/dist/multistream/remoteMediaManager.js.map +1 -0
  192. package/dist/multistream/sendSlotManager.js +236 -0
  193. package/dist/multistream/sendSlotManager.js.map +1 -0
  194. package/dist/networkQualityMonitor/index.js +5 -4
  195. package/dist/networkQualityMonitor/index.js.map +1 -1
  196. package/dist/personal-meeting-room/index.js +2 -3
  197. package/dist/personal-meeting-room/index.js.map +1 -1
  198. package/dist/personal-meeting-room/request.js +2 -3
  199. package/dist/personal-meeting-room/request.js.map +1 -1
  200. package/dist/personal-meeting-room/util.js +1 -2
  201. package/dist/personal-meeting-room/util.js.map +1 -1
  202. package/dist/reachability/index.js +265 -72
  203. package/dist/reachability/index.js.map +1 -1
  204. package/dist/reachability/request.js +18 -10
  205. package/dist/reachability/request.js.map +1 -1
  206. package/dist/reactions/constants.js +12 -0
  207. package/dist/reactions/constants.js.map +1 -0
  208. package/dist/reactions/reactions.js +4 -6
  209. package/dist/reactions/reactions.js.map +1 -1
  210. package/dist/reactions/reactions.type.js +21 -23
  211. package/dist/reactions/reactions.type.js.map +1 -1
  212. package/dist/reconnection-manager/index.js +281 -229
  213. package/dist/reconnection-manager/index.js.map +1 -1
  214. package/dist/recording-controller/enums.js +4 -5
  215. package/dist/recording-controller/enums.js.map +1 -1
  216. package/dist/recording-controller/index.js +57 -46
  217. package/dist/recording-controller/index.js.map +1 -1
  218. package/dist/recording-controller/util.js +10 -10
  219. package/dist/recording-controller/util.js.map +1 -1
  220. package/dist/roap/index.js +101 -235
  221. package/dist/roap/index.js.map +1 -1
  222. package/dist/roap/request.js +126 -180
  223. package/dist/roap/request.js.map +1 -1
  224. package/dist/roap/turnDiscovery.js +115 -105
  225. package/dist/roap/turnDiscovery.js.map +1 -1
  226. package/dist/rtcMetrics/constants.js +11 -0
  227. package/dist/rtcMetrics/constants.js.map +1 -0
  228. package/dist/rtcMetrics/index.js +140 -0
  229. package/dist/rtcMetrics/index.js.map +1 -0
  230. package/dist/statsAnalyzer/global.js +2 -85
  231. package/dist/statsAnalyzer/global.js.map +1 -1
  232. package/dist/statsAnalyzer/index.js +402 -424
  233. package/dist/statsAnalyzer/index.js.map +1 -1
  234. package/dist/statsAnalyzer/mqaUtil.js +117 -83
  235. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  236. package/dist/transcription/index.js +1 -2
  237. package/dist/transcription/index.js.map +1 -1
  238. package/dist/webinar/collection.js +43 -0
  239. package/dist/webinar/collection.js.map +1 -0
  240. package/dist/webinar/index.js +68 -0
  241. package/dist/webinar/index.js.map +1 -0
  242. package/package.json +34 -25
  243. package/src/annotation/annotation.types.ts +50 -0
  244. package/src/annotation/constants.ts +36 -0
  245. package/src/annotation/index.ts +328 -0
  246. package/src/breakouts/README.md +220 -0
  247. package/src/breakouts/breakout.ts +188 -0
  248. package/src/breakouts/collection.ts +19 -0
  249. package/src/breakouts/edit-lock-error.ts +25 -0
  250. package/src/breakouts/events.ts +56 -0
  251. package/src/breakouts/index.ts +925 -0
  252. package/src/breakouts/request.ts +55 -0
  253. package/src/breakouts/utils.ts +57 -0
  254. package/src/common/errors/no-meeting-info.ts +24 -0
  255. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  256. package/src/common/errors/webex-errors.ts +36 -12
  257. package/src/common/logs/logger-proxy.ts +1 -1
  258. package/src/common/logs/request.ts +5 -1
  259. package/src/common/queue.ts +22 -8
  260. package/src/config.ts +5 -7
  261. package/src/constants.ts +271 -93
  262. package/src/controls-options-manager/enums.ts +12 -0
  263. package/src/controls-options-manager/index.ts +116 -21
  264. package/src/controls-options-manager/types.ts +59 -0
  265. package/src/controls-options-manager/util.ts +294 -14
  266. package/src/index.ts +40 -0
  267. package/src/interpretation/README.md +60 -0
  268. package/src/interpretation/collection.ts +19 -0
  269. package/src/interpretation/index.ts +332 -0
  270. package/src/interpretation/siLanguage.ts +18 -0
  271. package/src/locus-info/controlsUtils.ts +110 -0
  272. package/src/locus-info/index.ts +449 -61
  273. package/src/locus-info/infoUtils.ts +14 -2
  274. package/src/locus-info/mediaSharesUtils.ts +64 -0
  275. package/src/locus-info/parser.ts +258 -47
  276. package/src/locus-info/selfUtils.ts +85 -2
  277. package/src/media/index.ts +153 -370
  278. package/src/media/properties.ts +106 -136
  279. package/src/media/util.ts +0 -21
  280. package/src/mediaQualityMetrics/config.ts +379 -377
  281. package/src/meeting/in-meeting-actions.ts +172 -0
  282. package/src/meeting/index.ts +3861 -2504
  283. package/src/meeting/locusMediaRequest.ts +313 -0
  284. package/src/meeting/muteState.ts +224 -138
  285. package/src/meeting/request.ts +207 -127
  286. package/src/meeting/request.type.ts +13 -0
  287. package/src/meeting/util.ts +590 -423
  288. package/src/meeting-info/index.ts +81 -8
  289. package/src/meeting-info/meeting-info-v2.ts +163 -13
  290. package/src/meeting-info/util.ts +1 -1
  291. package/src/meeting-info/utilv2.ts +28 -28
  292. package/src/meetings/collection.ts +33 -0
  293. package/src/meetings/index.ts +477 -124
  294. package/src/meetings/meetings.types.ts +12 -0
  295. package/src/meetings/request.ts +2 -0
  296. package/src/meetings/util.ts +116 -5
  297. package/src/member/index.ts +52 -1
  298. package/src/member/types.ts +38 -0
  299. package/src/member/util.ts +139 -28
  300. package/src/members/collection.ts +8 -0
  301. package/src/members/index.ts +196 -7
  302. package/src/members/request.ts +97 -17
  303. package/src/members/types.ts +29 -0
  304. package/src/members/util.ts +333 -240
  305. package/src/metrics/constants.ts +13 -6
  306. package/src/metrics/index.ts +1 -471
  307. package/src/multistream/mediaRequestManager.ts +440 -0
  308. package/src/multistream/receiveSlot.ts +184 -0
  309. package/src/multistream/receiveSlotManager.ts +166 -0
  310. package/src/multistream/remoteMedia.ts +254 -0
  311. package/src/multistream/remoteMediaGroup.ts +284 -0
  312. package/src/multistream/remoteMediaManager.ts +1145 -0
  313. package/src/multistream/sendSlotManager.ts +170 -0
  314. package/src/networkQualityMonitor/index.ts +6 -6
  315. package/src/reachability/index.ts +238 -45
  316. package/src/reachability/request.ts +17 -8
  317. package/src/reactions/constants.ts +4 -0
  318. package/src/reactions/reactions.ts +4 -4
  319. package/src/reactions/reactions.type.ts +30 -4
  320. package/src/reconnection-manager/index.ts +167 -154
  321. package/src/recording-controller/index.ts +20 -3
  322. package/src/recording-controller/util.ts +26 -9
  323. package/src/roap/index.ts +98 -241
  324. package/src/roap/request.ts +74 -148
  325. package/src/roap/turnDiscovery.ts +62 -56
  326. package/src/rtcMetrics/constants.ts +3 -0
  327. package/src/rtcMetrics/index.ts +124 -0
  328. package/src/statsAnalyzer/global.ts +1 -84
  329. package/src/statsAnalyzer/index.ts +470 -522
  330. package/src/statsAnalyzer/mqaUtil.ts +117 -112
  331. package/src/webinar/collection.ts +31 -0
  332. package/src/webinar/index.ts +62 -0
  333. package/test/integration/spec/converged-space-meetings.js +233 -0
  334. package/test/integration/spec/journey.js +320 -264
  335. package/test/integration/spec/space-meeting.js +77 -4
  336. package/test/unit/spec/annotation/index.ts +418 -0
  337. package/test/unit/spec/breakouts/breakout.ts +237 -0
  338. package/test/unit/spec/breakouts/collection.ts +15 -0
  339. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  340. package/test/unit/spec/breakouts/events.ts +89 -0
  341. package/test/unit/spec/breakouts/index.ts +1790 -0
  342. package/test/unit/spec/breakouts/request.ts +104 -0
  343. package/test/unit/spec/breakouts/utils.js +72 -0
  344. package/test/unit/spec/common/queue.js +31 -2
  345. package/test/unit/spec/controls-options-manager/index.js +163 -0
  346. package/test/unit/spec/controls-options-manager/util.js +576 -60
  347. package/test/unit/spec/fixture/locus.js +1 -0
  348. package/test/unit/spec/interpretation/collection.ts +15 -0
  349. package/test/unit/spec/interpretation/index.ts +589 -0
  350. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  351. package/test/unit/spec/locus-info/controlsUtils.js +323 -30
  352. package/test/unit/spec/locus-info/index.js +1390 -16
  353. package/test/unit/spec/locus-info/infoUtils.js +54 -16
  354. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  355. package/test/unit/spec/locus-info/lib/selfConstant.js +48 -0
  356. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  357. package/test/unit/spec/locus-info/parser.js +116 -35
  358. package/test/unit/spec/locus-info/selfUtils.js +275 -0
  359. package/test/unit/spec/media/index.ts +274 -0
  360. package/test/unit/spec/media/properties.ts +75 -84
  361. package/test/unit/spec/meeting/in-meeting-actions.ts +84 -0
  362. package/test/unit/spec/meeting/index.js +8269 -3145
  363. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  364. package/test/unit/spec/meeting/muteState.js +409 -213
  365. package/test/unit/spec/meeting/request.js +512 -42
  366. package/test/unit/spec/meeting/utils.js +741 -24
  367. package/test/unit/spec/meeting-info/index.js +300 -0
  368. package/test/unit/spec/meeting-info/meetinginfov2.js +527 -5
  369. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  370. package/test/unit/spec/meetings/collection.js +26 -0
  371. package/test/unit/spec/meetings/index.js +1201 -210
  372. package/test/unit/spec/meetings/utils.js +202 -2
  373. package/test/unit/spec/member/index.js +38 -8
  374. package/test/unit/spec/member/util.js +499 -29
  375. package/test/unit/spec/members/index.js +597 -3
  376. package/test/unit/spec/members/request.js +206 -27
  377. package/test/unit/spec/members/utils.js +210 -0
  378. package/test/unit/spec/metrics/index.js +1 -50
  379. package/test/unit/spec/multistream/mediaRequestManager.ts +1418 -0
  380. package/test/unit/spec/multistream/receiveSlot.ts +163 -0
  381. package/test/unit/spec/multistream/receiveSlotManager.ts +203 -0
  382. package/test/unit/spec/multistream/remoteMedia.ts +255 -0
  383. package/test/unit/spec/multistream/remoteMediaGroup.ts +662 -0
  384. package/test/unit/spec/multistream/remoteMediaManager.ts +1924 -0
  385. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  386. package/test/unit/spec/networkQualityMonitor/index.js +4 -4
  387. package/test/unit/spec/reachability/index.ts +598 -24
  388. package/test/unit/spec/reachability/request.js +68 -0
  389. package/test/unit/spec/reconnection-manager/index.js +145 -22
  390. package/test/unit/spec/recording-controller/index.js +293 -218
  391. package/test/unit/spec/recording-controller/util.js +223 -96
  392. package/test/unit/spec/roap/index.ts +200 -76
  393. package/test/unit/spec/roap/request.ts +232 -0
  394. package/test/unit/spec/roap/turnDiscovery.ts +86 -48
  395. package/test/unit/spec/rtcMetrics/index.ts +93 -0
  396. package/test/unit/spec/stats-analyzer/index.js +188 -174
  397. package/test/unit/spec/webinar/collection.ts +13 -0
  398. package/test/unit/spec/webinar/index.ts +60 -0
  399. package/test/utils/constants.js +9 -0
  400. package/test/utils/integrationTestUtils.js +46 -0
  401. package/test/utils/testUtils.js +0 -45
  402. package/test/utils/webex-config.js +4 -0
  403. package/test/utils/webex-test-users.js +7 -3
  404. package/dist/common/browser-detection.d.ts +0 -9
  405. package/dist/common/collection.d.ts +0 -48
  406. package/dist/common/config.d.ts +0 -2
  407. package/dist/common/errors/captcha-error.d.ts +0 -15
  408. package/dist/common/errors/intent-to-join.d.ts +0 -16
  409. package/dist/common/errors/join-meeting.d.ts +0 -17
  410. package/dist/common/errors/media.d.ts +0 -15
  411. package/dist/common/errors/parameter.d.ts +0 -15
  412. package/dist/common/errors/password-error.d.ts +0 -15
  413. package/dist/common/errors/permission.d.ts +0 -14
  414. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  415. package/dist/common/errors/reconnection.d.ts +0 -15
  416. package/dist/common/errors/stats.d.ts +0 -15
  417. package/dist/common/errors/webex-errors.d.ts +0 -81
  418. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  419. package/dist/common/events/events-scope.d.ts +0 -17
  420. package/dist/common/events/events.d.ts +0 -12
  421. package/dist/common/events/trigger-proxy.d.ts +0 -2
  422. package/dist/common/events/util.d.ts +0 -2
  423. package/dist/common/logs/logger-config.d.ts +0 -2
  424. package/dist/common/logs/logger-proxy.d.ts +0 -2
  425. package/dist/common/logs/request.d.ts +0 -34
  426. package/dist/common/queue.d.ts +0 -32
  427. package/dist/config.d.ts +0 -73
  428. package/dist/constants.d.ts +0 -926
  429. package/dist/controls-options-manager/constants.d.ts +0 -4
  430. package/dist/controls-options-manager/enums.d.ts +0 -5
  431. package/dist/controls-options-manager/index.d.ts +0 -120
  432. package/dist/controls-options-manager/util.d.ts +0 -7
  433. package/dist/index.d.ts +0 -4
  434. package/dist/locus-info/controlsUtils.d.ts +0 -2
  435. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  436. package/dist/locus-info/fullState.d.ts +0 -2
  437. package/dist/locus-info/hostUtils.d.ts +0 -2
  438. package/dist/locus-info/index.d.ts +0 -269
  439. package/dist/locus-info/infoUtils.d.ts +0 -2
  440. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  441. package/dist/locus-info/parser.d.ts +0 -212
  442. package/dist/locus-info/selfUtils.d.ts +0 -2
  443. package/dist/media/index.d.ts +0 -32
  444. package/dist/media/properties.d.ts +0 -108
  445. package/dist/media/util.d.ts +0 -2
  446. package/dist/mediaQualityMetrics/config.d.ts +0 -233
  447. package/dist/meeting/effectsState.d.ts +0 -42
  448. package/dist/meeting/effectsState.js +0 -260
  449. package/dist/meeting/effectsState.js.map +0 -1
  450. package/dist/meeting/in-meeting-actions.d.ts +0 -79
  451. package/dist/meeting/index.d.ts +0 -1622
  452. package/dist/meeting/muteState.d.ts +0 -116
  453. package/dist/meeting/request.d.ts +0 -255
  454. package/dist/meeting/state.d.ts +0 -9
  455. package/dist/meeting/util.d.ts +0 -2
  456. package/dist/meeting-info/collection.d.ts +0 -20
  457. package/dist/meeting-info/index.d.ts +0 -57
  458. package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
  459. package/dist/meeting-info/request.d.ts +0 -22
  460. package/dist/meeting-info/util.d.ts +0 -2
  461. package/dist/meeting-info/utilv2.d.ts +0 -2
  462. package/dist/meetings/collection.d.ts +0 -23
  463. package/dist/meetings/index.d.ts +0 -296
  464. package/dist/meetings/request.d.ts +0 -27
  465. package/dist/meetings/util.d.ts +0 -18
  466. package/dist/member/index.d.ts +0 -147
  467. package/dist/member/member.types.d.ts +0 -11
  468. package/dist/member/util.d.ts +0 -2
  469. package/dist/members/collection.d.ts +0 -24
  470. package/dist/members/index.d.ts +0 -298
  471. package/dist/members/request.d.ts +0 -50
  472. package/dist/members/util.d.ts +0 -2
  473. package/dist/metrics/config.d.ts +0 -169
  474. package/dist/metrics/config.js +0 -289
  475. package/dist/metrics/config.js.map +0 -1
  476. package/dist/metrics/constants.d.ts +0 -59
  477. package/dist/metrics/index.d.ts +0 -152
  478. package/dist/networkQualityMonitor/index.d.ts +0 -70
  479. package/dist/peer-connection-manager/index.d.ts +0 -6
  480. package/dist/peer-connection-manager/index.js +0 -671
  481. package/dist/peer-connection-manager/index.js.map +0 -1
  482. package/dist/peer-connection-manager/util.d.ts +0 -6
  483. package/dist/peer-connection-manager/util.js +0 -110
  484. package/dist/peer-connection-manager/util.js.map +0 -1
  485. package/dist/personal-meeting-room/index.d.ts +0 -47
  486. package/dist/personal-meeting-room/request.d.ts +0 -14
  487. package/dist/personal-meeting-room/util.d.ts +0 -2
  488. package/dist/reachability/index.d.ts +0 -139
  489. package/dist/reachability/request.d.ts +0 -35
  490. package/dist/reactions/reactions.d.ts +0 -4
  491. package/dist/reactions/reactions.type.d.ts +0 -32
  492. package/dist/reconnection-manager/index.d.ts +0 -112
  493. package/dist/recording-controller/enums.d.ts +0 -7
  494. package/dist/recording-controller/index.d.ts +0 -193
  495. package/dist/recording-controller/util.d.ts +0 -13
  496. package/dist/roap/collection.d.ts +0 -10
  497. package/dist/roap/collection.js +0 -63
  498. package/dist/roap/collection.js.map +0 -1
  499. package/dist/roap/handler.d.ts +0 -47
  500. package/dist/roap/handler.js +0 -279
  501. package/dist/roap/handler.js.map +0 -1
  502. package/dist/roap/index.d.ts +0 -116
  503. package/dist/roap/request.d.ts +0 -35
  504. package/dist/roap/state.d.ts +0 -9
  505. package/dist/roap/state.js +0 -127
  506. package/dist/roap/state.js.map +0 -1
  507. package/dist/roap/turnDiscovery.d.ts +0 -81
  508. package/dist/roap/util.d.ts +0 -2
  509. package/dist/roap/util.js +0 -76
  510. package/dist/roap/util.js.map +0 -1
  511. package/dist/statsAnalyzer/global.d.ts +0 -118
  512. package/dist/statsAnalyzer/index.d.ts +0 -193
  513. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
  514. package/dist/transcription/index.d.ts +0 -64
  515. package/src/index.js +0 -15
  516. package/src/meeting/effectsState.ts +0 -209
  517. package/src/metrics/config.ts +0 -485
  518. package/src/peer-connection-manager/index.ts +0 -847
  519. package/src/peer-connection-manager/util.ts +0 -119
  520. package/src/roap/collection.ts +0 -62
  521. package/src/roap/handler.ts +0 -294
  522. package/src/roap/state.ts +0 -156
  523. package/src/roap/util.ts +0 -100
  524. package/test/unit/spec/meeting/effectsState.js +0 -281
  525. package/test/unit/spec/peerconnection-manager/index.js +0 -218
  526. package/test/unit/spec/peerconnection-manager/utils.js +0 -49
  527. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -388
  528. package/test/unit/spec/roap/util.js +0 -30
@@ -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;