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

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 (329) 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 +4 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/constants.js +40 -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 +29 -1
  30. package/dist/meeting/in-meeting-actions.js.map +1 -1
  31. package/dist/meeting/index.js +786 -528
  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 +98 -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 +29 -2
  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 +13 -7
  48. package/dist/members/util.js.map +1 -1
  49. package/dist/metrics/constants.js +4 -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 +12 -15
  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/recording-controller/enums.js +8 -4
  62. package/dist/recording-controller/enums.js.map +1 -1
  63. package/dist/recording-controller/index.js +18 -9
  64. package/dist/recording-controller/index.js.map +1 -1
  65. package/dist/recording-controller/util.js +13 -9
  66. package/dist/recording-controller/util.js.map +1 -1
  67. package/dist/roap/index.js +5 -7
  68. package/dist/roap/index.js.map +1 -1
  69. package/dist/roap/request.js +45 -79
  70. package/dist/roap/request.js.map +1 -1
  71. package/dist/roap/turnDiscovery.js +3 -6
  72. package/dist/roap/turnDiscovery.js.map +1 -1
  73. package/dist/{common/errors/parameter.d.ts → types/common/errors/webinar-registration-error.d.ts} +4 -5
  74. package/dist/types/config.d.ts +3 -0
  75. package/dist/types/constants.d.ts +33 -0
  76. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  77. package/dist/types/controls-options-manager/index.d.ts +2 -1
  78. package/dist/types/controls-options-manager/types.d.ts +2 -0
  79. package/dist/types/index.d.ts +2 -1
  80. package/dist/types/locus-info/index.d.ts +9 -0
  81. package/dist/types/meeting/in-meeting-actions.d.ts +28 -0
  82. package/dist/types/meeting/index.d.ts +34 -3
  83. package/dist/types/meeting/locusMediaRequest.d.ts +2 -3
  84. package/dist/types/meeting/muteState.d.ts +2 -1
  85. package/dist/types/meeting/request.d.ts +2 -2
  86. package/dist/types/meeting/util.d.ts +2 -2
  87. package/dist/types/meeting-info/meeting-info-v2.d.ts +23 -0
  88. package/dist/types/meetings/index.d.ts +13 -1
  89. package/dist/types/members/index.d.ts +2 -1
  90. package/dist/types/members/util.d.ts +5 -1
  91. package/dist/types/metrics/constants.d.ts +3 -0
  92. package/dist/types/multistream/remoteMedia.d.ts +1 -0
  93. package/dist/types/reachability/clusterReachability.d.ts +1 -10
  94. package/dist/types/reachability/index.d.ts +74 -35
  95. package/dist/types/reachability/reachability.types.d.ts +64 -0
  96. package/dist/types/reachability/request.d.ts +5 -1
  97. package/dist/types/recording-controller/enums.d.ts +5 -2
  98. package/dist/types/recording-controller/index.d.ts +1 -0
  99. package/dist/types/recording-controller/util.d.ts +2 -1
  100. package/dist/types/roap/request.d.ts +1 -13
  101. package/dist/webinar/index.js +64 -19
  102. package/dist/webinar/index.js.map +1 -1
  103. package/package.json +22 -22
  104. package/src/common/errors/webinar-registration-error.ts +27 -0
  105. package/src/config.ts +3 -0
  106. package/src/constants.ts +41 -0
  107. package/src/controls-options-manager/enums.ts +1 -0
  108. package/src/controls-options-manager/index.ts +19 -2
  109. package/src/controls-options-manager/types.ts +2 -0
  110. package/src/controls-options-manager/util.ts +12 -0
  111. package/src/index.ts +2 -0
  112. package/src/locus-info/controlsUtils.ts +46 -2
  113. package/src/locus-info/fullState.ts +1 -0
  114. package/src/locus-info/index.ts +60 -0
  115. package/src/locus-info/parser.ts +8 -1
  116. package/src/meeting/in-meeting-actions.ts +58 -0
  117. package/src/meeting/index.ts +247 -22
  118. package/src/meeting/locusMediaRequest.ts +4 -8
  119. package/src/meeting/muteState.ts +6 -2
  120. package/src/meeting/request.ts +4 -11
  121. package/src/meeting/util.ts +31 -6
  122. package/src/meeting-info/meeting-info-v2.ts +51 -0
  123. package/src/meetings/index.ts +74 -40
  124. package/src/members/index.ts +4 -2
  125. package/src/members/util.ts +4 -1
  126. package/src/metrics/constants.ts +3 -0
  127. package/src/multistream/remoteMedia.ts +5 -0
  128. package/src/reachability/clusterReachability.ts +5 -15
  129. package/src/reachability/index.ts +285 -77
  130. package/src/reachability/reachability.types.ts +85 -0
  131. package/src/reachability/request.ts +55 -30
  132. package/src/recording-controller/enums.ts +5 -2
  133. package/src/recording-controller/index.ts +17 -4
  134. package/src/recording-controller/util.ts +20 -5
  135. package/src/roap/index.ts +4 -5
  136. package/src/roap/request.ts +32 -44
  137. package/src/roap/turnDiscovery.ts +2 -4
  138. package/src/webinar/index.ts +62 -16
  139. package/test/unit/spec/controls-options-manager/index.js +56 -32
  140. package/test/unit/spec/controls-options-manager/util.js +44 -0
  141. package/test/unit/spec/locus-info/controlsUtils.js +80 -4
  142. package/test/unit/spec/locus-info/index.js +88 -2
  143. package/test/unit/spec/meeting/in-meeting-actions.ts +31 -1
  144. package/test/unit/spec/meeting/index.js +346 -82
  145. package/test/unit/spec/meeting/locusMediaRequest.ts +18 -11
  146. package/test/unit/spec/meeting/muteState.js +8 -4
  147. package/test/unit/spec/meeting/request.js +3 -26
  148. package/test/unit/spec/meeting/utils.js +71 -14
  149. package/test/unit/spec/meeting-info/meetinginfov2.js +37 -0
  150. package/test/unit/spec/meetings/index.js +41 -6
  151. package/test/unit/spec/members/index.js +25 -2
  152. package/test/unit/spec/members/request.js +37 -3
  153. package/test/unit/spec/members/utils.js +110 -1
  154. package/test/unit/spec/multistream/remoteMedia.ts +16 -2
  155. package/test/unit/spec/reachability/clusterReachability.ts +7 -0
  156. package/test/unit/spec/reachability/index.ts +265 -1
  157. package/test/unit/spec/reachability/request.js +56 -15
  158. package/test/unit/spec/recording-controller/index.js +61 -5
  159. package/test/unit/spec/recording-controller/util.js +39 -3
  160. package/test/unit/spec/roap/index.ts +1 -1
  161. package/test/unit/spec/roap/request.ts +51 -109
  162. package/test/unit/spec/roap/turnDiscovery.ts +202 -147
  163. package/test/unit/spec/webinar/index.ts +128 -15
  164. package/dist/annotation/annotation.types.d.ts +0 -42
  165. package/dist/annotation/constants.d.ts +0 -31
  166. package/dist/annotation/index.d.ts +0 -117
  167. package/dist/breakouts/breakout.d.ts +0 -8
  168. package/dist/breakouts/collection.d.ts +0 -5
  169. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  170. package/dist/breakouts/events.d.ts +0 -8
  171. package/dist/breakouts/index.d.ts +0 -5
  172. package/dist/breakouts/request.d.ts +0 -22
  173. package/dist/breakouts/utils.d.ts +0 -15
  174. package/dist/common/browser-detection.d.ts +0 -9
  175. package/dist/common/collection.d.ts +0 -48
  176. package/dist/common/config.d.ts +0 -2
  177. package/dist/common/errors/captcha-error.d.ts +0 -15
  178. package/dist/common/errors/intent-to-join.d.ts +0 -16
  179. package/dist/common/errors/join-meeting.d.ts +0 -17
  180. package/dist/common/errors/media.d.ts +0 -15
  181. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  182. package/dist/common/errors/password-error.d.ts +0 -15
  183. package/dist/common/errors/permission.d.ts +0 -14
  184. package/dist/common/errors/reclaim-host-role-error.js +0 -149
  185. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  186. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  187. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  188. package/dist/common/errors/reconnection-in-progress.js +0 -33
  189. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  190. package/dist/common/errors/reconnection.d.ts +0 -15
  191. package/dist/common/errors/stats.d.ts +0 -15
  192. package/dist/common/errors/webex-errors.d.ts +0 -93
  193. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  194. package/dist/common/events/events-scope.d.ts +0 -17
  195. package/dist/common/events/events.d.ts +0 -12
  196. package/dist/common/events/trigger-proxy.d.ts +0 -2
  197. package/dist/common/events/util.d.ts +0 -2
  198. package/dist/common/logs/logger-config.d.ts +0 -2
  199. package/dist/common/logs/logger-proxy.d.ts +0 -2
  200. package/dist/common/logs/request.d.ts +0 -36
  201. package/dist/common/queue.d.ts +0 -34
  202. package/dist/config.d.ts +0 -72
  203. package/dist/constants.d.ts +0 -1088
  204. package/dist/controls-options-manager/constants.d.ts +0 -4
  205. package/dist/controls-options-manager/enums.d.ts +0 -15
  206. package/dist/controls-options-manager/index.d.ts +0 -136
  207. package/dist/controls-options-manager/types.d.ts +0 -43
  208. package/dist/controls-options-manager/util.d.ts +0 -1
  209. package/dist/index.d.ts +0 -7
  210. package/dist/interceptors/index.d.ts +0 -2
  211. package/dist/interceptors/locusRetry.d.ts +0 -27
  212. package/dist/interpretation/collection.d.ts +0 -5
  213. package/dist/interpretation/index.d.ts +0 -5
  214. package/dist/interpretation/siLanguage.d.ts +0 -5
  215. package/dist/locus-info/controlsUtils.d.ts +0 -2
  216. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  217. package/dist/locus-info/fullState.d.ts +0 -2
  218. package/dist/locus-info/hostUtils.d.ts +0 -2
  219. package/dist/locus-info/index.d.ts +0 -322
  220. package/dist/locus-info/infoUtils.d.ts +0 -2
  221. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  222. package/dist/locus-info/parser.d.ts +0 -272
  223. package/dist/locus-info/selfUtils.d.ts +0 -2
  224. package/dist/media/index.d.ts +0 -34
  225. package/dist/media/properties.d.ts +0 -93
  226. package/dist/media/util.d.ts +0 -2
  227. package/dist/mediaQualityMetrics/config.d.ts +0 -241
  228. package/dist/mediaQualityMetrics/config.js +0 -502
  229. package/dist/mediaQualityMetrics/config.js.map +0 -1
  230. package/dist/meeting/effectsState.js +0 -260
  231. package/dist/meeting/effectsState.js.map +0 -1
  232. package/dist/meeting/in-meeting-actions.d.ts +0 -167
  233. package/dist/meeting/index.d.ts +0 -1825
  234. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  235. package/dist/meeting/muteState.d.ts +0 -178
  236. package/dist/meeting/request.d.ts +0 -295
  237. package/dist/meeting/request.type.d.ts +0 -11
  238. package/dist/meeting/state.d.ts +0 -9
  239. package/dist/meeting/util.d.ts +0 -119
  240. package/dist/meeting/voicea-meeting.d.ts +0 -16
  241. package/dist/meeting-info/collection.d.ts +0 -20
  242. package/dist/meeting-info/index.d.ts +0 -69
  243. package/dist/meeting-info/meeting-info-v2.d.ts +0 -123
  244. package/dist/meeting-info/request.d.ts +0 -22
  245. package/dist/meeting-info/util.d.ts +0 -2
  246. package/dist/meeting-info/utilv2.d.ts +0 -2
  247. package/dist/meetings/collection.d.ts +0 -40
  248. package/dist/meetings/index.d.ts +0 -390
  249. package/dist/meetings/meetings.types.d.ts +0 -4
  250. package/dist/meetings/request.d.ts +0 -27
  251. package/dist/meetings/util.d.ts +0 -18
  252. package/dist/member/index.d.ts +0 -160
  253. package/dist/member/member.types.js +0 -17
  254. package/dist/member/member.types.js.map +0 -1
  255. package/dist/member/types.d.ts +0 -32
  256. package/dist/member/util.d.ts +0 -2
  257. package/dist/members/collection.d.ts +0 -29
  258. package/dist/members/index.d.ts +0 -353
  259. package/dist/members/request.d.ts +0 -114
  260. package/dist/members/types.d.ts +0 -25
  261. package/dist/members/util.d.ts +0 -215
  262. package/dist/metrics/config.js +0 -276
  263. package/dist/metrics/config.js.map +0 -1
  264. package/dist/metrics/constants.d.ts +0 -70
  265. package/dist/metrics/index.d.ts +0 -45
  266. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  267. package/dist/multistream/receiveSlot.d.ts +0 -68
  268. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  269. package/dist/multistream/remoteMedia.d.ts +0 -72
  270. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  271. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  272. package/dist/multistream/sendSlotManager.d.ts +0 -69
  273. package/dist/networkQualityMonitor/index.d.ts +0 -70
  274. package/dist/networkQualityMonitor/index.js +0 -221
  275. package/dist/networkQualityMonitor/index.js.map +0 -1
  276. package/dist/peer-connection-manager/index.js +0 -671
  277. package/dist/peer-connection-manager/index.js.map +0 -1
  278. package/dist/peer-connection-manager/util.js +0 -109
  279. package/dist/peer-connection-manager/util.js.map +0 -1
  280. package/dist/personal-meeting-room/index.d.ts +0 -47
  281. package/dist/personal-meeting-room/request.d.ts +0 -14
  282. package/dist/personal-meeting-room/util.d.ts +0 -2
  283. package/dist/reachability/clusterReachability.d.ts +0 -109
  284. package/dist/reachability/index.d.ts +0 -105
  285. package/dist/reachability/request.d.ts +0 -39
  286. package/dist/reachability/util.d.ts +0 -8
  287. package/dist/reactions/constants.d.ts +0 -3
  288. package/dist/reactions/reactions.d.ts +0 -4
  289. package/dist/reactions/reactions.type.d.ts +0 -52
  290. package/dist/reconnection-manager/index.d.ts +0 -136
  291. package/dist/recording-controller/enums.d.ts +0 -7
  292. package/dist/recording-controller/index.d.ts +0 -207
  293. package/dist/recording-controller/util.d.ts +0 -14
  294. package/dist/roap/collection.js +0 -62
  295. package/dist/roap/collection.js.map +0 -1
  296. package/dist/roap/handler.js +0 -275
  297. package/dist/roap/handler.js.map +0 -1
  298. package/dist/roap/index.d.ts +0 -86
  299. package/dist/roap/request.d.ts +0 -39
  300. package/dist/roap/state.js +0 -126
  301. package/dist/roap/state.js.map +0 -1
  302. package/dist/roap/turnDiscovery.d.ts +0 -155
  303. package/dist/roap/util.js +0 -75
  304. package/dist/roap/util.js.map +0 -1
  305. package/dist/rtcMetrics/constants.d.ts +0 -4
  306. package/dist/rtcMetrics/constants.js.map +0 -1
  307. package/dist/rtcMetrics/index.d.ts +0 -61
  308. package/dist/rtcMetrics/index.js +0 -197
  309. package/dist/rtcMetrics/index.js.map +0 -1
  310. package/dist/statsAnalyzer/global.d.ts +0 -36
  311. package/dist/statsAnalyzer/global.js +0 -126
  312. package/dist/statsAnalyzer/global.js.map +0 -1
  313. package/dist/statsAnalyzer/index.d.ts +0 -217
  314. package/dist/statsAnalyzer/index.js +0 -1013
  315. package/dist/statsAnalyzer/index.js.map +0 -1
  316. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -48
  317. package/dist/statsAnalyzer/mqaUtil.js +0 -179
  318. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  319. package/dist/transcription/index.d.ts +0 -64
  320. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  321. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  322. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  323. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  324. package/dist/types/rtcMetrics/index.d.ts +0 -71
  325. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  326. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  327. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  328. package/dist/webinar/collection.d.ts +0 -16
  329. package/dist/webinar/index.d.ts +0 -5
