@webex/plugin-meetings 3.0.0-beta.42 → 3.0.0-beta.421

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