@webex/plugin-meetings 3.6.0 → 3.7.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/README.md +2 -1
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/common/errors/webinar-registration-error.js +50 -0
  5. package/dist/common/errors/webinar-registration-error.js.map +1 -0
  6. package/dist/config.js +3 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/constants.js +31 -2
  9. package/dist/constants.js.map +1 -1
  10. package/dist/controls-options-manager/enums.js +1 -0
  11. package/dist/controls-options-manager/enums.js.map +1 -1
  12. package/dist/controls-options-manager/index.js +10 -3
  13. package/dist/controls-options-manager/index.js.map +1 -1
  14. package/dist/controls-options-manager/types.js.map +1 -1
  15. package/dist/controls-options-manager/util.js +12 -0
  16. package/dist/controls-options-manager/util.js.map +1 -1
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/interpretation/index.js +1 -1
  20. package/dist/interpretation/siLanguage.js +1 -1
  21. package/dist/locus-info/controlsUtils.js +28 -4
  22. package/dist/locus-info/controlsUtils.js.map +1 -1
  23. package/dist/locus-info/fullState.js +2 -1
  24. package/dist/locus-info/fullState.js.map +1 -1
  25. package/dist/locus-info/index.js +61 -3
  26. package/dist/locus-info/index.js.map +1 -1
  27. package/dist/locus-info/parser.js +5 -1
  28. package/dist/locus-info/parser.js.map +1 -1
  29. package/dist/meeting/in-meeting-actions.js +19 -1
  30. package/dist/meeting/in-meeting-actions.js.map +1 -1
  31. package/dist/meeting/index.js +692 -522
  32. package/dist/meeting/index.js.map +1 -1
  33. package/dist/meeting/locusMediaRequest.js +2 -6
  34. package/dist/meeting/locusMediaRequest.js.map +1 -1
  35. package/dist/meeting/muteState.js +5 -2
  36. package/dist/meeting/muteState.js.map +1 -1
  37. package/dist/meeting/request.js +21 -29
  38. package/dist/meeting/request.js.map +1 -1
  39. package/dist/meeting/util.js +97 -61
  40. package/dist/meeting/util.js.map +1 -1
  41. package/dist/meeting-info/meeting-info-v2.js +68 -17
  42. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  43. package/dist/meetings/index.js +25 -1
  44. package/dist/meetings/index.js.map +1 -1
  45. package/dist/members/index.js +3 -2
  46. package/dist/members/index.js.map +1 -1
  47. package/dist/members/util.js +9 -5
  48. package/dist/members/util.js.map +1 -1
  49. package/dist/metrics/constants.js +2 -1
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/multistream/remoteMedia.js +4 -0
  52. package/dist/multistream/remoteMedia.js.map +1 -1
  53. package/dist/reachability/clusterReachability.js +0 -4
  54. package/dist/reachability/clusterReachability.js.map +1 -1
  55. package/dist/reachability/index.js +433 -136
  56. package/dist/reachability/index.js.map +1 -1
  57. package/dist/{rtcMetrics/constants.js → reachability/reachability.types.js} +1 -5
  58. package/dist/reachability/reachability.types.js.map +1 -0
  59. package/dist/reachability/request.js +23 -9
  60. package/dist/reachability/request.js.map +1 -1
  61. package/dist/roap/index.js +5 -7
  62. package/dist/roap/index.js.map +1 -1
  63. package/dist/roap/request.js +45 -79
  64. package/dist/roap/request.js.map +1 -1
  65. package/dist/roap/turnDiscovery.js +3 -6
  66. package/dist/roap/turnDiscovery.js.map +1 -1
  67. package/dist/{common/errors/parameter.d.ts → types/common/errors/webinar-registration-error.d.ts} +4 -5
  68. package/dist/types/config.d.ts +2 -0
  69. package/dist/types/constants.d.ts +25 -0
  70. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  71. package/dist/types/controls-options-manager/index.d.ts +2 -1
  72. package/dist/types/controls-options-manager/types.d.ts +2 -0
  73. package/dist/types/index.d.ts +2 -1
  74. package/dist/types/locus-info/index.d.ts +9 -0
  75. package/dist/types/meeting/in-meeting-actions.d.ts +18 -0
  76. package/dist/types/meeting/index.d.ts +14 -3
  77. package/dist/types/meeting/locusMediaRequest.d.ts +2 -3
  78. package/dist/types/meeting/muteState.d.ts +2 -1
  79. package/dist/types/meeting/request.d.ts +2 -2
  80. package/dist/types/meeting/util.d.ts +2 -2
  81. package/dist/types/meeting-info/meeting-info-v2.d.ts +23 -0
  82. package/dist/types/meetings/index.d.ts +10 -1
  83. package/dist/types/members/index.d.ts +2 -1
  84. package/dist/types/members/util.d.ts +3 -1
  85. package/dist/types/metrics/constants.d.ts +1 -0
  86. package/dist/types/multistream/remoteMedia.d.ts +1 -0
  87. package/dist/types/reachability/clusterReachability.d.ts +1 -10
  88. package/dist/types/reachability/index.d.ts +74 -35
  89. package/dist/types/reachability/reachability.types.d.ts +64 -0
  90. package/dist/types/reachability/request.d.ts +5 -1
  91. package/dist/types/roap/request.d.ts +1 -13
  92. package/dist/webinar/index.js +32 -19
  93. package/dist/webinar/index.js.map +1 -1
  94. package/package.json +22 -22
  95. package/src/common/errors/webinar-registration-error.ts +27 -0
  96. package/src/config.ts +2 -0
  97. package/src/constants.ts +31 -0
  98. package/src/controls-options-manager/enums.ts +1 -0
  99. package/src/controls-options-manager/index.ts +19 -2
  100. package/src/controls-options-manager/types.ts +2 -0
  101. package/src/controls-options-manager/util.ts +12 -0
  102. package/src/index.ts +2 -0
  103. package/src/locus-info/controlsUtils.ts +46 -2
  104. package/src/locus-info/fullState.ts +1 -0
  105. package/src/locus-info/index.ts +60 -0
  106. package/src/locus-info/parser.ts +8 -1
  107. package/src/meeting/in-meeting-actions.ts +37 -0
  108. package/src/meeting/index.ts +154 -22
  109. package/src/meeting/locusMediaRequest.ts +4 -8
  110. package/src/meeting/muteState.ts +6 -2
  111. package/src/meeting/request.ts +4 -11
  112. package/src/meeting/util.ts +30 -6
  113. package/src/meeting-info/meeting-info-v2.ts +51 -0
  114. package/src/meetings/index.ts +68 -40
  115. package/src/members/index.ts +4 -2
  116. package/src/members/util.ts +3 -1
  117. package/src/metrics/constants.ts +1 -0
  118. package/src/multistream/remoteMedia.ts +5 -0
  119. package/src/reachability/clusterReachability.ts +1 -14
  120. package/src/reachability/index.ts +285 -77
  121. package/src/reachability/reachability.types.ts +85 -0
  122. package/src/reachability/request.ts +55 -30
  123. package/src/roap/index.ts +4 -5
  124. package/src/roap/request.ts +32 -44
  125. package/src/roap/turnDiscovery.ts +2 -4
  126. package/src/webinar/index.ts +31 -17
  127. package/test/unit/spec/controls-options-manager/index.js +56 -32
  128. package/test/unit/spec/controls-options-manager/util.js +44 -0
  129. package/test/unit/spec/locus-info/controlsUtils.js +80 -4
  130. package/test/unit/spec/locus-info/index.js +88 -2
  131. package/test/unit/spec/meeting/in-meeting-actions.ts +18 -0
  132. package/test/unit/spec/meeting/index.js +272 -82
  133. package/test/unit/spec/meeting/locusMediaRequest.ts +18 -11
  134. package/test/unit/spec/meeting/muteState.js +8 -4
  135. package/test/unit/spec/meeting/request.js +3 -26
  136. package/test/unit/spec/meeting/utils.js +69 -14
  137. package/test/unit/spec/meeting-info/meetinginfov2.js +37 -0
  138. package/test/unit/spec/meetings/index.js +32 -1
  139. package/test/unit/spec/members/index.js +25 -2
  140. package/test/unit/spec/members/request.js +37 -3
  141. package/test/unit/spec/members/utils.js +15 -1
  142. package/test/unit/spec/multistream/remoteMedia.ts +16 -2
  143. package/test/unit/spec/reachability/index.ts +265 -1
  144. package/test/unit/spec/reachability/request.js +56 -15
  145. package/test/unit/spec/roap/index.ts +1 -1
  146. package/test/unit/spec/roap/request.ts +51 -109
  147. package/test/unit/spec/roap/turnDiscovery.ts +202 -147
  148. package/test/unit/spec/webinar/index.ts +82 -16
  149. package/dist/annotation/annotation.types.d.ts +0 -42
  150. package/dist/annotation/constants.d.ts +0 -31
  151. package/dist/annotation/index.d.ts +0 -117
  152. package/dist/breakouts/breakout.d.ts +0 -8
  153. package/dist/breakouts/collection.d.ts +0 -5
  154. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  155. package/dist/breakouts/events.d.ts +0 -8
  156. package/dist/breakouts/index.d.ts +0 -5
  157. package/dist/breakouts/request.d.ts +0 -22
  158. package/dist/breakouts/utils.d.ts +0 -15
  159. package/dist/common/browser-detection.d.ts +0 -9
  160. package/dist/common/collection.d.ts +0 -48
  161. package/dist/common/config.d.ts +0 -2
  162. package/dist/common/errors/captcha-error.d.ts +0 -15
  163. package/dist/common/errors/intent-to-join.d.ts +0 -16
  164. package/dist/common/errors/join-meeting.d.ts +0 -17
  165. package/dist/common/errors/media.d.ts +0 -15
  166. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  167. package/dist/common/errors/password-error.d.ts +0 -15
  168. package/dist/common/errors/permission.d.ts +0 -14
  169. package/dist/common/errors/reclaim-host-role-error.js +0 -149
  170. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  171. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  172. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  173. package/dist/common/errors/reconnection-in-progress.js +0 -33
  174. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  175. package/dist/common/errors/reconnection.d.ts +0 -15
  176. package/dist/common/errors/stats.d.ts +0 -15
  177. package/dist/common/errors/webex-errors.d.ts +0 -93
  178. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  179. package/dist/common/events/events-scope.d.ts +0 -17
  180. package/dist/common/events/events.d.ts +0 -12
  181. package/dist/common/events/trigger-proxy.d.ts +0 -2
  182. package/dist/common/events/util.d.ts +0 -2
  183. package/dist/common/logs/logger-config.d.ts +0 -2
  184. package/dist/common/logs/logger-proxy.d.ts +0 -2
  185. package/dist/common/logs/request.d.ts +0 -36
  186. package/dist/common/queue.d.ts +0 -34
  187. package/dist/config.d.ts +0 -72
  188. package/dist/constants.d.ts +0 -1088
  189. package/dist/controls-options-manager/constants.d.ts +0 -4
  190. package/dist/controls-options-manager/enums.d.ts +0 -15
  191. package/dist/controls-options-manager/index.d.ts +0 -136
  192. package/dist/controls-options-manager/types.d.ts +0 -43
  193. package/dist/controls-options-manager/util.d.ts +0 -1
  194. package/dist/index.d.ts +0 -7
  195. package/dist/interceptors/index.d.ts +0 -2
  196. package/dist/interceptors/locusRetry.d.ts +0 -27
  197. package/dist/interpretation/collection.d.ts +0 -5
  198. package/dist/interpretation/index.d.ts +0 -5
  199. package/dist/interpretation/siLanguage.d.ts +0 -5
  200. package/dist/locus-info/controlsUtils.d.ts +0 -2
  201. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  202. package/dist/locus-info/fullState.d.ts +0 -2
  203. package/dist/locus-info/hostUtils.d.ts +0 -2
  204. package/dist/locus-info/index.d.ts +0 -322
  205. package/dist/locus-info/infoUtils.d.ts +0 -2
  206. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  207. package/dist/locus-info/parser.d.ts +0 -272
  208. package/dist/locus-info/selfUtils.d.ts +0 -2
  209. package/dist/media/index.d.ts +0 -34
  210. package/dist/media/properties.d.ts +0 -93
  211. package/dist/media/util.d.ts +0 -2
  212. package/dist/mediaQualityMetrics/config.d.ts +0 -241
  213. package/dist/mediaQualityMetrics/config.js +0 -502
  214. package/dist/mediaQualityMetrics/config.js.map +0 -1
  215. package/dist/meeting/effectsState.js +0 -260
  216. package/dist/meeting/effectsState.js.map +0 -1
  217. package/dist/meeting/in-meeting-actions.d.ts +0 -167
  218. package/dist/meeting/index.d.ts +0 -1825
  219. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  220. package/dist/meeting/muteState.d.ts +0 -178
  221. package/dist/meeting/request.d.ts +0 -295
  222. package/dist/meeting/request.type.d.ts +0 -11
  223. package/dist/meeting/state.d.ts +0 -9
  224. package/dist/meeting/util.d.ts +0 -119
  225. package/dist/meeting/voicea-meeting.d.ts +0 -16
  226. package/dist/meeting-info/collection.d.ts +0 -20
  227. package/dist/meeting-info/index.d.ts +0 -69
  228. package/dist/meeting-info/meeting-info-v2.d.ts +0 -123
  229. package/dist/meeting-info/request.d.ts +0 -22
  230. package/dist/meeting-info/util.d.ts +0 -2
  231. package/dist/meeting-info/utilv2.d.ts +0 -2
  232. package/dist/meetings/collection.d.ts +0 -40
  233. package/dist/meetings/index.d.ts +0 -390
  234. package/dist/meetings/meetings.types.d.ts +0 -4
  235. package/dist/meetings/request.d.ts +0 -27
  236. package/dist/meetings/util.d.ts +0 -18
  237. package/dist/member/index.d.ts +0 -160
  238. package/dist/member/member.types.js +0 -17
  239. package/dist/member/member.types.js.map +0 -1
  240. package/dist/member/types.d.ts +0 -32
  241. package/dist/member/util.d.ts +0 -2
  242. package/dist/members/collection.d.ts +0 -29
  243. package/dist/members/index.d.ts +0 -353
  244. package/dist/members/request.d.ts +0 -114
  245. package/dist/members/types.d.ts +0 -25
  246. package/dist/members/util.d.ts +0 -215
  247. package/dist/metrics/config.js +0 -276
  248. package/dist/metrics/config.js.map +0 -1
  249. package/dist/metrics/constants.d.ts +0 -70
  250. package/dist/metrics/index.d.ts +0 -45
  251. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  252. package/dist/multistream/receiveSlot.d.ts +0 -68
  253. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  254. package/dist/multistream/remoteMedia.d.ts +0 -72
  255. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  256. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  257. package/dist/multistream/sendSlotManager.d.ts +0 -69
  258. package/dist/networkQualityMonitor/index.d.ts +0 -70
  259. package/dist/networkQualityMonitor/index.js +0 -221
  260. package/dist/networkQualityMonitor/index.js.map +0 -1
  261. package/dist/peer-connection-manager/index.js +0 -671
  262. package/dist/peer-connection-manager/index.js.map +0 -1
  263. package/dist/peer-connection-manager/util.js +0 -109
  264. package/dist/peer-connection-manager/util.js.map +0 -1
  265. package/dist/personal-meeting-room/index.d.ts +0 -47
  266. package/dist/personal-meeting-room/request.d.ts +0 -14
  267. package/dist/personal-meeting-room/util.d.ts +0 -2
  268. package/dist/reachability/clusterReachability.d.ts +0 -109
  269. package/dist/reachability/index.d.ts +0 -105
  270. package/dist/reachability/request.d.ts +0 -39
  271. package/dist/reachability/util.d.ts +0 -8
  272. package/dist/reactions/constants.d.ts +0 -3
  273. package/dist/reactions/reactions.d.ts +0 -4
  274. package/dist/reactions/reactions.type.d.ts +0 -52
  275. package/dist/reconnection-manager/index.d.ts +0 -136
  276. package/dist/recording-controller/enums.d.ts +0 -7
  277. package/dist/recording-controller/index.d.ts +0 -207
  278. package/dist/recording-controller/util.d.ts +0 -14
  279. package/dist/roap/collection.js +0 -62
  280. package/dist/roap/collection.js.map +0 -1
  281. package/dist/roap/handler.js +0 -275
  282. package/dist/roap/handler.js.map +0 -1
  283. package/dist/roap/index.d.ts +0 -86
  284. package/dist/roap/request.d.ts +0 -39
  285. package/dist/roap/state.js +0 -126
  286. package/dist/roap/state.js.map +0 -1
  287. package/dist/roap/turnDiscovery.d.ts +0 -155
  288. package/dist/roap/util.js +0 -75
  289. package/dist/roap/util.js.map +0 -1
  290. package/dist/rtcMetrics/constants.d.ts +0 -4
  291. package/dist/rtcMetrics/constants.js.map +0 -1
  292. package/dist/rtcMetrics/index.d.ts +0 -61
  293. package/dist/rtcMetrics/index.js +0 -197
  294. package/dist/rtcMetrics/index.js.map +0 -1
  295. package/dist/statsAnalyzer/global.d.ts +0 -36
  296. package/dist/statsAnalyzer/global.js +0 -126
  297. package/dist/statsAnalyzer/global.js.map +0 -1
  298. package/dist/statsAnalyzer/index.d.ts +0 -217
  299. package/dist/statsAnalyzer/index.js +0 -1013
  300. package/dist/statsAnalyzer/index.js.map +0 -1
  301. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -48
  302. package/dist/statsAnalyzer/mqaUtil.js +0 -179
  303. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  304. package/dist/transcription/index.d.ts +0 -64
  305. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  306. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  307. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  308. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  309. package/dist/types/rtcMetrics/index.d.ts +0 -71
  310. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  311. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  312. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  313. package/dist/webinar/collection.d.ts +0 -16
  314. package/dist/webinar/index.d.ts +0 -5
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import {MEETINGS} from '../constants';
6
+ import ControlsOptionsUtil from '../controls-options-manager/util';
6
7
 