@@ -5,6 +5,7 @@ import jwtDecode from 'jwt-decode';
5
5
  import {StatelessWebexPlugin} from '@webex/webex-core';
6
6
  // @ts-ignore - Types not available for @webex/common
7
7
  import {Defer} from '@webex/common';
8
+ import {safeSetTimeout, safeSetInterval} from '@webex/common-timers';
8
9
  import {
9
10
  ClientEvent,
10
11
  ClientEventLeaveReason,
@@ -128,6 +129,7 @@ import {
128
129
  MeetingInfoV2PasswordError,
129
130
  MeetingInfoV2CaptchaError,
130
131
  MeetingInfoV2PolicyError,
132
+ MeetingInfoV2WebinarRegistrationError,
131
133
  } from '../meeting-info/meeting-info-v2';
132
134
  import {CSI, ReceiveSlotManager} from '../multistream/receiveSlotManager';
133
135
  import SendSlotManager from '../multistream/sendSlotManager';
@@ -156,6 +158,7 @@ import ControlsOptionsManager from '../controls-options-manager';
156
158
  import PermissionError from '../common/errors/permission';
157
159
  import {LocusMediaRequest} from './locusMediaRequest';
158
160
  import {ConnectionStateHandler, ConnectionStateEvent} from './connectionStateHandler';
161
+ import WebinarRegistrationError from '../common/errors/webinar-registration-error';
159
162
 
160
163
  // default callback so we don't call an undefined function, but in practice it should never be used
161
164
  const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
@@ -700,6 +703,8 @@ export default class Meeting extends StatelessWebexPlugin {
700
703
  private iceCandidateErrors: Map<string, number>;
701
704
  private iceCandidatesCount: number;
702
705
  private rtcMetrics?: RtcMetrics;
706
+ private uploadLogsTimer?: ReturnType<typeof setTimeout>;
707
+ private logUploadIntervalIndex: number;
703
708
 
704
709
  /**
705
710
  * @param {Object} attrs
@@ -768,6 +773,8 @@ export default class Meeting extends StatelessWebexPlugin {
768
773
  );
769
774
  this.callStateForMetrics.correlationId = this.id;
770
775
  }
776
+ this.logUploadIntervalIndex = 0;
777
+
771
778
  /**
772
779
  * @instance
773
780
  * @type {String}
@@ -1759,8 +1766,16 @@ export default class Meeting extends StatelessWebexPlugin {
1759
1766
  if (err.meetingInfo) {
1760
1767
  this.meetingInfo = err.meetingInfo;
1761
1768
  }
1762
-
1763
1769
  throw new PermissionError();
1770
+ } else if (err instanceof MeetingInfoV2WebinarRegistrationError) {
1771
+ this.meetingInfoFailureReason = MEETING_INFO_FAILURE_REASON.WEBINAR_REGISTRATION;
1772
+ this.meetingInfoFailureCode = err.wbxAppApiCode;
1773
+
1774
+ if (err.meetingInfo) {
1775
+ this.meetingInfo = err.meetingInfo;
1776
+ }
1777
+
1778
+ throw new WebinarRegistrationError();
1764
1779
  } else if (err instanceof MeetingInfoV2PasswordError) {
1765
1780
  LoggerProxy.logger.info(
1766
1781
  // @ts-ignore
@@ -2004,6 +2019,7 @@ export default class Meeting extends StatelessWebexPlugin {
2004
2019
  this.setUpLocusInfoSelfListener();
2005
2020
  this.setUpLocusInfoMeetingListener();
2006
2021
  this.setUpLocusServicesListener();
2022
+ this.setUpLocusResourcesListener();
2007
2023
  // members update listeners
2008
2024
  this.setUpLocusFullStateListener();
2009
2025
  this.setUpLocusUrlListener();
@@ -2625,6 +2641,43 @@ export default class Meeting extends StatelessWebexPlugin {
2625
2641
  );
2626
2642
  });
2627
2643
 
2644
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_WEBCAST_CHANGED, ({state}) => {
2645
+ Trigger.trigger(
2646
+ this,
2647
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2648
+ EVENT_TRIGGERS.MEETING_CONTROLS_WEBCAST_UPDATED,
2649
+ {state}
2650
+ );
2651
+ });
2652
+
2653
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_FULL_CHANGED, ({state}) => {
2654
+ Trigger.trigger(
2655
+ this,
2656
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2657
+ EVENT_TRIGGERS.MEETING_CONTROLS_MEETING_FULL_UPDATED,
2658
+ {state}
2659
+ );
2660
+ });
2661
+
2662
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_PRACTICE_SESSION_STATUS_UPDATED, ({state}) => {
2663
+ this.webinar.updatePracticeSessionStatus(state);
2664
+ Trigger.trigger(
2665
+ this,
2666
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2667
+ EVENT_TRIGGERS.MEETING_CONTROLS_PRACTICE_SESSION_STATUS_UPDATED,
2668
+ {state}
2669
+ );
2670
+ });
2671
+
2672
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_STAGE_VIEW_UPDATED, ({state}) => {
2673
+ Trigger.trigger(
2674
+ this,
2675
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
2676
+ EVENT_TRIGGERS.MEETING_CONTROLS_STAGE_VIEW_UPDATED,
2677
+ {state}
2678
+ );
2679
+ });
2680
+
2628
2681
  this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_VIDEO_CHANGED, ({state}) => {
2629
2682
  Trigger.trigger(
2630
2683
  this,
@@ -2739,6 +2792,9 @@ export default class Meeting extends StatelessWebexPlugin {
2739
2792
  newShareStatus = SHARE_STATUS.NO_SHARE;
2740
2793
  }
2741
2794
 
2795
+ LoggerProxy.logger.info(
2796
+ `Meeting:index#setUpLocusInfoMediaInactiveListener --> this.shareStatus=${this.shareStatus} newShareStatus=${newShareStatus}`
2797
+ );
2742
2798
  if (newShareStatus !== this.shareStatus) {
2743
2799
  const oldShareStatus = this.shareStatus;
2744
2800
 
@@ -2983,10 +3039,20 @@ export default class Meeting extends StatelessWebexPlugin {
2983
3039
  this.breakouts.breakoutServiceUrlUpdate(payload?.services?.breakout?.url);
2984
3040
  this.annotation.approvalUrlUpdate(payload?.services?.approval?.url);
2985
3041
  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
- );
3042
+ });
3043
+ }
3044
+
3045
+ /**
3046
+ * Set up the locus info resources link listener
3047
+ * update the locusInfo for webcast instance url
3048
+ * @param {Object} payload - The event payload
3049
+ * @returns {undefined}
3050
+ * @private
3051
+ * @memberof Meeting
3052
+ */
3053
+ private setUpLocusResourcesListener() {
3054
+ this.locusInfo.on(LOCUSINFO.EVENTS.LINKS_RESOURCES, (payload) => {
3055
+ this.webinar.updateWebcastUrl(payload);
2990
3056
  });
2991
3057
  }
2992
3058
 
@@ -3091,7 +3157,7 @@ export default class Meeting extends StatelessWebexPlugin {
3091
3157
  private setUpLocusInfoSelfListener() {
3092
3158
  this.locusInfo.on(LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUIRED, (payload) => {
3093
3159
  if (this.audio) {
3094
- this.audio.handleServerLocalUnmuteRequired(this);
3160
+ this.audio.handleServerLocalUnmuteRequired(this, payload.unmuteAllowed);
3095
3161
  Trigger.trigger(
3096
3162
  this,
3097
3163
  {
@@ -3189,6 +3255,9 @@ export default class Meeting extends StatelessWebexPlugin {
3189
3255
  options: {meetingId: this.id},
3190
3256
  });
3191
3257
  }
3258
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.GUEST_ENTERED_LOBBY, {
3259
+ correlation_id: this.correlationId,
3260
+ });
3192
3261
  this.updateLLMConnection();
3193
3262
  });
3194
3263
  this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, async (payload) => {
@@ -3212,6 +3281,9 @@ export default class Meeting extends StatelessWebexPlugin {
3212
3281
  name: 'client.lobby.exited',
3213
3282
  options: {meetingId: this.id},
3214
3283
  });
3284
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.GUEST_EXITED_LOBBY, {
3285
+ correlation_id: this.correlationId,
3286
+ });
3215
3287
  }
3216
3288
  this.rtcMetrics?.sendNextMetrics();
3217
3289
  this.updateLLMConnection();
@@ -3298,7 +3370,7 @@ export default class Meeting extends StatelessWebexPlugin {
3298
3370
  this.simultaneousInterpretation.updateCanManageInterpreters(
3299
3371
  payload.newRoles?.includes(SELF_ROLES.MODERATOR)
3300
3372
  );
3301
- this.webinar.updateCanManageWebcast(payload.newRoles?.includes(SELF_ROLES.MODERATOR));
3373
+ this.webinar.updateRoleChanged(payload);
3302
3374
  Trigger.trigger(
3303
3375
  this,
3304
3376
  {
@@ -3445,6 +3517,7 @@ export default class Meeting extends StatelessWebexPlugin {
3445
3517
  emailAddress: string;
3446
3518
  email: string;
3447
3519
  phoneNumber: string;
3520
+ roles: Array<string>;
3448
3521
  },
3449
3522
  alertIfActive = true
3450
3523
  ) {
@@ -3701,6 +3774,10 @@ export default class Meeting extends StatelessWebexPlugin {
3701
3774
  this.userDisplayHints,
3702
3775
  this.selfUserPolicies
3703
3776
  ),
3777
+ isPremiseRecordingEnabled: RecordingUtil.isPremiseRecordingEnabled(
3778
+ this.userDisplayHints,
3779
+ this.selfUserPolicies
3780
+ ),
3704
3781
  canRaiseHand: MeetingUtil.canUserRaiseHand(this.userDisplayHints),
3705
3782
  canLowerAllHands: MeetingUtil.canUserLowerAllHands(this.userDisplayHints),
3706
3783
  canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(this.userDisplayHints),
@@ -3792,6 +3869,22 @@ export default class Meeting extends StatelessWebexPlugin {
3792
3869
  requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST],
3793
3870
  displayHints: this.userDisplayHints,
3794
3871
  }),
3872
+ canEnableViewTheParticipantsListPanelist: ControlsOptionsUtil.hasHints({
3873
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST],
3874
+ displayHints: this.userDisplayHints,
3875
+ }),
3876
+ canDisableViewTheParticipantsListPanelist: ControlsOptionsUtil.hasHints({
3877
+ requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST_PANELIST],
3878
+ displayHints: this.userDisplayHints,
3879
+ }),
3880
+ canEnableShowAttendeeCount: ControlsOptionsUtil.hasHints({
3881
+ requiredHints: [DISPLAY_HINTS.ENABLE_SHOW_ATTENDEE_COUNT],
3882
+ displayHints: this.userDisplayHints,
3883
+ }),
3884
+ canDisableShowAttendeeCount: ControlsOptionsUtil.hasHints({
3885
+ requiredHints: [DISPLAY_HINTS.DISABLE_SHOW_ATTENDEE_COUNT],
3886
+ displayHints: this.userDisplayHints,
3887
+ }),
3795
3888
  canEnableRaiseHand: ControlsOptionsUtil.hasHints({
3796
3889
  requiredHints: [DISPLAY_HINTS.ENABLE_RAISE_HAND],
3797
3890
  displayHints: this.userDisplayHints,
@@ -3808,6 +3901,42 @@ export default class Meeting extends StatelessWebexPlugin {
3808
3901
  requiredHints: [DISPLAY_HINTS.DISABLE_VIDEO],
3809
3902
  displayHints: this.userDisplayHints,
3810
3903
  }),
3904
+ canStartWebcast: ControlsOptionsUtil.hasHints({
3905
+ requiredHints: [DISPLAY_HINTS.WEBCAST_CONTROL_START],
3906
+ displayHints: this.userDisplayHints,
3907
+ }),
3908
+ canStopWebcast: ControlsOptionsUtil.hasHints({
3909
+ requiredHints: [DISPLAY_HINTS.WEBCAST_CONTROL_STOP],
3910
+ displayHints: this.userDisplayHints,
3911
+ }),
3912
+ canShowStageView: ControlsOptionsUtil.hasHints({
3913
+ requiredHints: [DISPLAY_HINTS.STAGE_VIEW_ACTIVE],
3914
+ displayHints: this.userDisplayHints,
3915
+ }),
3916
+ canEnableStageView: ControlsOptionsUtil.hasHints({
3917
+ requiredHints: [DISPLAY_HINTS.ENABLE_STAGE_VIEW],
3918
+ displayHints: this.userDisplayHints,
3919
+ }),
3920
+ canDisableStageView: ControlsOptionsUtil.hasHints({
3921
+ requiredHints: [DISPLAY_HINTS.DISABLE_STAGE_VIEW],
3922
+ displayHints: this.userDisplayHints,
3923
+ }),
3924
+ isPracticeSessionOn: ControlsOptionsUtil.hasHints({
3925
+ requiredHints: [DISPLAY_HINTS.PRACTICE_SESSION_ON],
3926
+ displayHints: this.userDisplayHints,
3927
+ }),
3928
+ isPracticeSessionOff: ControlsOptionsUtil.hasHints({
3929
+ requiredHints: [DISPLAY_HINTS.PRACTICE_SESSION_OFF],
3930
+ displayHints: this.userDisplayHints,
3931
+ }),
3932
+ canStartPracticeSession: ControlsOptionsUtil.hasHints({
3933
+ requiredHints: [DISPLAY_HINTS.SHOW_PRACTICE_SESSION_START],
3934
+ displayHints: this.userDisplayHints,
3935
+ }),
3936
+ canStopPracticeSession: ControlsOptionsUtil.hasHints({
3937
+ requiredHints: [DISPLAY_HINTS.SHOW_PRACTICE_SESSION_STOP],
3938
+ displayHints: this.userDisplayHints,
3939
+ }),
3811
3940
  canShareFile:
3812
3941
  (ControlsOptionsUtil.hasHints({
3813
3942
  requiredHints: [DISPLAY_HINTS.SHARE_FILE],
@@ -3964,6 +4093,65 @@ export default class Meeting extends StatelessWebexPlugin {
3964
4093
  Trigger.trigger(this, options, EVENTS.REQUEST_UPLOAD_LOGS, this);
3965
4094
  }
3966
4095
 
4096
+ /**
4097
+ * sets the timer for periodic log upload
4098
+ * @returns {void}
4099
+ */
4100
+ private setLogUploadTimer() {
4101
+ // start with short timeouts and increase them later on so in case users have very long multi-hour meetings we don't get too fragmented logs
4102
+ const LOG_UPLOAD_INTERVALS = [0.1, 1, 15, 15, 30, 30, 30, 60];
4103
+
4104
+ const delay =
4105
+ 1000 *
4106
+ // @ts-ignore - config coming from registerPlugin
4107
+ this.config.logUploadIntervalMultiplicationFactor *
4108
+ LOG_UPLOAD_INTERVALS[this.logUploadIntervalIndex];
4109
+
4110
+ if (this.logUploadIntervalIndex < LOG_UPLOAD_INTERVALS.length - 1) {
4111
+ this.logUploadIntervalIndex += 1;
4112
+ }
4113
+
4114
+ this.uploadLogsTimer = safeSetTimeout(() => {
4115
+ this.uploadLogsTimer = undefined;
4116
+
4117
+ this.uploadLogs();
4118
+
4119
+ // just as an extra precaution, to avoid uploading logs forever in case something goes wrong
4120
+ // and the page remains opened, we stop it if there is no media connection
4121
+ if (!this.mediaProperties.webrtcMediaConnection) {
4122
+ return;
4123
+ }
4124
+
4125
+ this.setLogUploadTimer();
4126
+ }, delay);
4127
+ }
4128
+
4129
+ /**
4130
+ * Starts a periodic upload of logs
4131
+ *
4132
+ * @returns {undefined}
4133
+ */
4134
+ public startPeriodicLogUpload() {
4135
+ // @ts-ignore - config coming from registerPlugin
4136
+ if (this.config.logUploadIntervalMultiplicationFactor && !this.uploadLogsTimer) {
4137
+ this.logUploadIntervalIndex = 0;
4138
+
4139
+ this.setLogUploadTimer();
4140
+ }
4141
+ }
4142
+
4143
+ /**
4144
+ * Stops the periodic upload of logs
4145
+ *
4146
+ * @returns {undefined}
4147
+ */
4148
+ public stopPeriodicLogUpload() {
4149
+ if (this.uploadLogsTimer) {
4150
+ clearTimeout(this.uploadLogsTimer);
4151
+ this.uploadLogsTimer = undefined;
4152
+ }
4153
+ }
4154
+
3967
4155
  /**
3968
4156
  * Removes remote audio, video and share streams from class instance's mediaProperties
3969
4157
  * @returns {undefined}
@@ -4675,8 +4863,6 @@ export default class Meeting extends StatelessWebexPlugin {
4675
4863
  if (!joinResponse) {
4676
4864
  // This is the 1st attempt or a retry after join request failed -> we need to do a join with TURN discovery
4677
4865
 
4678
- // @ts-ignore
4679
- joinOptions.reachability = await this.webex.meetings.reachability.getReachabilityResults();
4680
4866
  const turnDiscoveryRequest = await this.roap.generateTurnDiscoveryRequestMessage(
4681
4867
  this,
4682
4868
  true
@@ -4808,6 +4994,8 @@ export default class Meeting extends StatelessWebexPlugin {
4808
4994
  );
4809
4995
  }
4810
4996
 
4997
+ this.cleanUpBeforeReconnection();
4998
+
4811
4999
  return this.reconnectionManager
4812
5000
  .reconnect(options, async () => {
4813
5001
  await this.waitForRemoteSDPAnswer();
@@ -6225,7 +6413,7 @@ export default class Meeting extends StatelessWebexPlugin {
6225
6413
  this.mediaProperties.webrtcMediaConnection.on(
6226
6414
  MediaConnectionEventNames.ICE_CANDIDATE,
6227
6415
  (event) => {
6228
- if (event.candidate) {
6416
+ if (event.candidate && event.candidate.candidate && event.candidate.candidate.length > 0) {
6229
6417
  this.iceCandidatesCount += 1;
6230
6418
  }
6231
6419
  }
@@ -6936,6 +7124,23 @@ export default class Meeting extends StatelessWebexPlugin {
6936
7124
  }
6937
7125
  }
6938
7126
 
7127
+ private async cleanUpBeforeReconnection(): Promise<void> {
7128
+ try {
7129
+ // when media fails, we want to upload a webrtc dump to see whats going on
7130
+ // this function is async, but returns once the stats have been gathered
7131
+ await this.forceSendStatsReport({callFrom: 'cleanUpBeforeReconnection'});
7132
+
7133
+ if (this.statsAnalyzer) {
7134
+ await this.statsAnalyzer.stopAnalyzer();
7135
+ }
7136
+ } catch (error) {
7137
+ LoggerProxy.logger.error(
7138
+ 'Meeting:index#cleanUpBeforeReconnection --> Error during cleanup: ',
7139
+ error
7140
+ );
7141
+ }
7142
+ }
7143
+
6939
7144
  /**
6940
7145
  * Creates an instance of LocusMediaRequest for this meeting - it is needed for doing any calls
6941
7146
  * to Locus /media API (these are used for sending Roap messages and updating audio/video mute status).
@@ -7027,7 +7232,7 @@ export default class Meeting extends StatelessWebexPlugin {
7027
7232
  shareAudioEnabled = true,
7028
7233
  shareVideoEnabled = true,
7029
7234
  remoteMediaManagerConfig,
7030
- bundlePolicy,
7235
+ bundlePolicy = 'max-bundle',
7031
7236
  } = options;
7032
7237
 
7033
7238
  this.allowMediaInLobby = options?.allowMediaInLobby;
@@ -7132,6 +7337,7 @@ export default class Meeting extends StatelessWebexPlugin {
7132
7337
 
7133
7338
  // We can log ReceiveSlot SSRCs only after the SDP exchange, so doing it here:
7134
7339
  this.remoteMediaManager?.logAllReceiveSlots();
7340
+ this.startPeriodicLogUpload();
7135
7341
  } catch (error) {
7136
7342
  LoggerProxy.logger.error(`${LOG_HEADER} failed to establish media connection: `, error);
7137
7343
 
@@ -7914,18 +8120,21 @@ export default class Meeting extends StatelessWebexPlugin {
7914
8120
  * @param {boolean} mutedEnabled
7915
8121
  * @param {boolean} disallowUnmuteEnabled
7916
8122
  * @param {boolean} muteOnEntryEnabled
8123
+ * @param {array} roles
7917
8124
  * @public
7918
8125
  * @memberof Meeting
7919
8126
  */
7920
8127
  public setMuteAll(
7921
8128
  mutedEnabled: boolean,
7922
8129
  disallowUnmuteEnabled: boolean,
7923
- muteOnEntryEnabled: boolean
8130
+ muteOnEntryEnabled: boolean,
8131
+ roles: Array<string>
7924
8132
  ) {
7925
8133
  return this.controlsOptionsManager.setMuteAll(
7926
8134
  mutedEnabled,
7927
8135
  disallowUnmuteEnabled,
7928
- muteOnEntryEnabled
8136
+ muteOnEntryEnabled,
8137
+ roles
7929
8138
  );
7930
8139
  }
7931
8140
 
@@ -8182,6 +8391,9 @@ export default class Meeting extends StatelessWebexPlugin {
8182
8391
  * @returns {undefined}
8183
8392
  */
8184
8393
  private handleShareAudioStreamEnded = async () => {
8394
+ LoggerProxy.logger.info(
8395
+ `Meeting:index#handleShareAudioStreamEnded --> audio share stream ended`
8396
+ );
8185
8397
  // current share audio stream has ended, but there might be an active
8186
8398
  // share video stream. we only leave from wireless share if share has
8187
8399
  // completely ended, which means no share audio or video streams active
@@ -8224,6 +8436,9 @@ export default class Meeting extends StatelessWebexPlugin {
8224
8436
  * @returns {undefined}
8225
8437
  */
8226
8438
  private handleShareVideoStreamEnded = async () => {
8439
+ LoggerProxy.logger.info(
8440
+ `Meeting:index#handleShareVideoStreamEnded --> video share stream ended`
8441
+ );
8227
8442
  // current share video stream has ended, but there might be an active
8228
8443
  // share audio stream. we only leave from wireless share if share has
8229
8444
  // completely ended, which means no share audio or video streams active
@@ -8712,6 +8927,9 @@ export default class Meeting extends StatelessWebexPlugin {
8712
8927
  * @returns {Promise}
8713
8928
  */
8714
8929
  async publishStreams(streams: LocalStreams): Promise<void> {
8930
+ LoggerProxy.logger.info(
8931
+ `Meeting:index#publishStreams --> called with: ${JSON.stringify(streams)}`
8932
+ );
8715
8933
  this.checkMediaConnection();
8716
8934
  if (
8717
8935
  !streams.microphone &&
@@ -8723,15 +8941,19 @@ export default class Meeting extends StatelessWebexPlugin {
8723
8941
  return;
8724
8942
  }
8725
8943
 
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
- );
8944
+ const streamChecks = [
8945
+ {stream: streams?.microphone, name: 'microphone'},
8946
+ {stream: streams?.camera, name: 'camera'},
8947
+ {stream: streams?.screenShare?.audio, name: 'screenShare audio'},
8948
+ {stream: streams?.screenShare?.video, name: 'screenShare video'},
8949
+ ];
8950
+
8951
+ for (const {stream, name} of streamChecks) {
8952
+ if (stream?.readyState === 'ended') {
8953
+ throw new Error(
8954
+ `Attempted to publish ${name} stream with ended readyState, correlationId=${this.correlationId}`
8955
+ );
8956
+ }
8735
8957
  }
8736
8958
 
8737
8959
  let floorRequestNeeded = false;
@@ -8793,6 +9015,9 @@ export default class Meeting extends StatelessWebexPlugin {
8793
9015
  * @returns {Promise}
8794
9016
  */
8795
9017
  async unpublishStreams(streams: LocalStream[]): Promise<void> {
9018
+ LoggerProxy.logger.info(
9019
+ `Meeting:index#unpublishStreams --> called with: ${JSON.stringify(streams)}`
9020
+ );
8796
9021
  this.checkMediaConnection();
8797
9022
 
8798
9023
  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) {