7
8
  /**
8
9
  * IInMeetingActions
@@ -64,6 +65,10 @@ interface IInMeetingActions {
64
65
  canUpdateShareControl?: boolean;
65
66
  canEnableViewTheParticipantsList?: boolean;
66
67
  canDisableViewTheParticipantsList?: boolean;
68
+ canEnableViewTheParticipantsListPanelist?: boolean;
69
+ canDisableViewTheParticipantsListPanelist?: boolean;
70
+ canEnableShowAttendeeCount?: boolean;
71
+ canDisableShowAttendeeCount?: boolean;
67
72
  canEnableRaiseHand?: boolean;
68
73
  canDisableRaiseHand?: boolean;
69
74
  canEnableVideo?: boolean;
@@ -83,6 +88,11 @@ interface IInMeetingActions {
83
88
  canShareWhiteBoard?: boolean;
84
89
  enforceVirtualBackground?: boolean;
85
90
  canPollingAndQA?: boolean;
91
+ canStartWebcast?: boolean;
92
+ canStopWebcast?: boolean;
93
+ canShowStageView?: boolean;
94
+ canEnableStageView?: boolean;
95
+ canDisableStageView?: boolean;
86
96
  }
87
97
 
88
98
  /**
@@ -201,6 +211,14 @@ export default class InMeetingActions implements IInMeetingActions {
201
211
 
202
212
  canDisableViewTheParticipantsList = null;
203
213
 
214
+ canEnableViewTheParticipantsListPanelist = null;
215
+
216
+ canDisableViewTheParticipantsListPanelist = null;
217
+
218
+ canEnableShowAttendeeCount = null;
219
+
220
+ canDisableShowAttendeeCount = null;
221
+
204
222
  canEnableRaiseHand = null;
205
223
 
206
224
  canDisableRaiseHand = null;
@@ -238,6 +256,16 @@ export default class InMeetingActions implements IInMeetingActions {
238
256
  canShareWhiteBoard = null;
239
257
 
240
258
  canPollingAndQA = null;
259
+
260
+ canStartWebcast = null;
261
+
262
+ canStopWebcast = null;
263
+
264
+ canShowStageView = null;
265
+
266
+ canEnableStageView = null;
267
+
268
+ canDisableStageView = null;
241
269
  /**
242
270
  * Returns all meeting action options
243
271
  * @returns {Object}
@@ -298,6 +326,10 @@ export default class InMeetingActions implements IInMeetingActions {
298
326
  canUpdateShareControl: this.canUpdateShareControl,
299
327
  canEnableViewTheParticipantsList: this.canEnableViewTheParticipantsList,
300
328
  canDisableViewTheParticipantsList: this.canDisableViewTheParticipantsList,
329
+ canEnableViewTheParticipantsListPanelist: this.canEnableViewTheParticipantsListPanelist,
330
+ canDisableViewTheParticipantsListPanelist: this.canDisableViewTheParticipantsListPanelist,
331
+ canEnableShowAttendeeCount: this.canEnableShowAttendeeCount,
332
+ canDisableShowAttendeeCount: this.canDisableShowAttendeeCount,
301
333
  canEnableRaiseHand: this.canEnableRaiseHand,
302
334
  canDisableRaiseHand: this.canDisableRaiseHand,
303
335
  canEnableVideo: this.canEnableVideo,
@@ -317,6 +349,11 @@ export default class InMeetingActions implements IInMeetingActions {
317
349
  supportHDV: this.supportHDV,
318
350
  canShareWhiteBoard: this.canShareWhiteBoard,
319
351
  canPollingAndQA: this.canPollingAndQA,
352
+ canStartWebcast: this.canStartWebcast,
353
+ canStopWebcast: this.canStopWebcast,
354
+ canShowStageView: this.canShowStageView,
355
+ canEnableStageView: this.canEnableStageView,
356
+ canDisableStageView: this.canDisableStageView,
320
357
  });
321
358
 
322
359
  /**
@@ -128,6 +128,7 @@ import {
128
128
  MeetingInfoV2PasswordError,
129
129
  MeetingInfoV2CaptchaError,
130
130
  MeetingInfoV2PolicyError,
131
+ MeetingInfoV2WebinarRegistrationError,
131
132
  } from '../meeting-info/meeting-info-v2';
132
133
  import {CSI, ReceiveSlotManager} from '../multistream/receiveSlotManager';
133
134
  import SendSlotManager from '../multistream/sendSlotManager';
@@ -156,6 +157,7 @@ import ControlsOptionsManager from '../controls-options-manager';
156
157
  import PermissionError from '../common/errors/permission';
157
158
  import {LocusMediaRequest} from './locusMediaRequest';
158
159
  import {ConnectionStateHandler, ConnectionStateEvent} from './connectionStateHandler';
160
+ import WebinarRegistrationError from '../common/errors/webinar-registration-error';
159
161
 
160
162
  // default callback so we don't call an undefined function, but in practice it should never be used
161
163
  const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
@@ -1759,8 +1761,16 @@ export default class Meeting extends StatelessWebexPlugin {
1759
1761
  if (err.meetingInfo) {
1760
1762
  this.meetingInfo = err.meetingInfo;
1761
1763
  }
1762
-
1763
1764
  throw new PermissionError();
1765
+ } else if (err instanceof MeetingInfoV2WebinarRegistrationError) {
1766
+ this.meetingInfoFailureReason = MEETING_INFO_FAILURE_REASON.WEBINAR_REGISTRATION;
1767
+ this.meetingInfoFailureCode = err.wbxAppApiCode;
1768
+
1769
+ if (err.meetingInfo) {
1770
+ this.meetingInfo = err.meetingInfo;
1771
+ }
1772
+
1773
+ throw new WebinarRegistrationError();
1764
1774
  } else if (err instanceof MeetingInfoV2PasswordError) {
1765
1775
  LoggerProxy.logger.info(
1766
1776
  // @ts-ignore
@@ -2004,6 +2014,7 @@ export default class Meeting extends StatelessWebexPlugin {
2004
2014
  this.setUpLocusInfoSelfListener();
2005
2015
  this.setUpLocusInfoMeetingListener();
2006
2016
  this.setUpLocusServicesListener();
2017
+ this.setUpLocusResourcesListener();
2007
2018
  // members update listeners
2008
2019
  this.setUpLocusFullStateListener();
2009
2020
  this.setUpLocusUrlListener();
@@ -2625,6 +2636,42 @@ export default class Meeting extends StatelessWebexPlugin {
2625
2636
  );
2626
2637
  });
2627
2638
 
2639
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_WEBCAST_CHANGED, ({state}) => {
2640
+ Trigger.trigger(
2641
+ this,
2642
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2643
+ EVENT_TRIGGERS.MEETING_CONTROLS_WEBCAST_UPDATED,
2644
+ {state}
2645
+ );
2646
+ });
2647
+
2648
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_FULL_CHANGED, ({state}) => {
2649
+ Trigger.trigger(
2650
+ this,
2651
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2652
+ EVENT_TRIGGERS.MEETING_CONTROLS_MEETING_FULL_UPDATED,
2653
+ {state}
2654
+ );
2655
+ });
2656
+
2657
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_PRACTICE_SESSION_STATUS_UPDATED, ({state}) => {
2658
+ Trigger.trigger(
2659
+ this,
2660
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2661
+ EVENT_TRIGGERS.MEETING_CONTROLS_PRACTICE_SESSION_STATUS_UPDATED,
2662
+ {state}
2663
+ );
2664
+ });
2665
+
2666
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_STAGE_VIEW_UPDATED, ({state}) => {
2667
+ Trigger.trigger(
2668
+ this,
2669
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2670
+ EVENT_TRIGGERS.MEETING_CONTROLS_STAGE_VIEW_UPDATED,
2671
+ {state}
2672
+ );
2673
+ });
2674
+
2628
2675
  this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_VIDEO_CHANGED, ({state}) => {
2629
2676
  Trigger.trigger(
2630
2677
  this,
@@ -2739,6 +2786,9 @@ export default class Meeting extends StatelessWebexPlugin {
2739
2786
  newShareStatus = SHARE_STATUS.NO_SHARE;
2740
2787
  }
2741
2788
 
2789
+ LoggerProxy.logger.info(
2790
+ `Meeting:index#setUpLocusInfoMediaInactiveListener --> this.shareStatus=${this.shareStatus} newShareStatus=${newShareStatus}`
2791
+ );
2742
2792
  if (newShareStatus !== this.shareStatus) {
2743
2793
  const oldShareStatus = this.shareStatus;
2744
2794
 
@@ -2983,10 +3033,20 @@ export default class Meeting extends StatelessWebexPlugin {
2983
3033
  this.breakouts.breakoutServiceUrlUpdate(payload?.services?.breakout?.url);
2984
3034
  this.annotation.approvalUrlUpdate(payload?.services?.approval?.url);
2985
3035
  this.simultaneousInterpretation.approvalUrlUpdate(payload?.services?.approval?.url);
2986
- this.webinar.webcastUrlUpdate(payload?.services?.webcast?.url);
2987
- this.webinar.webinarAttendeesSearchingUrlUpdate(
2988
- payload?.services?.webinarAttendeesSearching?.url
2989
- );
3036
+ });
3037
+ }
3038
+
3039
+ /**
3040
+ * Set up the locus info resources link listener
3041
+ * update the locusInfo for webcast instance url
3042
+ * @param {Object} payload - The event payload
3043
+ * @returns {undefined}
3044
+ * @private
3045
+ * @memberof Meeting
3046
+ */
3047
+ private setUpLocusResourcesListener() {
3048
+ this.locusInfo.on(LOCUSINFO.EVENTS.LINKS_RESOURCES, (payload) => {
3049
+ this.webinar.updateWebcastUrl(payload);
2990
3050
  });
2991
3051
  }
2992
3052
 
@@ -3091,7 +3151,7 @@ export default class Meeting extends StatelessWebexPlugin {
3091
3151
  private setUpLocusInfoSelfListener() {
3092
3152
  this.locusInfo.on(LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUIRED, (payload) => {
3093
3153
  if (this.audio) {
3094
- this.audio.handleServerLocalUnmuteRequired(this);
3154
+ this.audio.handleServerLocalUnmuteRequired(this, payload.unmuteAllowed);
3095
3155
  Trigger.trigger(
3096
3156
  this,
3097
3157
  {
@@ -3298,7 +3358,7 @@ export default class Meeting extends StatelessWebexPlugin {
3298
3358
  this.simultaneousInterpretation.updateCanManageInterpreters(
3299
3359
  payload.newRoles?.includes(SELF_ROLES.MODERATOR)
3300
3360
  );
3301
- this.webinar.updateCanManageWebcast(payload.newRoles?.includes(SELF_ROLES.MODERATOR));
3361
+ this.webinar.updateRoleChanged(payload);
3302
3362
  Trigger.trigger(
3303
3363
  this,
3304
3364
  {
@@ -3792,6 +3852,22 @@ export default class Meeting extends StatelessWebexPlugin {
3792
3852
  requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST],
3793
3853
  displayHints: this.userDisplayHints,
3794
3854
  }),
3855
+ canEnableViewTheParticipantsListPanelist: ControlsOptionsUtil.hasHints({
3856
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST],
3857
+ displayHints: this.userDisplayHints,
3858
+ }),
3859
+ canDisableViewTheParticipantsListPanelist: ControlsOptionsUtil.hasHints({
3860
+ requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST],
3861
+ displayHints: this.userDisplayHints,
3862
+ }),
3863
+ canEnableShowAttendeeCount: ControlsOptionsUtil.hasHints({
3864
+ requiredHints: [DISPLAY_HINTS.ENABLE_SHOW_ATTENDEE_COUNT],
3865
+ displayHints: this.userDisplayHints,
3866
+ }),
3867
+ canDisableShowAttendeeCount: ControlsOptionsUtil.hasHints({
3868
+ requiredHints: [DISPLAY_HINTS.DISABLE_SHOW_ATTENDEE_COUNT],
3869
+ displayHints: this.userDisplayHints,
3870
+ }),
3795
3871
  canEnableRaiseHand: ControlsOptionsUtil.hasHints({
3796
3872
  requiredHints: [DISPLAY_HINTS.ENABLE_RAISE_HAND],
3797
3873
  displayHints: this.userDisplayHints,
@@ -3808,6 +3884,26 @@ export default class Meeting extends StatelessWebexPlugin {
3808
3884
  requiredHints: [DISPLAY_HINTS.DISABLE_VIDEO],
3809
3885
  displayHints: this.userDisplayHints,
3810
3886
  }),
3887
+ canStartWebcast: ControlsOptionsUtil.hasHints({
3888
+ requiredHints: [DISPLAY_HINTS.WEBCAST_CONTROL_START],
3889
+ displayHints: this.userDisplayHints,
3890
+ }),
3891
+ canStopWebcast: ControlsOptionsUtil.hasHints({
3892
+ requiredHints: [DISPLAY_HINTS.WEBCAST_CONTROL_STOP],
3893
+ displayHints: this.userDisplayHints,
3894
+ }),
3895
+ canShowStageView: ControlsOptionsUtil.hasHints({
3896
+ requiredHints: [DISPLAY_HINTS.STAGE_VIEW_ACTIVE],
3897
+ displayHints: this.userDisplayHints,
3898
+ }),
3899
+ canEnableStageView: ControlsOptionsUtil.hasHints({
3900
+ requiredHints: [DISPLAY_HINTS.ENABLE_STAGE_VIEW],
3901
+ displayHints: this.userDisplayHints,
3902
+ }),
3903
+ canDisableStageView: ControlsOptionsUtil.hasHints({
3904
+ requiredHints: [DISPLAY_HINTS.DISABLE_STAGE_VIEW],
3905
+ displayHints: this.userDisplayHints,
3906
+ }),
3811
3907
  canShareFile:
3812
3908
  (ControlsOptionsUtil.hasHints({
3813
3909
  requiredHints: [DISPLAY_HINTS.SHARE_FILE],
@@ -4675,8 +4771,6 @@ export default class Meeting extends StatelessWebexPlugin {
4675
4771
  if (!joinResponse) {
4676
4772
  // This is the 1st attempt or a retry after join request failed -> we need to do a join with TURN discovery
4677
4773
 
4678
- // @ts-ignore
4679
- joinOptions.reachability = await this.webex.meetings.reachability.getReachabilityResults();
4680
4774
  const turnDiscoveryRequest = await this.roap.generateTurnDiscoveryRequestMessage(
4681
4775
  this,
4682
4776
  true
@@ -4808,6 +4902,8 @@ export default class Meeting extends StatelessWebexPlugin {
4808
4902
  );
4809
4903
  }
4810
4904
 
4905
+ this.cleanUpBeforeReconnection();
4906
+
4811
4907
  return this.reconnectionManager
4812
4908
  .reconnect(options, async () => {
4813
4909
  await this.waitForRemoteSDPAnswer();
@@ -6225,7 +6321,7 @@ export default class Meeting extends StatelessWebexPlugin {
6225
6321
  this.mediaProperties.webrtcMediaConnection.on(
6226
6322
  MediaConnectionEventNames.ICE_CANDIDATE,
6227
6323
  (event) => {
6228
- if (event.candidate) {
6324
+ if (event.candidate && event.candidate.candidate && event.candidate.candidate.length > 0) {
6229
6325
  this.iceCandidatesCount += 1;
6230
6326
  }
6231
6327
  }
@@ -6936,6 +7032,23 @@ export default class Meeting extends StatelessWebexPlugin {
6936
7032
  }
6937
7033
  }
6938
7034
 
7035
+ private async cleanUpBeforeReconnection(): Promise<void> {
7036
+ try {
7037
+ // when media fails, we want to upload a webrtc dump to see whats going on
7038
+ // this function is async, but returns once the stats have been gathered
7039
+ await this.forceSendStatsReport({callFrom: 'cleanUpBeforeReconnection'});
7040
+
7041
+ if (this.statsAnalyzer) {
7042
+ await this.statsAnalyzer.stopAnalyzer();
7043
+ }
7044
+ } catch (error) {
7045
+ LoggerProxy.logger.error(
7046
+ 'Meeting:index#cleanUpBeforeReconnection --> Error during cleanup: ',
7047
+ error
7048
+ );
7049
+ }
7050
+ }
7051
+
6939
7052
  /**
6940
7053
  * Creates an instance of LocusMediaRequest for this meeting - it is needed for doing any calls
6941
7054
  * to Locus /media API (these are used for sending Roap messages and updating audio/video mute status).
@@ -7027,7 +7140,7 @@ export default class Meeting extends StatelessWebexPlugin {
7027
7140
  shareAudioEnabled = true,
7028
7141
  shareVideoEnabled = true,
7029
7142
  remoteMediaManagerConfig,
7030
- bundlePolicy,
7143
+ bundlePolicy = 'max-bundle',
7031
7144
  } = options;
7032
7145
 
7033
7146
  this.allowMediaInLobby = options?.allowMediaInLobby;
@@ -7914,18 +8027,21 @@ export default class Meeting extends StatelessWebexPlugin {
7914
8027
  * @param {boolean} mutedEnabled
7915
8028
  * @param {boolean} disallowUnmuteEnabled
7916
8029
  * @param {boolean} muteOnEntryEnabled
8030
+ * @param {array} roles
7917
8031
  * @public
7918
8032
  * @memberof Meeting
7919
8033
  */
7920
8034
  public setMuteAll(
7921
8035
  mutedEnabled: boolean,
7922
8036
  disallowUnmuteEnabled: boolean,
7923
- muteOnEntryEnabled: boolean
8037
+ muteOnEntryEnabled: boolean,
8038
+ roles: Array<string>
7924
8039
  ) {
7925
8040
  return this.controlsOptionsManager.setMuteAll(
7926
8041
  mutedEnabled,
7927
8042
  disallowUnmuteEnabled,
7928
- muteOnEntryEnabled
8043
+ muteOnEntryEnabled,
8044
+ roles
7929
8045
  );
7930
8046
  }
7931
8047
 
@@ -8182,6 +8298,9 @@ export default class Meeting extends StatelessWebexPlugin {
8182
8298
  * @returns {undefined}
8183
8299
  */
8184
8300
  private handleShareAudioStreamEnded = async () => {
8301
+ LoggerProxy.logger.info(
8302
+ `Meeting:index#handleShareAudioStreamEnded --> audio share stream ended`
8303
+ );
8185
8304
  // current share audio stream has ended, but there might be an active
8186
8305
  // share video stream. we only leave from wireless share if share has
8187
8306
  // completely ended, which means no share audio or video streams active
@@ -8224,6 +8343,9 @@ export default class Meeting extends StatelessWebexPlugin {
8224
8343
  * @returns {undefined}
8225
8344
  */
8226
8345
  private handleShareVideoStreamEnded = async () => {
8346
+ LoggerProxy.logger.info(
8347
+ `Meeting:index#handleShareVideoStreamEnded --> video share stream ended`
8348
+ );
8227
8349
  // current share video stream has ended, but there might be an active
8228
8350
  // share audio stream. we only leave from wireless share if share has
8229
8351
  // completely ended, which means no share audio or video streams active
@@ -8712,6 +8834,9 @@ export default class Meeting extends StatelessWebexPlugin {
8712
8834
  * @returns {Promise}
8713
8835
  */
8714
8836
  async publishStreams(streams: LocalStreams): Promise<void> {
8837
+ LoggerProxy.logger.info(
8838
+ `Meeting:index#publishStreams --> called with: ${JSON.stringify(streams)}`
8839
+ );
8715
8840
  this.checkMediaConnection();
8716
8841
  if (
8717
8842
  !streams.microphone &&
@@ -8723,15 +8848,19 @@ export default class Meeting extends StatelessWebexPlugin {
8723
8848
  return;
8724
8849
  }
8725
8850
 
8726
- if (
8727
- streams?.microphone?.readyState === 'ended' ||
8728
- streams?.camera?.readyState === 'ended' ||
8729
- streams?.screenShare?.audio?.readyState === 'ended' ||
8730
- streams?.screenShare?.video?.readyState === 'ended'
8731
- ) {
8732
- throw new Error(
8733
- `Attempted to publish stream with ended readyState, correlationId=${this.correlationId}`
8734
- );
8851
+ const streamChecks = [
8852
+ {stream: streams?.microphone, name: 'microphone'},
8853
+ {stream: streams?.camera, name: 'camera'},
8854
+ {stream: streams?.screenShare?.audio, name: 'screenShare audio'},
8855
+ {stream: streams?.screenShare?.video, name: 'screenShare video'},
8856
+ ];
8857
+
8858
+ for (const {stream, name} of streamChecks) {
8859
+ if (stream?.readyState === 'ended') {
8860
+ throw new Error(
8861
+ `Attempted to publish ${name} stream with ended readyState, correlationId=${this.correlationId}`
8862
+ );
8863
+ }
8735
8864
  }
8736
8865
 
8737
8866
  let floorRequestNeeded = false;
@@ -8793,6 +8922,9 @@ export default class Meeting extends StatelessWebexPlugin {
8793
8922
  * @returns {Promise}
8794
8923
  */
8795
8924
  async unpublishStreams(streams: LocalStream[]): Promise<void> {
8925
+ LoggerProxy.logger.info(
8926
+ `Meeting:index#unpublishStreams --> called with: ${JSON.stringify(streams)}`
8927
+ );
8796
8928
  this.checkMediaConnection();
8797
8929
 
8798
8930
  const promises = [];
@@ -2,8 +2,9 @@
2
2
  import {defer} from 'lodash';
3
3
  import {Defer} from '@webex/common';
4
4
  import {WebexPlugin} from '@webex/webex-core';
5
- import {MEDIA, HTTP_VERBS, ROAP, IP_VERSION} from '../constants';
5
+ import {MEDIA, HTTP_VERBS, ROAP} from '../constants';
6
6
  import LoggerProxy from '../common/logs/logger-proxy';
7
+ import {ClientMediaPreferences} from '../reachability/reachability.types';
7
8
 
8
9
  export type MediaRequestType = 'RoapMessage' | 'LocalMute';
9
10
  export type RequestResult = any;
@@ -14,9 +15,8 @@ export type RoapRequest = {
14
15
  mediaId: string;
15
16
  roapMessage: any;
16
17
  reachability: any;
18
+ clientMediaPreferences: ClientMediaPreferences;
17
19
  sequence?: any;
18
- joinCookie: any; // any, because this is opaque to the client, we pass whatever object we got from one backend component (Orpheus) to the other (Locus)
19
- ipVersion?: IP_VERSION;
20
20
  };
21
21
 
22
22
  export type LocalMuteRequest = {
@@ -202,10 +202,6 @@ export class LocusMediaRequest extends WebexPlugin {
202
202
  const body: any = {
203
203
  device: this.config.device,
204
204
  correlationId: this.config.correlationId,
205
- clientMediaPreferences: {
206
- preferTranscoding: this.config.preferTranscoding,
207
- ipver: request.type === 'RoapMessage' ? request.ipVersion : undefined,
208
- },
209
205
  };
210
206
 
211
207
  const localMedias: any = {
@@ -223,7 +219,7 @@ export class LocusMediaRequest extends WebexPlugin {
223
219
  case 'RoapMessage':
224
220
  localMedias.roapMessage = request.roapMessage;
225
221
  localMedias.reachability = request.reachability;
226
- body.clientMediaPreferences.joinCookie = request.joinCookie;
222
+ body.clientMediaPreferences = request.clientMediaPreferences;
227
223
 
228
224
  // @ts-ignore
229
225
  this.webex.internal.newMetrics.submitClientEvent({
@@ -394,21 +394,25 @@ export class MuteState {
394
394
  * @public
395
395
  * @memberof MuteState
396
396
  * @param {Object} [meeting] the meeting object
397
+ * @param {Boolean} [unmuteAllowed] whether the user is allowed to unmute self
397
398
  * @returns {undefined}
398
399
  */
399
- public handleServerLocalUnmuteRequired(meeting?: any) {
400
+ public handleServerLocalUnmuteRequired(meeting: any, unmuteAllowed: boolean) {
400
401
  if (!this.state.client.enabled) {
401
402
  LoggerProxy.logger.warn(
402
403
  `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received while ${this.type} is disabled -> local unmute will not result in ${this.type} being sent`
403
404
  );
404
405
  } else {
405
406
  LoggerProxy.logger.info(
406
- `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute`
407
+ `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute (unmuteAllowed=${unmuteAllowed})`
407
408
  );
408
409
  }
409
410
 
410
411
  // todo: I'm seeing "you can now unmute yourself " popup when this happens - but same thing happens on web.w.c so we can ignore for now
411
412
  this.state.server.remoteMute = false;
413
+ this.state.server.unmuteAllowed = unmuteAllowed;
414
+
415
+ this.applyUnmuteAllowedToStream(meeting);
412
416
 
413
417
  // change user mute state to false, but keep localMute true if overall mute state is still true
414
418
  this.muteLocalStream(meeting, false, 'localUnmuteRequired');
@@ -26,11 +26,11 @@ import {
26
26
  SEND_DTMF_ENDPOINT,
27
27
  _SLIDES_,
28
28
  ANNOTATION,
29
- IP_VERSION,
30
29
  } from '../constants';
31
30
  import {SendReactionOptions, ToggleReactionsOptions} from './request.type';
32
31
  import MeetingUtil from './util';
33
32
  import {AnnotationInfo} from '../annotation/annotation.types';
33
+ import {ClientMediaPreferences} from '../reachability/reachability.types';
34
34
 
35
35
  /**
36
36
  * @class MeetingRequest
@@ -128,8 +128,8 @@ export default class MeetingRequest extends StatelessWebexPlugin {
128
128
  locale?: string;
129
129
  deviceCapabilities?: Array<string>;
130
130
  liveAnnotationSupported: boolean;
131
- ipVersion?: IP_VERSION;
132
131
  alias?: string;
132
+ clientMediaPreferences: ClientMediaPreferences;
133
133
  }) {
134
134
  const {
135
135
  asResourceOccupant,
@@ -147,12 +147,11 @@ export default class MeetingRequest extends StatelessWebexPlugin {
147
147
  moveToResource,
148
148
  roapMessage,
149
149
  reachability,
150
- preferTranscoding,
151
150
  breakoutsSupported,
152
151
  locale,
153
152
  deviceCapabilities = [],
154
153
  liveAnnotationSupported,
155
- ipVersion,
154
+ clientMediaPreferences,
156
155
  alias,
157
156
  } = options;
158
157
 
@@ -160,8 +159,6 @@ export default class MeetingRequest extends StatelessWebexPlugin {
160
159
 
161
160
  let url = '';
162
161
 
163
- const joinCookie = await this.getJoinCookie();
164
-
165
162
  const body: any = {
166
163
  asResourceOccupant,
167
164
  device: {
@@ -176,11 +173,7 @@ export default class MeetingRequest extends StatelessWebexPlugin {
176
173
  allowMultiDevice: true,
177
174
  ensureConversation: ensureConversation || false,
178
175
  supportsNativeLobby: 1,
179
- clientMediaPreferences: {
180
- preferTranscoding: preferTranscoding ?? true,
181
- joinCookie,
182
- ipver: ipVersion,
183
- },
176
+ clientMediaPreferences,
184
177
  };
185
178
 
186
179
  if (alias) {
@@ -89,8 +89,12 @@ const MeetingUtil = {
89
89
  getIpVersion(webex: any): IP_VERSION | undefined {
90
90
  const {supportsIpV4, supportsIpV6} = webex.internal.device.ipNetworkDetector;
91
91
 
92
- if (BrowserDetection().isBrowser('firefox')) {
93
- // our ipv6 solution relies on FQDN ICE candidates, but Firefox doesn't support them,
92
+ if (
93
+ !webex.config.meetings.backendIpv6NativeSupport &&
94
+ BrowserDetection().isBrowser('firefox')
95
+ ) {
96
+ // when backend doesn't support native ipv6,
97
+ // then our NAT64/DNS64 based solution relies on FQDN ICE candidates, but Firefox doesn't support them,
94
98
  // see https://bugzilla.mozilla.org/show_bug.cgi?id=1713128
95
99
  // so for Firefox we don't want the backend to activate the "ipv6 feature"
96
100
  return undefined;
@@ -111,7 +115,7 @@ const MeetingUtil = {
111
115
  return IP_VERSION.unknown;
112
116
  },
113
117
 
114
- joinMeeting: (meeting, options) => {
118
+ joinMeeting: async (meeting, options) => {
115
119
  if (!meeting) {
116
120
  return Promise.reject(new ParameterError('You need a meeting object.'));
117
121
  }
@@ -123,6 +127,27 @@ const MeetingUtil = {
123
127
  options: {meetingId: meeting.id},
124
128
  });
125
129
 
130
+ let reachability;
131
+ let clientMediaPreferences = {
132
+ // bare minimum fallback value that should allow us to join
133
+ ipver: IP_VERSION.unknown,
134
+ joinCookie: undefined,
135
+ preferTranscoding: !meeting.isMultistream,
136
+ };
137
+
138
+ try {
139
+ clientMediaPreferences = await webex.meetings.reachability.getClientMediaPreferences(
140
+ meeting.isMultistream,
141
+ MeetingUtil.getIpVersion(webex)
142
+ );
143
+ reachability = await webex.meetings.reachability.getReachabilityReportToAttachToRoap();
144
+ } catch (e) {
145
+ LoggerProxy.logger.error(
146
+ 'Meeting:util#joinMeeting --> Error getting reachability or clientMediaPreferences:',
147
+ e
148
+ );
149
+ }
150
+
126
151
  // eslint-disable-next-line no-warning-comments
127
152
  // TODO: check if the meeting is in JOINING state
128
153
  // if Joining state termintate the request as user might click multiple times
@@ -134,20 +159,19 @@ const MeetingUtil = {
134
159
  locusUrl: meeting.locusUrl,
135
160
  locusClusterUrl: meeting.meetingInfo?.locusClusterUrl,
136
161
  correlationId: meeting.correlationId,
137
- reachability: options.reachability,
162
+ reachability,
138
163
  roapMessage: options.roapMessage,
139
164
  permissionToken: meeting.permissionToken,
140
165
  resourceId: options.resourceId || null,
141
166
  moderator: options.moderator,
142
167
  pin: options.pin,
143
168
  moveToResource: options.moveToResource,
144
- preferTranscoding: !meeting.isMultistream,
145
169
  asResourceOccupant: options.asResourceOccupant,
146
170
  breakoutsSupported: options.breakoutsSupported,
147
171
  locale: options.locale,
148
172
  deviceCapabilities: options.deviceCapabilities,
149
173
  liveAnnotationSupported: options.liveAnnotationSupported,
150
- ipVersion: MeetingUtil.getIpVersion(meeting.getWebexObject()),
174
+ clientMediaPreferences,
151
175
  })
152
176
  .then((res) => {
153
177
  const parsed = MeetingUtil.parseLocusJoin(res);