@webex/plugin-meetings 2.36.1 → 2.37.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 (308) hide show
  1. package/UPGRADING.md +9 -9
  2. package/browsers.js +19 -24
  3. package/dist/common/browser-detection.js +1 -20
  4. package/dist/common/browser-detection.js.map +1 -1
  5. package/dist/common/collection.js +5 -20
  6. package/dist/common/collection.js.map +1 -1
  7. package/dist/common/config.js +0 -7
  8. package/dist/common/config.js.map +1 -1
  9. package/dist/common/errors/captcha-error.js +5 -26
  10. package/dist/common/errors/captcha-error.js.map +1 -1
  11. package/dist/common/errors/intent-to-join.js +5 -26
  12. package/dist/common/errors/intent-to-join.js.map +1 -1
  13. package/dist/common/errors/join-meeting.js +6 -27
  14. package/dist/common/errors/join-meeting.js.map +1 -1
  15. package/dist/common/errors/media.js +5 -26
  16. package/dist/common/errors/media.js.map +1 -1
  17. package/dist/common/errors/parameter.js +5 -33
  18. package/dist/common/errors/parameter.js.map +1 -1
  19. package/dist/common/errors/password-error.js +5 -26
  20. package/dist/common/errors/password-error.js.map +1 -1
  21. package/dist/common/errors/permission.js +4 -25
  22. package/dist/common/errors/permission.js.map +1 -1
  23. package/dist/common/errors/reconnection-in-progress.js +0 -17
  24. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  25. package/dist/common/errors/reconnection.js +5 -26
  26. package/dist/common/errors/reconnection.js.map +1 -1
  27. package/dist/common/errors/stats.js +5 -26
  28. package/dist/common/errors/stats.js.map +1 -1
  29. package/dist/common/errors/webex-errors.js +7 -46
  30. package/dist/common/errors/webex-errors.js.map +1 -1
  31. package/dist/common/errors/webex-meetings-error.js +1 -24
  32. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  33. package/dist/common/events/events-scope.js +0 -22
  34. package/dist/common/events/events-scope.js.map +1 -1
  35. package/dist/common/events/events.js +0 -23
  36. package/dist/common/events/events.js.map +1 -1
  37. package/dist/common/events/trigger-proxy.js +0 -12
  38. package/dist/common/events/trigger-proxy.js.map +1 -1
  39. package/dist/common/events/util.js +0 -15
  40. package/dist/common/events/util.js.map +1 -1
  41. package/dist/common/logs/logger-config.js +0 -4
  42. package/dist/common/logs/logger-config.js.map +1 -1
  43. package/dist/common/logs/logger-proxy.js +1 -8
  44. package/dist/common/logs/logger-proxy.js.map +1 -1
  45. package/dist/common/logs/request.js +35 -61
  46. package/dist/common/logs/request.js.map +1 -1
  47. package/dist/common/queue.js +4 -14
  48. package/dist/common/queue.js.map +1 -1
  49. package/dist/config.js +1 -5
  50. package/dist/config.js.map +1 -1
  51. package/dist/constants.js +46 -42
  52. package/dist/constants.js.map +1 -1
  53. package/dist/index.js +1 -17
  54. package/dist/index.js.map +1 -1
  55. package/dist/locus-info/controlsUtils.js +10 -28
  56. package/dist/locus-info/controlsUtils.js.map +1 -1
  57. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  58. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  59. package/dist/locus-info/fullState.js +0 -15
  60. package/dist/locus-info/fullState.js.map +1 -1
  61. package/dist/locus-info/hostUtils.js +4 -12
  62. package/dist/locus-info/hostUtils.js.map +1 -1
  63. package/dist/locus-info/index.js +101 -193
  64. package/dist/locus-info/index.js.map +1 -1
  65. package/dist/locus-info/infoUtils.js +0 -37
  66. package/dist/locus-info/infoUtils.js.map +1 -1
  67. package/dist/locus-info/mediaSharesUtils.js +12 -38
  68. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  69. package/dist/locus-info/parser.js +87 -123
  70. package/dist/locus-info/parser.js.map +1 -1
  71. package/dist/locus-info/selfUtils.js +16 -81
  72. package/dist/locus-info/selfUtils.js.map +1 -1
  73. package/dist/media/index.js +74 -137
  74. package/dist/media/index.js.map +1 -1
  75. package/dist/media/properties.js +64 -110
  76. package/dist/media/properties.js.map +1 -1
  77. package/dist/media/util.js +3 -17
  78. package/dist/media/util.js.map +1 -1
  79. package/dist/mediaQualityMetrics/config.js +10 -12
  80. package/dist/mediaQualityMetrics/config.js.map +1 -1
  81. package/dist/meeting/effectsState.js +120 -192
  82. package/dist/meeting/effectsState.js.map +1 -1
  83. package/dist/meeting/in-meeting-actions.js +0 -13
  84. package/dist/meeting/in-meeting-actions.js.map +1 -1
  85. package/dist/meeting/index.js +812 -1487
  86. package/dist/meeting/index.js.map +1 -1
  87. package/dist/meeting/muteState.js +31 -78
  88. package/dist/meeting/muteState.js.map +1 -1
  89. package/dist/meeting/request.js +157 -227
  90. package/dist/meeting/request.js.map +1 -1
  91. package/dist/meeting/state.js +21 -31
  92. package/dist/meeting/state.js.map +1 -1
  93. package/dist/meeting/util.js +25 -169
  94. package/dist/meeting/util.js.map +1 -1
  95. package/dist/meeting-info/collection.js +3 -25
  96. package/dist/meeting-info/collection.js.map +1 -1
  97. package/dist/meeting-info/index.js +10 -33
  98. package/dist/meeting-info/index.js.map +1 -1
  99. package/dist/meeting-info/meeting-info-v2.js +179 -268
  100. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  101. package/dist/meeting-info/request.js +1 -16
  102. package/dist/meeting-info/request.js.map +1 -1
  103. package/dist/meeting-info/util.js +98 -183
  104. package/dist/meeting-info/util.js.map +1 -1
  105. package/dist/meeting-info/utilv2.js +137 -228
  106. package/dist/meeting-info/utilv2.js.map +1 -1
  107. package/dist/meetings/collection.js +3 -21
  108. package/dist/meetings/collection.js.map +1 -1
  109. package/dist/meetings/index.js +451 -570
  110. package/dist/meetings/index.js.map +1 -1
  111. package/dist/meetings/request.js +7 -30
  112. package/dist/meetings/request.js.map +1 -1
  113. package/dist/meetings/util.js +94 -148
  114. package/dist/meetings/util.js.map +1 -1
  115. package/dist/member/index.js +49 -89
  116. package/dist/member/index.js.map +1 -1
  117. package/dist/member/util.js +17 -68
  118. package/dist/member/util.js.map +1 -1
  119. package/dist/members/collection.js +2 -12
  120. package/dist/members/collection.js.map +1 -1
  121. package/dist/members/index.js +68 -184
  122. package/dist/members/index.js.map +1 -1
  123. package/dist/members/request.js +21 -56
  124. package/dist/members/request.js.map +1 -1
  125. package/dist/members/util.js +9 -38
  126. package/dist/members/util.js.map +1 -1
  127. package/dist/metrics/config.js +0 -2
  128. package/dist/metrics/config.js.map +1 -1
  129. package/dist/metrics/constants.js +1 -2
  130. package/dist/metrics/constants.js.map +1 -1
  131. package/dist/metrics/index.js +48 -136
  132. package/dist/metrics/index.js.map +1 -1
  133. package/dist/networkQualityMonitor/index.js +28 -57
  134. package/dist/networkQualityMonitor/index.js.map +1 -1
  135. package/dist/peer-connection-manager/index.js +60 -190
  136. package/dist/peer-connection-manager/index.js.map +1 -1
  137. package/dist/peer-connection-manager/util.js +10 -24
  138. package/dist/peer-connection-manager/util.js.map +1 -1
  139. package/dist/personal-meeting-room/index.js +10 -45
  140. package/dist/personal-meeting-room/index.js.map +1 -1
  141. package/dist/personal-meeting-room/request.js +2 -33
  142. package/dist/personal-meeting-room/request.js.map +1 -1
  143. package/dist/personal-meeting-room/util.js +0 -13
  144. package/dist/personal-meeting-room/util.js.map +1 -1
  145. package/dist/reachability/index.js +100 -166
  146. package/dist/reachability/index.js.map +1 -1
  147. package/dist/reachability/request.js +2 -18
  148. package/dist/reachability/request.js.map +1 -1
  149. package/dist/reactions/reactions.js +0 -2
  150. package/dist/reactions/reactions.js.map +1 -1
  151. package/dist/reactions/reactions.type.js +0 -5
  152. package/dist/reactions/reactions.type.js.map +1 -1
  153. package/dist/reconnection-manager/index.js +294 -468
  154. package/dist/reconnection-manager/index.js.map +1 -1
  155. package/dist/roap/collection.js +1 -12
  156. package/dist/roap/collection.js.map +1 -1
  157. package/dist/roap/handler.js +15 -85
  158. package/dist/roap/handler.js.map +1 -1
  159. package/dist/roap/index.js +42 -94
  160. package/dist/roap/index.js.map +1 -1
  161. package/dist/roap/request.js +81 -148
  162. package/dist/roap/request.js.map +1 -1
  163. package/dist/roap/state.js +2 -39
  164. package/dist/roap/state.js.map +1 -1
  165. package/dist/roap/turnDiscovery.js +8 -52
  166. package/dist/roap/turnDiscovery.js.map +1 -1
  167. package/dist/roap/util.js +0 -26
  168. package/dist/roap/util.js.map +1 -1
  169. package/dist/statsAnalyzer/global.js +0 -2
  170. package/dist/statsAnalyzer/global.js.map +1 -1
  171. package/dist/statsAnalyzer/index.js +68 -168
  172. package/dist/statsAnalyzer/index.js.map +1 -1
  173. package/dist/statsAnalyzer/mqaUtil.js +54 -53
  174. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  175. package/dist/transcription/index.js +13 -45
  176. package/dist/transcription/index.js.map +1 -1
  177. package/internal-README.md +7 -6
  178. package/package.json +17 -17
  179. package/src/common/browser-detection.ts +9 -6
  180. package/src/common/collection.ts +3 -1
  181. package/src/common/errors/captcha-error.ts +6 -6
  182. package/src/common/errors/intent-to-join.ts +6 -6
  183. package/src/common/errors/join-meeting.ts +12 -8
  184. package/src/common/errors/media.ts +6 -6
  185. package/src/common/errors/parameter.ts +9 -6
  186. package/src/common/errors/password-error.ts +6 -6
  187. package/src/common/errors/permission.ts +5 -5
  188. package/src/common/errors/reconnection.ts +6 -6
  189. package/src/common/errors/stats.ts +6 -6
  190. package/src/common/errors/webex-errors.ts +7 -5
  191. package/src/common/errors/webex-meetings-error.ts +1 -1
  192. package/src/common/events/events-scope.ts +5 -1
  193. package/src/common/events/events.ts +5 -1
  194. package/src/common/events/trigger-proxy.ts +8 -3
  195. package/src/common/events/util.ts +1 -2
  196. package/src/common/logs/logger-proxy.ts +21 -10
  197. package/src/common/logs/request.ts +11 -8
  198. package/src/config.ts +11 -11
  199. package/src/constants.ts +138 -119
  200. package/src/index.js +1 -1
  201. package/src/locus-info/controlsUtils.ts +34 -24
  202. package/src/locus-info/fullState.ts +15 -11
  203. package/src/locus-info/hostUtils.ts +4 -3
  204. package/src/locus-info/index.ts +25 -34
  205. package/src/locus-info/infoUtils.ts +12 -4
  206. package/src/locus-info/mediaSharesUtils.ts +4 -4
  207. package/src/locus-info/parser.ts +45 -68
  208. package/src/locus-info/selfUtils.ts +106 -57
  209. package/src/media/index.ts +118 -109
  210. package/src/media/properties.ts +26 -20
  211. package/src/media/util.ts +2 -2
  212. package/src/mediaQualityMetrics/config.ts +46 -46
  213. package/src/meeting/effectsState.ts +35 -35
  214. package/src/meeting/in-meeting-actions.ts +7 -3
  215. package/src/meeting/index.ts +1435 -1210
  216. package/src/meeting/muteState.ts +62 -31
  217. package/src/meeting/request.ts +160 -113
  218. package/src/meeting/state.ts +45 -30
  219. package/src/meeting/util.ts +131 -90
  220. package/src/meeting-info/collection.ts +2 -1
  221. package/src/meeting-info/index.ts +32 -30
  222. package/src/meeting-info/meeting-info-v2.ts +106 -108
  223. package/src/meeting-info/request.ts +9 -3
  224. package/src/meeting-info/util.ts +54 -46
  225. package/src/meeting-info/utilv2.ts +59 -53
  226. package/src/meetings/collection.ts +1 -1
  227. package/src/meetings/index.ts +513 -441
  228. package/src/meetings/request.ts +26 -24
  229. package/src/meetings/util.ts +26 -23
  230. package/src/member/index.ts +55 -49
  231. package/src/member/util.ts +26 -13
  232. package/src/members/collection.ts +0 -1
  233. package/src/members/index.ts +172 -121
  234. package/src/members/request.ts +46 -14
  235. package/src/members/util.ts +44 -42
  236. package/src/metrics/config.ts +254 -81
  237. package/src/metrics/constants.ts +0 -2
  238. package/src/metrics/index.ts +84 -71
  239. package/src/networkQualityMonitor/index.ts +20 -23
  240. package/src/peer-connection-manager/index.ts +321 -241
  241. package/src/peer-connection-manager/util.ts +4 -2
  242. package/src/personal-meeting-room/index.ts +12 -16
  243. package/src/personal-meeting-room/request.ts +10 -3
  244. package/src/personal-meeting-room/util.ts +3 -3
  245. package/src/reachability/index.ts +61 -59
  246. package/src/reachability/request.ts +36 -32
  247. package/src/reactions/reactions.ts +4 -4
  248. package/src/reactions/reactions.type.ts +2 -3
  249. package/src/reconnection-manager/index.ts +159 -98
  250. package/src/roap/collection.ts +2 -4
  251. package/src/roap/handler.ts +63 -32
  252. package/src/roap/index.ts +78 -58
  253. package/src/roap/request.ts +69 -54
  254. package/src/roap/state.ts +17 -11
  255. package/src/roap/turnDiscovery.ts +60 -31
  256. package/src/roap/util.ts +39 -31
  257. package/src/statsAnalyzer/global.ts +30 -33
  258. package/src/statsAnalyzer/index.ts +397 -169
  259. package/src/statsAnalyzer/mqaUtil.ts +178 -72
  260. package/src/transcription/index.ts +34 -32
  261. package/test/integration/spec/journey.js +666 -462
  262. package/test/integration/spec/space-meeting.js +318 -203
  263. package/test/integration/spec/transcription.js +6 -7
  264. package/test/unit/spec/common/browser-detection.js +9 -28
  265. package/test/unit/spec/fixture/locus.js +92 -90
  266. package/test/unit/spec/locus-info/controlsUtils.js +5 -5
  267. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  268. package/test/unit/spec/locus-info/index.js +1 -2
  269. package/test/unit/spec/locus-info/infoUtils.js +24 -31
  270. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  271. package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
  272. package/test/unit/spec/locus-info/parser.js +3 -9
  273. package/test/unit/spec/locus-info/selfConstant.js +72 -103
  274. package/test/unit/spec/locus-info/selfUtils.js +21 -12
  275. package/test/unit/spec/meeting/effectsState.js +33 -45
  276. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -3
  277. package/test/unit/spec/meeting/index.js +1141 -649
  278. package/test/unit/spec/meeting/muteState.js +42 -33
  279. package/test/unit/spec/meeting/request.js +56 -45
  280. package/test/unit/spec/meeting/utils.js +66 -49
  281. package/test/unit/spec/meeting-info/meetinginfov2.js +100 -73
  282. package/test/unit/spec/meeting-info/request.js +7 -9
  283. package/test/unit/spec/meeting-info/util.js +11 -12
  284. package/test/unit/spec/meeting-info/utilv2.js +110 -74
  285. package/test/unit/spec/meetings/collection.js +1 -1
  286. package/test/unit/spec/meetings/index.js +438 -257
  287. package/test/unit/spec/meetings/utils.js +14 -12
  288. package/test/unit/spec/member/index.js +0 -1
  289. package/test/unit/spec/member/util.js +5 -6
  290. package/test/unit/spec/members/index.js +84 -35
  291. package/test/unit/spec/members/request.js +29 -20
  292. package/test/unit/spec/members/utils.js +8 -5
  293. package/test/unit/spec/metrics/index.js +16 -21
  294. package/test/unit/spec/networkQualityMonitor/index.js +21 -15
  295. package/test/unit/spec/peerconnection-manager/index.js +88 -58
  296. package/test/unit/spec/peerconnection-manager/utils.js +5 -4
  297. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +7 -8
  298. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  299. package/test/unit/spec/reachability/index.ts +9 -11
  300. package/test/unit/spec/reconnection-manager/index.js +14 -17
  301. package/test/unit/spec/roap/index.ts +18 -8
  302. package/test/unit/spec/roap/turnDiscovery.ts +22 -19
  303. package/test/unit/spec/roap/util.js +3 -3
  304. package/test/unit/spec/stats-analyzer/index.js +29 -24
  305. package/test/utils/cmr.js +44 -42
  306. package/test/utils/testUtils.js +83 -74
  307. package/test/utils/webex-config.js +18 -18
  308. package/test/utils/webex-test-users.js +53 -50
@@ -5,8 +5,12 @@ import {StatelessWebexPlugin} from '@webex/webex-core';
5
5
  import {Media as WebRTCMedia} from '@webex/internal-media-core';
6
6
 
7
7
  import {
8
- MeetingNotActiveError, createMeetingsError, UserInLobbyError,
9
- NoMediaEstablishedYetError, UserNotJoinedError, InvalidSdpError
8
+ MeetingNotActiveError,
9
+ createMeetingsError,
10
+ UserInLobbyError,
11
+ NoMediaEstablishedYetError,
12
+ UserNotJoinedError,
13
+ InvalidSdpError,
10
14
  } from '../common/errors/webex-errors';
11
15
  import {StatsAnalyzer, EVENTS as StatsAnalyzerEvents} from '../statsAnalyzer';
12
16
  import NetworkQualityMonitor from '../networkQualityMonitor';
@@ -15,17 +19,17 @@ import Trigger from '../common/events/trigger-proxy';
15
19
  import Roap from '../roap/index';
16
20
  import Media from '../media';
17
21
  import MediaProperties from '../media/properties';
18
- import MeetingStateMachine from '../meeting/state';
19
- import createMuteState from '../meeting/muteState';
20
- import createEffectsState from '../meeting/effectsState';
22
+ import MeetingStateMachine from './state';
23
+ import createMuteState from './muteState';
24
+ import createEffectsState from './effectsState';
21
25
  import LocusInfo from '../locus-info';
22
26
  import PeerConnectionManager from '../peer-connection-manager';
23
27
  import Metrics from '../metrics';
24
28
  import {trigger, mediaType, eventType} from '../metrics/config';
25
29
  import ReconnectionManager from '../reconnection-manager';
26
- import MeetingRequest from '../meeting/request';
30
+ import MeetingRequest from './request';
27
31
  import Members from '../members/index';
28
- import MeetingUtil from '../meeting/util';
32
+ import MeetingUtil from './util';
29
33
  import MediaUtil from '../media/util';
30
34
  import Transcription from '../transcription';
31
35
  import PasswordError from '../common/errors/password-error';
@@ -69,12 +73,15 @@ import {
69
73
  VIDEO_RESOLUTIONS,
70
74
  VIDEO,
71
75
  BNR_STATUS,
72
- HTTP_VERBS
76
+ HTTP_VERBS,
73
77
  } from '../constants';
74
78
  import BEHAVIORAL_METRICS from '../metrics/constants';
75
79
  import ParameterError from '../common/errors/parameter';
76
80
  import MediaError from '../common/errors/media';
77
- import {MeetingInfoV2PasswordError, MeetingInfoV2CaptchaError} from '../meeting-info/meeting-info-v2';
81
+ import {
82
+ MeetingInfoV2PasswordError,
83
+ MeetingInfoV2CaptchaError,
84
+ } from '../meeting-info/meeting-info-v2';
78
85
  import BrowserDetection from '../common/browser-detection';
79
86
  import RoapCollection from '../roap/collection';
80
87
  import {SkinTones, Reactions} from '../reactions/reactions';
@@ -82,10 +89,9 @@ import {Reaction, ReactionType, SkinToneType} from '../reactions/reactions.type'
82
89
 
83
90
  import InMeetingActions from './in-meeting-actions';
84
91
 
85
-
86
92
  const {isBrowser} = BrowserDetection();
87
93
 
88
- const logRequest = (request: any, { header = '', success = '', failure = '' }) => {
94
+ const logRequest = (request: any, {header = '', success = '', failure = ''}) => {
89
95
  LoggerProxy.logger.info(header);
90
96
 
91
97
  return request
@@ -104,7 +110,7 @@ export const MEDIA_UPDATE_TYPE = {
104
110
  ALL: 'ALL',
105
111
  AUDIO: 'AUDIO',
106
112
  VIDEO: 'VIDEO',
107
- SHARE: 'SHARE'
113
+ SHARE: 'SHARE',
108
114
  };
109
115
 
110
116
  /**
@@ -120,21 +126,21 @@ export const MEDIA_UPDATE_TYPE = {
120
126
  */
121
127
 
122
128
  /**
123
- * AudioVideo
124
- * @typedef {Object} AudioVideo
125
- * @property {Object} audio
126
- * @property {String} audio.deviceId
127
- * @property {Object} video
128
- * @property {String} video.deviceId
129
- * @property {String} video.localVideoQuality // [240p, 360p, 480p, 720p, 1080p]
130
- */
129
+ * AudioVideo
130
+ * @typedef {Object} AudioVideo
131
+ * @property {Object} audio
132
+ * @property {String} audio.deviceId
133
+ * @property {Object} video
134
+ * @property {String} video.deviceId
135
+ * @property {String} video.localVideoQuality // [240p, 360p, 480p, 720p, 1080p]
136
+ */
131
137
 
132
138
  /**
133
- * SharePreferences
134
- * @typedef {Object} SharePreferences
135
- * @property {Object} [shareConstraints]
136
- * @property {Boolean} [highFrameRate]
137
- */
139
+ * SharePreferences
140
+ * @typedef {Object} SharePreferences
141
+ * @property {Object} [shareConstraints]
142
+ * @property {Boolean} [highFrameRate]
143
+ */
138
144
 
139
145
  /**
140
146
  * JoinOptions
@@ -164,36 +170,36 @@ export const MEDIA_UPDATE_TYPE = {
164
170
  */
165
171
 
166
172
  /**
167
- * Meeting State Change Event
168
- * Emitted when ever there is a meeting state change
169
- * @event meeting:stateChange
170
- * @instance
171
- * @type {Object}
172
- * @property {String} currentState current state of the meeting
173
- * @property {String} previousState previous state of the meeting
174
- * @memberof Meeting
175
- */
173
+ * Meeting State Change Event
174
+ * Emitted when ever there is a meeting state change
175
+ * @event meeting:stateChange
176
+ * @instance
177
+ * @type {Object}
178
+ * @property {String} currentState current state of the meeting
179
+ * @property {String} previousState previous state of the meeting
180
+ * @memberof Meeting
181
+ */
176
182
 
177
183
  /**
178
- * Media Ready Event
179
- * Emitted when a stream is ready to be rendered
180
- * @event media:ready
181
- * @instance
182
- * @type {Object}
183
- * @property {MediaStream} stream the media stream
184
- * @property {String} type what type of stream, remote, local
185
- * @memberof Meeting
186
- */
184
+ * Media Ready Event
185
+ * Emitted when a stream is ready to be rendered
186
+ * @event media:ready
187
+ * @instance
188
+ * @type {Object}
189
+ * @property {MediaStream} stream the media stream
190
+ * @property {String} type what type of stream, remote, local
191
+ * @memberof Meeting
192
+ */
187
193
 
188
194
  /**
189
- * Media Stopped Event
190
- * Emitted when a stream has stopped sending
191
- * @event media:stopped
192
- * @instance
193
- * @type {Object}
194
- * @property {String} type what type of stream, remote, local
195
- * @memberof Meeting
196
- */
195
+ * Media Stopped Event
196
+ * Emitted when a stream has stopped sending
197
+ * @event media:stopped
198
+ * @instance
199
+ * @type {Object}
200
+ * @property {String} type what type of stream, remote, local
201
+ * @memberof Meeting
202
+ */
197
203
 
198
204
  /**
199
205
  * Meeting Ringing Event
@@ -320,7 +326,6 @@ export const MEDIA_UPDATE_TYPE = {
320
326
  * @memberof Meeting
321
327
  */
322
328
 
323
-
324
329
  /**
325
330
  * Meeting Self Guest Admitted Event
326
331
  * Emitted when a joined user get admitted to the meeting by another member or host
@@ -352,42 +357,42 @@ export const MEDIA_UPDATE_TYPE = {
352
357
  */
353
358
 
354
359
  /**
355
- * Reconnection Starting Event
356
- * Emitted when reconnection of media to the active meeting was successful
357
- * @event meeting:reconnectionStarting
358
- * @instance
359
- * @memberof Meeting
360
- */
360
+ * Reconnection Starting Event
361
+ * Emitted when reconnection of media to the active meeting was successful
362
+ * @event meeting:reconnectionStarting
363
+ * @instance
364
+ * @memberof Meeting
365
+ */
361
366
 
362
367
  /**
363
- * Reconnection Success Event
364
- * Emitted when reconnection of media to the active meeting was successful
365
- * @event meeting:reconnectionSuccess
366
- * @instance
367
- * @type {Object}
368
- * @property {Object} reconnect
369
- * @memberof Meeting
370
- */
368
+ * Reconnection Success Event
369
+ * Emitted when reconnection of media to the active meeting was successful
370
+ * @event meeting:reconnectionSuccess
371
+ * @instance
372
+ * @type {Object}
373
+ * @property {Object} reconnect
374
+ * @memberof Meeting
375
+ */
371
376
 
372
377
  /**
373
- * Reconnection Failure Event
374
- * Emitted when reconnection of media to the active meeting was successful
375
- * @event meeting:reconnectionFailure
376
- * @instance
377
- * @type {Object}
378
- * @property {Error} error
379
- * @memberof Meeting
380
- */
378
+ * Reconnection Failure Event
379
+ * Emitted when reconnection of media to the active meeting was successful
380
+ * @event meeting:reconnectionFailure
381
+ * @instance
382
+ * @type {Object}
383
+ * @property {Error} error
384
+ * @memberof Meeting
385
+ */
381
386
 
382
387
  /**
383
- * Meeting network quality event
384
- * Emitted on each interval of retrieving stats Analyzer data
385
- * @event network:quality
386
- * @type {Object}
387
- * @property {string} mediaType {video|audio}
388
- * @property {number} networkQualityScore - {1|0} 1 indicates acceptable uplink 0 indicates unacceptable uplink based on threshold
389
- * @memberof Meeting
390
- */
388
+ * Meeting network quality event
389
+ * Emitted on each interval of retrieving stats Analyzer data
390
+ * @event network:quality
391
+ * @type {Object}
392
+ * @property {string} mediaType {video|audio}
393
+ * @property {number} networkQualityScore - {1|0} 1 indicates acceptable uplink 0 indicates unacceptable uplink based on threshold
394
+ * @memberof Meeting
395
+ */
391
396
 
392
397
  /**
393
398
  * @description Meeting is the crux of the plugin
@@ -470,6 +475,7 @@ export default class Meeting extends StatelessWebexPlugin {
470
475
  resourceUrl: string;
471
476
  selfId: string;
472
477
  state: any;
478
+
473
479
  namespace = MEETINGS;
474
480
 
475
481
  /**
@@ -477,7 +483,7 @@ export default class Meeting extends StatelessWebexPlugin {
477
483
  * @param {Object} options
478
484
  * @constructor
479
485
  * @memberof Meeting
480
- */
486
+ */
481
487
  constructor(attrs: any, options: object) {
482
488
  super({}, options);
483
489
  /**
@@ -755,7 +761,7 @@ export default class Meeting extends StatelessWebexPlugin {
755
761
  * @type {InMeetingActions}
756
762
  * @public
757
763
  * @memberof Meeting
758
- */
764
+ */
759
765
  this.inMeetingActions = new InMeetingActions();
760
766
  /**
761
767
  * This is deprecated, please use shareStatus instead.
@@ -796,7 +802,7 @@ export default class Meeting extends StatelessWebexPlugin {
796
802
 
797
803
  return false;
798
804
  },
799
- configurable: true
805
+ configurable: true,
800
806
  });
801
807
  /**
802
808
  * @instance
@@ -992,32 +998,55 @@ export default class Meeting extends StatelessWebexPlugin {
992
998
  * @memberof Meeting
993
999
  * @returns {Promise}
994
1000
  */
995
- public async fetchMeetingInfo({ password = null, captchaCode = null }: { password?: string; captchaCode?: string }) {
1001
+ public async fetchMeetingInfo({
1002
+ password = null,
1003
+ captchaCode = null,
1004
+ }: {
1005
+ password?: string;
1006
+ captchaCode?: string;
1007
+ }) {
996
1008
  // when fetch meeting info is called directly by the client, we want to clear out the random timer for sdk to do it
997
1009
  if (this.fetchMeetingInfoTimeoutId) {
998
1010
  clearTimeout(this.fetchMeetingInfoTimeoutId);
999
1011
  this.fetchMeetingInfoTimeoutId = undefined;
1000
1012
  }
1001
1013
  if (captchaCode && !this.requiredCaptcha) {
1002
- return Promise.reject(new Error('fetchMeetingInfo() called with captchaCode when captcha was not required'));
1014
+ return Promise.reject(
1015
+ new Error('fetchMeetingInfo() called with captchaCode when captcha was not required')
1016
+ );
1003
1017
  }
1004
- if (password && (this.passwordStatus !== PASSWORD_STATUS.REQUIRED && this.passwordStatus !== PASSWORD_STATUS.UNKNOWN)) {
1005
- return Promise.reject(new Error('fetchMeetingInfo() called with password when password was not required'));
1018
+ if (
1019
+ password &&
1020
+ this.passwordStatus !== PASSWORD_STATUS.REQUIRED &&
1021
+ this.passwordStatus !== PASSWORD_STATUS.UNKNOWN
1022
+ ) {
1023
+ return Promise.reject(
1024
+ new Error('fetchMeetingInfo() called with password when password was not required')
1025
+ );
1006
1026
  }
1007
1027
 
1008
1028
  try {
1009
- const captchaInfo = captchaCode ? {code: captchaCode, id: this.requiredCaptcha.captchaId} : null;
1010
-
1011
- const info = await this.attrs.meetingInfoProvider.fetchMeetingInfo(this.destination, this.destinationType, password, captchaInfo);
1029
+ const captchaInfo = captchaCode
1030
+ ? {code: captchaCode, id: this.requiredCaptcha.captchaId}
1031
+ : null;
1032
+
1033
+ const info = await this.attrs.meetingInfoProvider.fetchMeetingInfo(
1034
+ this.destination,
1035
+ this.destinationType,
1036
+ password,
1037
+ captchaInfo
1038
+ );
1012
1039
 
1013
1040
  this.parseMeetingInfo(info, this.destination);
1014
1041
  this.meetingInfo = info ? info.body : null;
1015
1042
  this.meetingInfoFailureReason = MEETING_INFO_FAILURE_REASON.NONE;
1016
1043
  this.requiredCaptcha = null;
1017
- if ((this.passwordStatus === PASSWORD_STATUS.REQUIRED) || (this.passwordStatus === PASSWORD_STATUS.VERIFIED)) {
1044
+ if (
1045
+ this.passwordStatus === PASSWORD_STATUS.REQUIRED ||
1046
+ this.passwordStatus === PASSWORD_STATUS.VERIFIED
1047
+ ) {
1018
1048
  this.passwordStatus = PASSWORD_STATUS.VERIFIED;
1019
- }
1020
- else {
1049
+ } else {
1021
1050
  this.passwordStatus = PASSWORD_STATUS.NOT_REQUIRED;
1022
1051
  }
1023
1052
 
@@ -1025,17 +1054,18 @@ export default class Meeting extends StatelessWebexPlugin {
1025
1054
  this,
1026
1055
  {
1027
1056
  file: 'meetings',
1028
- function: 'fetchMeetingInfo'
1057
+ function: 'fetchMeetingInfo',
1029
1058
  },
1030
1059
  EVENT_TRIGGERS.MEETING_INFO_AVAILABLE
1031
1060
  );
1032
1061
 
1033
1062
  return Promise.resolve();
1034
- }
1035
- catch (err) {
1063
+ } catch (err) {
1036
1064
  if (err instanceof MeetingInfoV2PasswordError) {
1037
1065
  // @ts-ignore
1038
- LoggerProxy.logger.info(`Meeting:index#fetchMeetingInfo --> Info Unable to fetch meeting info for ${this.destination} - password required (code=${err?.body?.code}).`);
1066
+ LoggerProxy.logger.info(
1067
+ `Meeting:index#fetchMeetingInfo --> Info Unable to fetch meeting info for ${this.destination} - password required (code=${err?.body?.code}).`
1068
+ );
1039
1069
 
1040
1070
  // when wbxappapi requires password it still populates partial meeting info in the response
1041
1071
  if (err.meetingInfo) {
@@ -1050,26 +1080,26 @@ export default class Meeting extends StatelessWebexPlugin {
1050
1080
  await this.refreshCaptcha();
1051
1081
  }
1052
1082
 
1053
- throw (new PasswordError());
1054
- }
1055
- else if (err instanceof MeetingInfoV2CaptchaError) {
1083
+ throw new PasswordError();
1084
+ } else if (err instanceof MeetingInfoV2CaptchaError) {
1056
1085
  // @ts-ignore
1057
- LoggerProxy.logger.info(`Meeting:index#fetchMeetingInfo --> Info Unable to fetch meeting info for ${this.destination} - captcha required (code=${err?.body?.code}).`);
1086
+ LoggerProxy.logger.info(
1087
+ `Meeting:index#fetchMeetingInfo --> Info Unable to fetch meeting info for ${this.destination} - captcha required (code=${err?.body?.code}).`
1088
+ );
1058
1089
 
1059
- this.meetingInfoFailureReason = (this.requiredCaptcha) ?
1060
- MEETING_INFO_FAILURE_REASON.WRONG_CAPTCHA :
1061
- MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD;
1090
+ this.meetingInfoFailureReason = this.requiredCaptcha
1091
+ ? MEETING_INFO_FAILURE_REASON.WRONG_CAPTCHA
1092
+ : MEETING_INFO_FAILURE_REASON.WRONG_PASSWORD;
1062
1093
 
1063
1094
  if (err.isPasswordRequired) {
1064
1095
  this.passwordStatus = PASSWORD_STATUS.REQUIRED;
1065
1096
  }
1066
1097
 
1067
1098
  this.requiredCaptcha = err.captchaInfo;
1068
- throw (new CaptchaError());
1069
- }
1070
- else {
1099
+ throw new CaptchaError();
1100
+ } else {
1071
1101
  this.meetingInfoFailureReason = MEETING_INFO_FAILURE_REASON.OTHER;
1072
- throw (err);
1102
+ throw err;
1073
1103
  }
1074
1104
  }
1075
1105
  }
@@ -1085,24 +1115,27 @@ export default class Meeting extends StatelessWebexPlugin {
1085
1115
  */
1086
1116
  public verifyPassword(password: string, captchaCode: string) {
1087
1117
  return this.fetchMeetingInfo({
1088
- password, captchaCode
1118
+ password,
1119
+ captchaCode,
1089
1120
  })
1090
1121
  .then(() => {
1091
- Metrics.sendBehavioralMetric(
1092
- BEHAVIORAL_METRICS.VERIFY_PASSWORD_SUCCESS
1093
- );
1122
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.VERIFY_PASSWORD_SUCCESS);
1094
1123
 
1095
- return {isPasswordValid: true, requiredCaptcha: null, failureReason: MEETING_INFO_FAILURE_REASON.NONE};
1124
+ return {
1125
+ isPasswordValid: true,
1126
+ requiredCaptcha: null,
1127
+ failureReason: MEETING_INFO_FAILURE_REASON.NONE,
1128
+ };
1096
1129
  })
1097
1130
  .catch((error) => {
1098
1131
  if (error instanceof PasswordError || error instanceof CaptchaError) {
1099
1132
  return {
1100
1133
  isPasswordValid: this.passwordStatus === PASSWORD_STATUS.VERIFIED,
1101
1134
  requiredCaptcha: this.requiredCaptcha,
1102
- failureReason: this.meetingInfoFailureReason
1135
+ failureReason: this.meetingInfoFailureReason,
1103
1136
  };
1104
1137
  }
1105
- throw (error);
1138
+ throw error;
1106
1139
  });
1107
1140
  }
1108
1141
 
@@ -1122,18 +1155,21 @@ export default class Meeting extends StatelessWebexPlugin {
1122
1155
  // we have to pass the wbxappapi hostname as the siteFullName parameter
1123
1156
  const {hostname} = new URL(this.requiredCaptcha.refreshURL);
1124
1157
 
1125
- return this.meetingRequest.refreshCaptcha({
1126
- captchaRefreshUrl: `${this.requiredCaptcha.refreshURL}&siteFullName=${hostname}`,
1127
- captchaId: this.requiredCaptcha.captchaId
1128
- })
1158
+ return this.meetingRequest
1159
+ .refreshCaptcha({
1160
+ captchaRefreshUrl: `${this.requiredCaptcha.refreshURL}&siteFullName=${hostname}`,
1161
+ captchaId: this.requiredCaptcha.captchaId,
1162
+ })
1129
1163
  .then((response) => {
1130
1164
  this.requiredCaptcha.captchaId = response.body.captchaID;
1131
1165
  this.requiredCaptcha.verificationImageURL = response.body.verificationImageURL;
1132
1166
  this.requiredCaptcha.verificationAudioURL = response.body.verificationAudioURL;
1133
1167
  })
1134
1168
  .catch((error) => {
1135
- LoggerProxy.logger.error(`Meeting:index#refreshCaptcha --> Error Unable to refresh captcha for ${this.destination} - ${error}`);
1136
- throw (error);
1169
+ LoggerProxy.logger.error(
1170
+ `Meeting:index#refreshCaptcha --> Error Unable to refresh captcha for ${this.destination} - ${error}`
1171
+ );
1172
+ throw error;
1137
1173
  });
1138
1174
  }
1139
1175
 
@@ -1173,13 +1209,10 @@ export default class Meeting extends StatelessWebexPlugin {
1173
1209
  // https:// jira-eng-gpk2.cisco.com/jira/browse/SPARK-240520
1174
1210
  // TODO: send custom parameter explaining why the inactivity happened
1175
1211
  // refresh , no media or network got dsconnected or something else
1176
- Metrics.sendBehavioralMetric(
1177
- BEHAVIORAL_METRICS.DISCONNECT_DUE_TO_INACTIVITY,
1178
- {
1179
- correlation_id: this.correlationId,
1180
- locus_id: this.locusId
1181
- }
1182
- );
1212
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.DISCONNECT_DUE_TO_INACTIVITY, {
1213
+ correlation_id: this.correlationId,
1214
+ locus_id: this.locusId,
1215
+ });
1183
1216
 
1184
1217
  // Upload logs on media inactivity
1185
1218
  // Normally media should not be inactive
@@ -1187,24 +1220,25 @@ export default class Meeting extends StatelessWebexPlugin {
1187
1220
  this,
1188
1221
  {
1189
1222
  file: 'meeting/index',
1190
- function: 'setUpLocusInfoMediaInactiveListener'
1223
+ function: 'setUpLocusInfoMediaInactiveListener',
1191
1224
  },
1192
1225
  EVENTS.REQUEST_UPLOAD_LOGS,
1193
1226
  this
1194
1227
  );
1195
1228
 
1196
- LoggerProxy.logger.error(`Meeting:index#setUpLocusInfoMediaInactiveListener --> Meeting disconnected due to inactivity: ${res.reason}`);
1229
+ LoggerProxy.logger.error(
1230
+ `Meeting:index#setUpLocusInfoMediaInactiveListener --> Meeting disconnected due to inactivity: ${res.reason}`
1231
+ );
1197
1232
 
1198
1233
  // @ts-ignore - config coming from registerPlugin
1199
1234
  if (this.config.reconnection.autoRejoin) {
1200
1235
  this.reconnect();
1201
- }
1202
- else {
1236
+ } else {
1203
1237
  Trigger.trigger(
1204
1238
  this,
1205
1239
  {
1206
1240
  file: 'meeting/index',
1207
- function: 'setUpLocusInfoMediaInactiveListener'
1241
+ function: 'setUpLocusInfoMediaInactiveListener',
1208
1242
  },
1209
1243
  EVENT_TRIGGERS.MEETING_SELF_LEFT,
1210
1244
  res.reason
@@ -1230,7 +1264,7 @@ export default class Meeting extends StatelessWebexPlugin {
1230
1264
  this,
1231
1265
  {
1232
1266
  file: 'meeting/index',
1233
- function: 'setUpLocusInfoAssignHostListener'
1267
+ function: 'setUpLocusInfoAssignHostListener',
1234
1268
  },
1235
1269
  EVENT_TRIGGERS.MEETING_ACTIONS_UPDATE,
1236
1270
  this.inMeetingActions.get()
@@ -1251,11 +1285,11 @@ export default class Meeting extends StatelessWebexPlugin {
1251
1285
  this,
1252
1286
  {
1253
1287
  file: 'meeting/index',
1254
- function: 'setUpLocusFullStateListener'
1288
+ function: 'setUpLocusFullStateListener',
1255
1289
  },
1256
1290
  EVENT_TRIGGERS.MEETING_STATE_CHANGE,
1257
1291
  {
1258
- payload
1292
+ payload,
1259
1293
  }
1260
1294
  );
1261
1295
  });
@@ -1276,22 +1310,26 @@ export default class Meeting extends StatelessWebexPlugin {
1276
1310
  * @returns {Object}
1277
1311
  * @memberof Meeting
1278
1312
  */
1279
- getAnalyzerMetricsPrePayload(options: {
1280
- event: string;
1281
- trackingId: string;
1282
- locus: object;
1283
- mediaConnections: Array<any>;
1284
- errors: object;
1285
- } | any) {
1313
+ getAnalyzerMetricsPrePayload(
1314
+ options:
1315
+ | {
1316
+ event: string;
1317
+ trackingId: string;
1318
+ locus: object;
1319
+ mediaConnections: Array<any>;
1320
+ errors: object;
1321
+ }
1322
+ | any
1323
+ ) {
1286
1324
  if (options) {
1287
- const {
1288
- event,
1289
- trackingId,
1290
- mediaConnections
1291
- } = options;
1325
+ const {event, trackingId, mediaConnections} = options;
1292
1326
 
1293
1327
  if (!event) {
1294
- LoggerProxy.logger.error('Meeting:index#getAnalyzerMetricsPrePayload --> Error [Call Analyzer Event', event || '', `]: invalid identifers or event type! ${this.correlationId}`);
1328
+ LoggerProxy.logger.error(
1329
+ 'Meeting:index#getAnalyzerMetricsPrePayload --> Error [Call Analyzer Event',
1330
+ event || '',
1331
+ `]: invalid identifers or event type! ${this.correlationId}`
1332
+ );
1295
1333
 
1296
1334
  return null;
1297
1335
  }
@@ -1302,13 +1340,14 @@ export default class Meeting extends StatelessWebexPlugin {
1302
1340
  deviceId: this.deviceUrl,
1303
1341
  orgId: this.orgId,
1304
1342
  // @ts-ignore fix type
1305
- locusUrl: this.webex.internal.services.get('locus')
1343
+ locusUrl: this.webex.internal.services.get('locus'),
1306
1344
  };
1307
1345
 
1308
1346
  if (this.locusUrl && this.locusInfo.fullState) {
1309
1347
  identifiers.locusUrl = this.locusUrl;
1310
1348
  identifiers.locusId = this.locusUrl && this.locusUrl.split('/').pop();
1311
- identifiers.locusStartTime = this.locusInfo.fullState && this.locusInfo.fullState.lastActive;
1349
+ identifiers.locusStartTime =
1350
+ this.locusInfo.fullState && this.locusInfo.fullState.lastActive;
1312
1351
  }
1313
1352
 
1314
1353
  // Check if mediaConnections has been passed in or else use this.mediaConnections
@@ -1316,8 +1355,7 @@ export default class Meeting extends StatelessWebexPlugin {
1316
1355
  identifiers.mediaAgentAlias = mediaConnections?.[0].mediaAgentAlias;
1317
1356
  identifiers.mediaAgentGroupId = mediaConnections?.[0].mediaAgentGroupId;
1318
1357
  identifiers.mediaAgentCluster = mediaConnections?.[0].mediaAgentCluster;
1319
- }
1320
- else if (this.mediaConnections) {
1358
+ } else if (this.mediaConnections) {
1321
1359
  identifiers.mediaAgentAlias = this.mediaConnections?.[0].mediaAgentAlias;
1322
1360
  identifiers.mediaAgentGroupId = this.mediaConnections?.[0].mediaAgentGroupId;
1323
1361
  identifiers.mediaAgentCluster = this.mediaConnections?.[0].mediaAgentCluster;
@@ -1333,7 +1371,7 @@ export default class Meeting extends StatelessWebexPlugin {
1333
1371
 
1334
1372
  if (joinRespRxStartAudio) {
1335
1373
  options.audioSetupDelay = {
1336
- joinRespRxStart: joinRespRxStartAudio
1374
+ joinRespRxStart: joinRespRxStartAudio,
1337
1375
  };
1338
1376
  }
1339
1377
 
@@ -1341,7 +1379,7 @@ export default class Meeting extends StatelessWebexPlugin {
1341
1379
 
1342
1380
  if (joinRespRxStartAudio) {
1343
1381
  options.videoSetupDelay = {
1344
- joinRespRxStart: joinRespRxStartVideo
1382
+ joinRespRxStart: joinRespRxStartVideo,
1345
1383
  };
1346
1384
  }
1347
1385
 
@@ -1350,7 +1388,7 @@ export default class Meeting extends StatelessWebexPlugin {
1350
1388
  if (joinRespTxStartAudio) {
1351
1389
  options.audioSetupDelay = {
1352
1390
  ...options.audioSetupDelay,
1353
- joinRespTxStart: joinRespTxStartAudio
1391
+ joinRespTxStart: joinRespTxStartAudio,
1354
1392
  };
1355
1393
  }
1356
1394
 
@@ -1359,7 +1397,7 @@ export default class Meeting extends StatelessWebexPlugin {
1359
1397
  if (joinRespTxStartVideo) {
1360
1398
  options.videoSetupDelay = {
1361
1399
  ...options.videoSetupDelay,
1362
- joinRespTxStart: joinRespTxStartVideo
1400
+ joinRespTxStart: joinRespTxStartVideo,
1363
1401
  };
1364
1402
  }
1365
1403
 
@@ -1368,7 +1406,7 @@ export default class Meeting extends StatelessWebexPlugin {
1368
1406
  if (localSDPGenRemoteSDPRecv) {
1369
1407
  options.joinTimes = {
1370
1408
  ...options.joinTimes,
1371
- localSDPGenRemoteSDPRecv
1409
+ localSDPGenRemoteSDPRecv,
1372
1410
  };
1373
1411
  }
1374
1412
 
@@ -1377,7 +1415,7 @@ export default class Meeting extends StatelessWebexPlugin {
1377
1415
  if (callInitiateJoinReq) {
1378
1416
  options.joinTimes = {
1379
1417
  ...options.joinTimes,
1380
- callInitiateJoinReq
1418
+ callInitiateJoinReq,
1381
1419
  };
1382
1420
  }
1383
1421
 
@@ -1386,7 +1424,7 @@ export default class Meeting extends StatelessWebexPlugin {
1386
1424
  if (joinReqResp) {
1387
1425
  options.joinTimes = {
1388
1426
  ...options.joinTimes,
1389
- joinReqResp
1427
+ joinReqResp,
1390
1428
  };
1391
1429
  }
1392
1430
 
@@ -1395,14 +1433,13 @@ export default class Meeting extends StatelessWebexPlugin {
1395
1433
  if (getTotalJmt) {
1396
1434
  options.joinTimes = {
1397
1435
  ...options.joinTimes,
1398
- getTotalJmt
1436
+ getTotalJmt,
1399
1437
  };
1400
1438
  }
1401
1439
 
1402
1440
  if (options.type === MQA_STATS.CA_TYPE) {
1403
1441
  payload = Metrics.initMediaPayload(options.event, identifiers, options);
1404
- }
1405
- else {
1442
+ } else {
1406
1443
  payload = Metrics.initPayload(options.event, identifiers, options);
1407
1444
  }
1408
1445
 
@@ -1423,11 +1460,16 @@ export default class Meeting extends StatelessWebexPlugin {
1423
1460
  * @private
1424
1461
  * @memberof Meeting
1425
1462
  */
1426
- private sendCallAnalyzerMetrics(options: { event: string; trackingId: string; locus: object; errors: object }) {
1463
+ private sendCallAnalyzerMetrics(options: {
1464
+ event: string;
1465
+ trackingId: string;
1466
+ locus: object;
1467
+ errors: object;
1468
+ }) {
1427
1469
  const payload = this.getAnalyzerMetricsPrePayload({
1428
1470
  // @ts-ignore - config coming from registerPlugin
1429
1471
  ...pick(this.config.metrics, ['clientType', 'subClientType']),
1430
- ...options
1472
+ ...options,
1431
1473
  });
1432
1474
 
1433
1475
  // @ts-ignore - fix type
@@ -1444,12 +1486,16 @@ export default class Meeting extends StatelessWebexPlugin {
1444
1486
  * @private
1445
1487
  * @memberof Meeting
1446
1488
  */
1447
- private sendMediaQualityAnalyzerMetrics(options: { event: string; trackingId: string; locus: object }) {
1489
+ private sendMediaQualityAnalyzerMetrics(options: {
1490
+ event: string;
1491
+ trackingId: string;
1492
+ locus: object;
1493
+ }) {
1448
1494
  const payload = this.getAnalyzerMetricsPrePayload({
1449
1495
  type: MQA_STATS.CA_TYPE,
1450
1496
  // @ts-ignore - config coming from registerPlugin
1451
1497
  ...pick(this.config.metrics, ['clientType', 'subClientType']),
1452
- ...options
1498
+ ...options,
1453
1499
  });
1454
1500
 
1455
1501
  // @ts-ignore
@@ -1469,19 +1515,21 @@ export default class Meeting extends StatelessWebexPlugin {
1469
1515
  this,
1470
1516
  {
1471
1517
  file: 'meeting/index',
1472
- function: 'setNetworkStatus'
1518
+ function: 'setNetworkStatus',
1473
1519
  },
1474
- EVENT_TRIGGERS.MEETINGS_NETWORK_DISCONNECTED,
1520
+ EVENT_TRIGGERS.MEETINGS_NETWORK_DISCONNECTED
1475
1521
  );
1476
- }
1477
- else if (networkStatus === NETWORK_STATUS.CONNECTED && this.networkStatus === NETWORK_STATUS.DISCONNECTED) {
1522
+ } else if (
1523
+ networkStatus === NETWORK_STATUS.CONNECTED &&
1524
+ this.networkStatus === NETWORK_STATUS.DISCONNECTED
1525
+ ) {
1478
1526
  Trigger.trigger(
1479
1527
  this,
1480
1528
  {
1481
1529
  file: 'meeting/index',
1482
- function: 'setNetworkStatus'
1530
+ function: 'setNetworkStatus',
1483
1531
  },
1484
- EVENT_TRIGGERS.MEETINGS_NETWORK_CONNECTED,
1532
+ EVENT_TRIGGERS.MEETINGS_NETWORK_CONNECTED
1485
1533
  );
1486
1534
  }
1487
1535
 
@@ -1503,8 +1551,9 @@ export default class Meeting extends StatelessWebexPlugin {
1503
1551
 
1504
1552
  // If user moved to a JOINED state and there is a pending floor grant trigger it
1505
1553
  if (this.floorGrantPending && payload.newSelf.state === MEETING_STATE.STATES.JOINED) {
1506
- this.requestScreenShareFloor()
1507
- .then(() => { this.floorGrantPending = false; });
1554
+ this.requestScreenShareFloor().then(() => {
1555
+ this.floorGrantPending = false;
1556
+ });
1508
1557
  }
1509
1558
  });
1510
1559
  }
@@ -1518,8 +1567,12 @@ export default class Meeting extends StatelessWebexPlugin {
1518
1567
  */
1519
1568
  private pstnUpdate(payload: any) {
1520
1569
  if (this.locusInfo.self) {
1521
- const dialInPstnDevice = payload.newSelf?.pstnDevices.find((device) => device.url === this.dialInUrl);
1522
- const dialOutPstnDevice = payload.newSelf?.pstnDevices.find((device) => device.url === this.dialOutUrl);
1570
+ const dialInPstnDevice = payload.newSelf?.pstnDevices.find(
1571
+ (device) => device.url === this.dialInUrl
1572
+ );
1573
+ const dialOutPstnDevice = payload.newSelf?.pstnDevices.find(
1574
+ (device) => device.url === this.dialOutUrl
1575
+ );
1523
1576
  let changed = false;
1524
1577
 
1525
1578
  if (dialInPstnDevice) {
@@ -1545,18 +1598,18 @@ export default class Meeting extends StatelessWebexPlugin {
1545
1598
  this,
1546
1599
  {
1547
1600
  file: 'meeting/index',
1548
- function: 'setUpLocusSelfListener'
1601
+ function: 'setUpLocusSelfListener',
1549
1602
  },
1550
1603
  EVENT_TRIGGERS.MEETING_SELF_PHONE_AUDIO_UPDATE,
1551
1604
  {
1552
1605
  dialIn: {
1553
1606
  status: this.dialInDeviceStatus,
1554
- attendeeId: dialInPstnDevice?.attendeeId
1607
+ attendeeId: dialInPstnDevice?.attendeeId,
1555
1608
  },
1556
1609
  dialOut: {
1557
1610
  status: this.dialOutDeviceStatus,
1558
- attendeeId: dialOutPstnDevice?.attendeeId
1559
- }
1611
+ attendeeId: dialOutPstnDevice?.attendeeId,
1612
+ },
1560
1613
  }
1561
1614
  );
1562
1615
  }
@@ -1609,8 +1662,9 @@ export default class Meeting extends StatelessWebexPlugin {
1609
1662
  * @private
1610
1663
  * @memberof Meeting
1611
1664
  */
1612
- private setupLocusControlsListener() {
1613
- this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
1665
+ private setupLocusControlsListener() {
1666
+ this.locusInfo.on(
1667
+ LOCUSINFO.EVENTS.CONTROLS_RECORDING_UPDATED,
1614
1668
  ({state, modifiedBy, lastModified}) => {
1615
1669
  let event;
1616
1670
 
@@ -1636,65 +1690,67 @@ export default class Meeting extends StatelessWebexPlugin {
1636
1690
  this.recording = {
1637
1691
  state: state === RECORDING_STATE.RESUMED ? RECORDING_STATE.RECORDING : state,
1638
1692
  modifiedBy,
1639
- lastModified
1693
+ lastModified,
1640
1694
  };
1641
1695
 
1642
1696
  Trigger.trigger(
1643
1697
  this,
1644
1698
  {
1645
1699
  file: 'meeting/index',
1646
- function: 'setupLocusControlsListener'
1700
+ function: 'setupLocusControlsListener',
1647
1701
  },
1648
1702
  event,
1649
1703
  this.recording
1650
1704
  );
1651
- });
1705
+ }
1706
+ );
1652
1707
 
1653
- this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
1708
+ this.locusInfo.on(
1709
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_CONTAINER_UPDATED,
1654
1710
  ({meetingContainerUrl}) => {
1655
1711
  Trigger.trigger(
1656
1712
  this,
1657
1713
  {
1658
1714
  file: 'meeting/index',
1659
- function: 'setupLocusControlsListener'
1715
+ function: 'setupLocusControlsListener',
1660
1716
  },
1661
1717
  EVENT_TRIGGERS.MEETING_MEETING_CONTAINER_UPDATE,
1662
1718
  {meetingContainerUrl}
1663
1719
  );
1664
- });
1720
+ }
1721
+ );
1665
1722
 
1666
- this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIBE_UPDATED,
1723
+ this.locusInfo.on(
1724
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIBE_UPDATED,
1667
1725
  ({caption, transcribing}) => {
1668
-
1669
1726
  // @ts-ignore - config coming from registerPlugin
1670
1727
  if (transcribing && this.transcription && this.config.receiveTranscription) {
1671
1728
  this.receiveTranscription();
1672
- }
1673
- else if (!transcribing && this.transcription) {
1729
+ } else if (!transcribing && this.transcription) {
1674
1730
  Trigger.trigger(
1675
1731
  this,
1676
1732
  {
1677
1733
  file: 'meeting/index',
1678
- function: 'setupLocusControlsListener'
1734
+ function: 'setupLocusControlsListener',
1679
1735
  },
1680
1736
  EVENT_TRIGGERS.MEETING_STOPPED_RECEIVING_TRANSCRIPTION,
1681
1737
  {caption, transcribing}
1682
1738
  );
1683
1739
  }
1684
- });
1740
+ }
1741
+ );
1685
1742
 
1686
- this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED,
1687
- ({entryExitTone}) => {
1688
- Trigger.trigger(
1689
- this,
1690
- {
1691
- file: 'meeting/index',
1692
- function: 'setupLocusControlsListener'
1693
- },
1694
- EVENT_TRIGGERS.MEETING_ENTRY_EXIT_TONE_UPDATE,
1695
- {entryExitTone}
1696
- );
1697
- });
1743
+ this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_ENTRY_EXIT_TONE_UPDATED, ({entryExitTone}) => {
1744
+ Trigger.trigger(
1745
+ this,
1746
+ {
1747
+ file: 'meeting/index',
1748
+ function: 'setupLocusControlsListener',
1749
+ },
1750
+ EVENT_TRIGGERS.MEETING_ENTRY_EXIT_TONE_UPDATE,
1751
+ {entryExitTone}
1752
+ );
1753
+ });
1698
1754
  }
1699
1755
 
1700
1756
  /**
@@ -1705,7 +1761,7 @@ export default class Meeting extends StatelessWebexPlugin {
1705
1761
  * @private
1706
1762
  * @memberof Meeting
1707
1763
  */
1708
- private setUpLocusMediaSharesListener() {
1764
+ private setUpLocusMediaSharesListener() {
1709
1765
  // Will get triggered on local and remote share
1710
1766
  this.locusInfo.on(EVENTS.LOCUS_INFO_UPDATE_MEDIA_SHARES, (payload) => {
1711
1767
  const {content: contentShare, whiteboard: whiteboardShare} = payload.current;
@@ -1713,11 +1769,11 @@ export default class Meeting extends StatelessWebexPlugin {
1713
1769
  const previousWhiteboardShare = payload.previous?.whiteboard;
1714
1770
 
1715
1771
  if (
1716
- (contentShare.beneficiaryId === previousContentShare?.beneficiaryId &&
1717
- contentShare.disposition === previousContentShare?.disposition) &&
1718
- (whiteboardShare.beneficiaryId === previousWhiteboardShare?.beneficiaryId &&
1719
- whiteboardShare.disposition === previousWhiteboardShare?.disposition &&
1720
- whiteboardShare.resourceUrl === previousWhiteboardShare?.resourceUrl)
1772
+ contentShare.beneficiaryId === previousContentShare?.beneficiaryId &&
1773
+ contentShare.disposition === previousContentShare?.disposition &&
1774
+ whiteboardShare.beneficiaryId === previousWhiteboardShare?.beneficiaryId &&
1775
+ whiteboardShare.disposition === previousWhiteboardShare?.disposition &&
1776
+ whiteboardShare.resourceUrl === previousWhiteboardShare?.resourceUrl
1721
1777
  ) {
1722
1778
  // nothing changed, so ignore
1723
1779
  // (this happens when we steal presentation from remote)
@@ -1741,13 +1797,14 @@ export default class Meeting extends StatelessWebexPlugin {
1741
1797
  ) {
1742
1798
  if (this.mediaProperties.shareTrack?.readyState === 'ended') {
1743
1799
  this.stopShare({
1744
- skipSignalingCheck: true
1745
- })
1746
- .catch((error) => {
1747
- LoggerProxy.logger.log('Meeting:index#setUpLocusMediaSharesListener --> Error stopping share: ', error);
1748
- });
1749
- }
1750
- else {
1800
+ skipSignalingCheck: true,
1801
+ }).catch((error) => {
1802
+ LoggerProxy.logger.log(
1803
+ 'Meeting:index#setUpLocusMediaSharesListener --> Error stopping share: ',
1804
+ error
1805
+ );
1806
+ });
1807
+ } else {
1751
1808
  // CONTENT - sharing content local
1752
1809
  newShareStatus = SHARE_STATUS.LOCAL_SHARE_ACTIVE;
1753
1810
  }
@@ -1761,10 +1818,10 @@ export default class Meeting extends StatelessWebexPlugin {
1761
1818
  }
1762
1819
  // or if content share is either released or null and whiteboard share is either released or null, no one is sharing
1763
1820
  else if (
1764
- (previousContentShare &&
1765
- (contentShare.disposition === FLOOR_ACTION.RELEASED) || (contentShare.disposition === null)) &&
1766
- (previousWhiteboardShare &&
1767
- (whiteboardShare.disposition === FLOOR_ACTION.RELEASED) || (whiteboardShare.disposition === null))
1821
+ ((previousContentShare && contentShare.disposition === FLOOR_ACTION.RELEASED) ||
1822
+ contentShare.disposition === null) &&
1823
+ ((previousWhiteboardShare && whiteboardShare.disposition === FLOOR_ACTION.RELEASED) ||
1824
+ whiteboardShare.disposition === null)
1768
1825
  ) {
1769
1826
  newShareStatus = SHARE_STATUS.NO_SHARE;
1770
1827
  }
@@ -1782,7 +1839,7 @@ export default class Meeting extends StatelessWebexPlugin {
1782
1839
  this,
1783
1840
  {
1784
1841
  file: 'meetings/index',
1785
- function: 'remoteShare'
1842
+ function: 'remoteShare',
1786
1843
  },
1787
1844
  EVENT_TRIGGERS.MEETING_STOPPED_SHARING_REMOTE
1788
1845
  );
@@ -1793,11 +1850,11 @@ export default class Meeting extends StatelessWebexPlugin {
1793
1850
  this,
1794
1851
  {
1795
1852
  file: 'meeting/index',
1796
- function: 'localShare'
1853
+ function: 'stopFloorRequest',
1797
1854
  },
1798
1855
  EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
1799
1856
  {
1800
- reason: SHARE_STOPPED_REASON.SELF_STOPPED
1857
+ reason: SHARE_STOPPED_REASON.SELF_STOPPED,
1801
1858
  }
1802
1859
  );
1803
1860
  break;
@@ -1807,7 +1864,7 @@ export default class Meeting extends StatelessWebexPlugin {
1807
1864
  this,
1808
1865
  {
1809
1866
  file: 'meeting/index',
1810
- function: 'stopWhiteboardShare'
1867
+ function: 'stopWhiteboardShare',
1811
1868
  },
1812
1869
  EVENT_TRIGGERS.MEETING_STOPPED_SHARING_WHITEBOARD
1813
1870
  );
@@ -1829,27 +1886,28 @@ export default class Meeting extends StatelessWebexPlugin {
1829
1886
  this,
1830
1887
  {
1831
1888
  file: 'meetings/index',
1832
- function: 'remoteShare'
1889
+ function: 'remoteShare',
1833
1890
  },
1834
1891
  EVENT_TRIGGERS.MEETING_STARTED_SHARING_REMOTE,
1835
1892
  {
1836
- memberId: contentShare.beneficiaryId
1893
+ memberId: contentShare.beneficiaryId,
1837
1894
  }
1838
1895
  );
1839
1896
  };
1840
1897
 
1841
1898
  // if a remote participant is stealing the presentation from us
1842
- if (!this.mediaProperties.mediaDirection?.sendShare || oldShareStatus === SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE) {
1899
+ if (
1900
+ !this.mediaProperties.mediaDirection?.sendShare ||
1901
+ oldShareStatus === SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE
1902
+ ) {
1843
1903
  sendStartedSharingRemote();
1844
- }
1845
- else {
1904
+ } else {
1846
1905
  this.updateShare({
1847
1906
  sendShare: false,
1848
- receiveShare: this.mediaProperties.mediaDirection.receiveShare
1849
- })
1850
- .finally(() => {
1851
- sendStartedSharingRemote();
1852
- });
1907
+ receiveShare: this.mediaProperties.mediaDirection.receiveShare,
1908
+ }).finally(() => {
1909
+ sendStartedSharingRemote();
1910
+ });
1853
1911
  }
1854
1912
  break;
1855
1913
  }
@@ -1859,9 +1917,9 @@ export default class Meeting extends StatelessWebexPlugin {
1859
1917
  this,
1860
1918
  {
1861
1919
  file: 'meeting/index',
1862
- function: 'share'
1920
+ function: 'share',
1863
1921
  },
1864
- EVENT_TRIGGERS.MEETING_STARTED_SHARING_LOCAL,
1922
+ EVENT_TRIGGERS.MEETING_STARTED_SHARING_LOCAL
1865
1923
  );
1866
1924
  Metrics.postEvent({event: eventType.LOCAL_SHARE_FLOOR_GRANTED, meeting: this});
1867
1925
  break;
@@ -1871,19 +1929,19 @@ export default class Meeting extends StatelessWebexPlugin {
1871
1929
  this,
1872
1930
  {
1873
1931
  file: 'meeting/index',
1874
- function: 'startWhiteboardShare'
1932
+ function: 'startWhiteboardShare',
1875
1933
  },
1876
1934
  EVENT_TRIGGERS.MEETING_STARTED_SHARING_WHITEBOARD,
1877
1935
  {
1878
1936
  resourceUrl: whiteboardShare.resourceUrl,
1879
- memberId: whiteboardShare.beneficiaryId
1937
+ memberId: whiteboardShare.beneficiaryId,
1880
1938
  }
1881
1939
  );
1882
1940
  Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_FLOOR_GRANTED, meeting: this});
1883
1941
  break;
1884
1942
 
1885
1943
  case SHARE_STATUS.NO_SHARE:
1886
- // nothing to do
1944
+ // nothing to do
1887
1945
  break;
1888
1946
 
1889
1947
  default:
@@ -1891,36 +1949,34 @@ export default class Meeting extends StatelessWebexPlugin {
1891
1949
  }
1892
1950
 
1893
1951
  this.members.locusMediaSharesUpdate(payload);
1894
- }
1895
- else if (newShareStatus === SHARE_STATUS.REMOTE_SHARE_ACTIVE) {
1952
+ } else if (newShareStatus === SHARE_STATUS.REMOTE_SHARE_ACTIVE) {
1896
1953
  // if we got here, then some remote participant has stolen
1897
1954
  // the presentation from another remote participant
1898
1955
  Trigger.trigger(
1899
1956
  this,
1900
1957
  {
1901
1958
  file: 'meetings/index',
1902
- function: 'remoteShare'
1959
+ function: 'remoteShare',
1903
1960
  },
1904
1961
  EVENT_TRIGGERS.MEETING_STARTED_SHARING_REMOTE,
1905
1962
  {
1906
- memberId: contentShare.beneficiaryId
1963
+ memberId: contentShare.beneficiaryId,
1907
1964
  }
1908
1965
  );
1909
1966
  this.members.locusMediaSharesUpdate(payload);
1910
- }
1911
- else if (newShareStatus === SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE) {
1967
+ } else if (newShareStatus === SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE) {
1912
1968
  // if we got here, then some remote participant has stolen
1913
1969
  // the presentation from another remote participant
1914
1970
  Trigger.trigger(
1915
1971
  this,
1916
1972
  {
1917
1973
  file: 'meeting/index',
1918
- function: 'startWhiteboardShare'
1974
+ function: 'startWhiteboardShare',
1919
1975
  },
1920
1976
  EVENT_TRIGGERS.MEETING_STARTED_SHARING_WHITEBOARD,
1921
1977
  {
1922
1978
  resourceUrl: whiteboardShare.resourceUrl,
1923
- memberId: whiteboardShare.beneficiaryId
1979
+ memberId: whiteboardShare.beneficiaryId,
1924
1980
  }
1925
1981
  );
1926
1982
  Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_FLOOR_GRANTED, meeting: this});
@@ -1957,11 +2013,11 @@ export default class Meeting extends StatelessWebexPlugin {
1957
2013
  this,
1958
2014
  {
1959
2015
  file: 'meeting/index',
1960
- function: 'setUpLocusInfoMeetingInfoListener'
2016
+ function: 'setUpLocusInfoMeetingInfoListener',
1961
2017
  },
1962
2018
  EVENT_TRIGGERS.MEETING_LOCKED,
1963
2019
  {
1964
- payload
2020
+ payload,
1965
2021
  }
1966
2022
  );
1967
2023
  }
@@ -1972,11 +2028,11 @@ export default class Meeting extends StatelessWebexPlugin {
1972
2028
  this,
1973
2029
  {
1974
2030
  file: 'meeting/index',
1975
- function: 'setUpLocusInfoMeetingInfoListener'
2031
+ function: 'setUpLocusInfoMeetingInfoListener',
1976
2032
  },
1977
2033
  EVENT_TRIGGERS.MEETING_UNLOCKED,
1978
2034
  {
1979
- payload
2035
+ payload,
1980
2036
  }
1981
2037
  );
1982
2038
  }
@@ -1984,7 +2040,9 @@ export default class Meeting extends StatelessWebexPlugin {
1984
2040
  this.locusInfo.on(LOCUSINFO.EVENTS.MEETING_INFO_UPDATED, (payload) => {
1985
2041
  if (payload && payload.info) {
1986
2042
  const changed = this.inMeetingActions.set({
1987
- canInviteNewParticipants: MeetingUtil.canInviteNewParticipants(payload.info.userDisplayHints),
2043
+ canInviteNewParticipants: MeetingUtil.canInviteNewParticipants(
2044
+ payload.info.userDisplayHints
2045
+ ),
1988
2046
  canAdmitParticipant: MeetingUtil.canAdmitParticipant(payload.info.userDisplayHints),
1989
2047
  canLock: MeetingUtil.canUserLock(payload.info.userDisplayHints),
1990
2048
  canUnlock: MeetingUtil.canUserUnlock(payload.info.userDisplayHints),
@@ -1994,16 +2052,24 @@ export default class Meeting extends StatelessWebexPlugin {
1994
2052
  canResumeRecording: MeetingUtil.canUserResume(payload.info.userDisplayHints),
1995
2053
  canRaiseHand: MeetingUtil.canUserRaiseHand(payload.info.userDisplayHints),
1996
2054
  canLowerAllHands: MeetingUtil.canUserLowerAllHands(payload.info.userDisplayHints),
1997
- canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(payload.info.userDisplayHints),
1998
- bothLeaveAndEndMeetingAvailable: MeetingUtil.bothLeaveAndEndMeetingAvailable(payload.info.userDisplayHints),
2055
+ canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(
2056
+ payload.info.userDisplayHints
2057
+ ),
2058
+ bothLeaveAndEndMeetingAvailable: MeetingUtil.bothLeaveAndEndMeetingAvailable(
2059
+ payload.info.userDisplayHints
2060
+ ),
1999
2061
  canEnableClosedCaption: MeetingUtil.canEnableClosedCaption(payload.info.userDisplayHints),
2000
2062
  canStartTranscribing: MeetingUtil.canStartTranscribing(payload.info.userDisplayHints),
2001
2063
  canStopTranscribing: MeetingUtil.canStopTranscribing(payload.info.userDisplayHints),
2002
2064
  isClosedCaptionActive: MeetingUtil.isClosedCaptionActive(payload.info.userDisplayHints),
2003
2065
  isWebexAssistantActive: MeetingUtil.isWebexAssistantActive(payload.info.userDisplayHints),
2004
2066
  canViewCaptionPanel: MeetingUtil.canViewCaptionPanel(payload.info.userDisplayHints),
2005
- isRealTimeTranslationEnabled: MeetingUtil.isRealTimeTranslationEnabled(payload.info.userDisplayHints),
2006
- canSelectSpokenLanguages: MeetingUtil.canSelectSpokenLanguages(payload.info.userDisplayHints),
2067
+ isRealTimeTranslationEnabled: MeetingUtil.isRealTimeTranslationEnabled(
2068
+ payload.info.userDisplayHints
2069
+ ),
2070
+ canSelectSpokenLanguages: MeetingUtil.canSelectSpokenLanguages(
2071
+ payload.info.userDisplayHints
2072
+ ),
2007
2073
  waitingForOthersToJoin: MeetingUtil.waitingForOthersToJoin(payload.info.userDisplayHints),
2008
2074
  });
2009
2075
 
@@ -2012,7 +2078,7 @@ export default class Meeting extends StatelessWebexPlugin {
2012
2078
  this,
2013
2079
  {
2014
2080
  file: 'meeting/index',
2015
- function: 'setUpLocusInfoMeetingInfoListener'
2081
+ function: 'setUpLocusInfoMeetingInfoListener',
2016
2082
  },
2017
2083
  EVENT_TRIGGERS.MEETING_ACTIONS_UPDATE,
2018
2084
  this.inMeetingActions.get()
@@ -2035,7 +2101,7 @@ export default class Meeting extends StatelessWebexPlugin {
2035
2101
  this,
2036
2102
  {
2037
2103
  file: 'meeting/index',
2038
- function: 'setUpLocusEmbeddedAppsListener'
2104
+ function: 'setUpLocusEmbeddedAppsListener',
2039
2105
  },
2040
2106
  EVENT_TRIGGERS.MEETING_EMBEDDED_APPS_UPDATE,
2041
2107
  embeddedApps
@@ -2058,11 +2124,11 @@ export default class Meeting extends StatelessWebexPlugin {
2058
2124
  this,
2059
2125
  {
2060
2126
  file: 'meeting/index',
2061
- function: 'setUpLocusInfoSelfListener'
2127
+ function: 'setUpLocusInfoSelfListener',
2062
2128
  },
2063
2129
  EVENT_TRIGGERS.MEETING_SELF_UNMUTED_BY_OTHERS,
2064
2130
  {
2065
- payload
2131
+ payload,
2066
2132
  }
2067
2133
  );
2068
2134
  }
@@ -2075,17 +2141,19 @@ export default class Meeting extends StatelessWebexPlugin {
2075
2141
  // with "mute on entry" server will send us remote mute even if we don't have media configured,
2076
2142
  // so if being muted by others, always send the notification,
2077
2143
  // but if being unmuted, only send it if we are also locally unmuted
2078
- if (payload.muted || (!this.audio?.isMuted())) {
2144
+ if (payload.muted || !this.audio?.isMuted()) {
2079
2145
  Trigger.trigger(
2080
2146
  this,
2081
2147
  {
2082
2148
  file: 'meeting/index',
2083
- function: 'setUpLocusInfoSelfListener'
2149
+ function: 'setUpLocusInfoSelfListener',
2084
2150
  },
2085
- payload.muted ? EVENT_TRIGGERS.MEETING_SELF_MUTED_BY_OTHERS : EVENT_TRIGGERS.MEETING_SELF_UNMUTED_BY_OTHERS,
2151
+ payload.muted
2152
+ ? EVENT_TRIGGERS.MEETING_SELF_MUTED_BY_OTHERS
2153
+ : EVENT_TRIGGERS.MEETING_SELF_UNMUTED_BY_OTHERS,
2086
2154
  {
2087
- payload
2088
- },
2155
+ payload,
2156
+ }
2089
2157
  );
2090
2158
  }
2091
2159
  }
@@ -2095,11 +2163,11 @@ export default class Meeting extends StatelessWebexPlugin {
2095
2163
  this,
2096
2164
  {
2097
2165
  file: 'meeting/index',
2098
- function: 'setUpLocusInfoSelfListener'
2166
+ function: 'setUpLocusInfoSelfListener',
2099
2167
  },
2100
2168
  EVENT_TRIGGERS.MEETING_SELF_REQUESTED_TO_UNMUTE,
2101
2169
  {
2102
- payload
2170
+ payload,
2103
2171
  }
2104
2172
  );
2105
2173
  });
@@ -2111,17 +2179,17 @@ export default class Meeting extends StatelessWebexPlugin {
2111
2179
  this,
2112
2180
  {
2113
2181
  file: 'meeting/index',
2114
- function: 'setUpLocusInfoSelfListener'
2182
+ function: 'setUpLocusInfoSelfListener',
2115
2183
  },
2116
2184
  EVENT_TRIGGERS.MEETING_SELF_LOBBY_WAITING,
2117
2185
  {
2118
- payload
2186
+ payload,
2119
2187
  }
2120
2188
  );
2121
2189
 
2122
2190
  Metrics.postEvent({
2123
2191
  event: eventType.LOBBY_ENTERED,
2124
- meeting: this
2192
+ meeting: this,
2125
2193
  });
2126
2194
  }
2127
2195
  });
@@ -2133,30 +2201,27 @@ export default class Meeting extends StatelessWebexPlugin {
2133
2201
  this,
2134
2202
  {
2135
2203
  file: 'meeting/index',
2136
- function: 'setUpLocusInfoSelfListener'
2204
+ function: 'setUpLocusInfoSelfListener',
2137
2205
  },
2138
2206
  EVENT_TRIGGERS.MEETING_SELF_GUEST_ADMITTED,
2139
2207
  {
2140
- payload
2208
+ payload,
2141
2209
  }
2142
2210
  );
2143
2211
 
2144
2212
  Metrics.postEvent({
2145
2213
  event: eventType.LOBBY_EXITED,
2146
- meeting: this
2214
+ meeting: this,
2147
2215
  });
2148
2216
  }
2149
2217
  });
2150
2218
 
2151
2219
  // @ts-ignore - check if MEDIA_INACTIVITY exists
2152
2220
  this.locusInfo.on(LOCUSINFO.EVENTS.MEDIA_INACTIVITY, () => {
2153
- Metrics.sendBehavioralMetric(
2154
- BEHAVIORAL_METRICS.MEETING_MEDIA_INACTIVE,
2155
- {
2156
- correlation_id: this.correlationId,
2157
- locus_id: this.locusId
2158
- }
2159
- );
2221
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_MEDIA_INACTIVE, {
2222
+ correlation_id: this.correlationId,
2223
+ locus_id: this.locusId,
2224
+ });
2160
2225
  this.reconnect();
2161
2226
  });
2162
2227
 
@@ -2174,8 +2239,8 @@ export default class Meeting extends StatelessWebexPlugin {
2174
2239
  sendShare: this.mediaProperties.mediaDirection?.sendShare,
2175
2240
  receiveAudio: this.mediaProperties.mediaDirection?.receiveAudio,
2176
2241
  receiveVideo: this.mediaProperties.mediaDirection?.receiveVideo,
2177
- receiveShare: this.mediaProperties.mediaDirection?.receiveShare
2178
- }
2242
+ receiveShare: this.mediaProperties.mediaDirection?.receiveShare,
2243
+ },
2179
2244
  });
2180
2245
  }
2181
2246
  });
@@ -2185,11 +2250,11 @@ export default class Meeting extends StatelessWebexPlugin {
2185
2250
  this,
2186
2251
  {
2187
2252
  file: 'meeting/index',
2188
- function: 'setUpLocusInfoSelfListener'
2253
+ function: 'setUpLocusInfoSelfListener',
2189
2254
  },
2190
2255
  EVENT_TRIGGERS.MEETING_SELF_CANNOT_VIEW_PARTICIPANT_LIST,
2191
2256
  {
2192
- payload
2257
+ payload,
2193
2258
  }
2194
2259
  );
2195
2260
  });
@@ -2199,11 +2264,11 @@ export default class Meeting extends StatelessWebexPlugin {
2199
2264
  this,
2200
2265
  {
2201
2266
  file: 'meeting/index',
2202
- function: 'setUpLocusInfoSelfListener'
2267
+ function: 'setUpLocusInfoSelfListener',
2203
2268
  },
2204
2269
  EVENT_TRIGGERS.MEETING_SELF_IS_SHARING_BLOCKED,
2205
2270
  {
2206
- payload
2271
+ payload,
2207
2272
  }
2208
2273
  );
2209
2274
  });
@@ -2220,12 +2285,18 @@ export default class Meeting extends StatelessWebexPlugin {
2220
2285
  this.meetingFiniteStateMachine.remote(payload);
2221
2286
 
2222
2287
  if (payload.remoteDeclined) {
2223
- this.leave({reason: payload.reason}).then(() => {
2224
- LoggerProxy.logger.info('Meeting:index#setUpLocusInfoMeetingListener --> REMOTE_RESPONSE. Attempting to leave meeting.');
2225
- }).catch((error) => {
2226
- // @ts-ignore
2227
- LoggerProxy.logger.error(`Meeting:index#setUpLocusInfoMeetingListener --> REMOTE_RESPONSE. Issue with leave for meeting, meeting still in collection: ${this.meeting}, error: ${error}`);
2228
- });
2288
+ this.leave({reason: payload.reason})
2289
+ .then(() => {
2290
+ LoggerProxy.logger.info(
2291
+ 'Meeting:index#setUpLocusInfoMeetingListener --> REMOTE_RESPONSE. Attempting to leave meeting.'
2292
+ );
2293
+ })
2294
+ .catch((error) => {
2295
+ // @ts-ignore
2296
+ LoggerProxy.logger.error(
2297
+ `Meeting:index#setUpLocusInfoMeetingListener --> REMOTE_RESPONSE. Issue with leave for meeting, meeting still in collection: ${this.meeting}, error: ${error}`
2298
+ );
2299
+ });
2229
2300
  }
2230
2301
  });
2231
2302
  this.locusInfo.on(EVENTS.DESTROY_MEETING, (payload) => {
@@ -2249,27 +2320,35 @@ export default class Meeting extends StatelessWebexPlugin {
2249
2320
  if (payload.shouldLeave) {
2250
2321
  // TODO: We should do cleaning of meeting object if the shouldLeave: false because there might be meeting object which we are not cleaning
2251
2322
 
2252
- this.leave({reason: payload.reason}).then(() => {
2253
- LoggerProxy.logger.warn('Meeting:index#setUpLocusInfoMeetingListener --> DESTROY_MEETING. The meeting has been left, but has not been destroyed, you should see a later event for leave.');
2254
- }).catch((error) => {
2255
- // @ts-ignore
2256
- LoggerProxy.logger.error(`Meeting:index#setUpLocusInfoMeetingListener --> DESTROY_MEETING. Issue with leave for meeting, meeting still in collection: ${this.meeting}, error: ${error}`);
2257
- });
2258
- }
2259
- else {
2260
- LoggerProxy.logger.info('Meeting:index#setUpLocusInfoMeetingListener --> MEETING_REMOVED_REASON', payload.reason);
2323
+ this.leave({reason: payload.reason})
2324
+ .then(() => {
2325
+ LoggerProxy.logger.warn(
2326
+ 'Meeting:index#setUpLocusInfoMeetingListener --> DESTROY_MEETING. The meeting has been left, but has not been destroyed, you should see a later event for leave.'
2327
+ );
2328
+ })
2329
+ .catch((error) => {
2330
+ // @ts-ignore
2331
+ LoggerProxy.logger.error(
2332
+ `Meeting:index#setUpLocusInfoMeetingListener --> DESTROY_MEETING. Issue with leave for meeting, meeting still in collection: ${this.meeting}, error: ${error}`
2333
+ );
2334
+ });
2335
+ } else {
2336
+ LoggerProxy.logger.info(
2337
+ 'Meeting:index#setUpLocusInfoMeetingListener --> MEETING_REMOVED_REASON',
2338
+ payload.reason
2339
+ );
2261
2340
 
2262
2341
  MeetingUtil.cleanUp(this);
2263
2342
  Trigger.trigger(
2264
2343
  this,
2265
2344
  {
2266
2345
  file: 'meeting/index',
2267
- function: 'setUpLocusInfoMeetingListener'
2346
+ function: 'setUpLocusInfoMeetingListener',
2268
2347
  },
2269
2348
  EVENTS.DESTROY_MEETING,
2270
2349
  {
2271
2350
  reason: payload.reason,
2272
- meetingId: this.id
2351
+ meetingId: this.id,
2273
2352
  }
2274
2353
  );
2275
2354
  }
@@ -2312,7 +2391,7 @@ export default class Meeting extends StatelessWebexPlugin {
2312
2391
  email: string;
2313
2392
  phoneNumber: string;
2314
2393
  },
2315
- alertIfActive: boolean = true
2394
+ alertIfActive = true
2316
2395
  ) {
2317
2396
  return this.members.addMember(invitee, alertIfActive);
2318
2397
  }
@@ -2325,7 +2404,7 @@ export default class Meeting extends StatelessWebexPlugin {
2325
2404
  * @public
2326
2405
  * @memberof Meeting
2327
2406
  */
2328
- public cancelPhoneInvite(invitee: { phoneNumber: string }) {
2407
+ public cancelPhoneInvite(invitee: {phoneNumber: string}) {
2329
2408
  return this.members.cancelPhoneInvite(invitee);
2330
2409
  }
2331
2410
 
@@ -2359,7 +2438,7 @@ export default class Meeting extends StatelessWebexPlugin {
2359
2438
  * @public
2360
2439
  * @memberof Meeting
2361
2440
  */
2362
- public mute(memberId: string, mute: boolean = true) {
2441
+ public mute(memberId: string, mute = true) {
2363
2442
  return this.members.muteMember(memberId, mute);
2364
2443
  }
2365
2444
 
@@ -2371,7 +2450,7 @@ export default class Meeting extends StatelessWebexPlugin {
2371
2450
  * @public
2372
2451
  * @memberof Meeting
2373
2452
  */
2374
- public transfer(memberId: string, moderator: boolean = true) {
2453
+ public transfer(memberId: string, moderator = true) {
2375
2454
  return this.members.transferHostToMember(memberId, moderator);
2376
2455
  }
2377
2456
 
@@ -2459,14 +2538,16 @@ export default class Meeting extends StatelessWebexPlugin {
2459
2538
  * @memberof Meeting
2460
2539
  */
2461
2540
  parseMeetingInfo(
2462
- meetingInfo: {
2463
- body: {
2464
- conversationUrl: string;
2465
- locusUrl: string;
2466
- sipUri: string;
2467
- owner: object;
2468
- };
2469
- } | any,
2541
+ meetingInfo:
2542
+ | {
2543
+ body: {
2544
+ conversationUrl: string;
2545
+ locusUrl: string;
2546
+ sipUri: string;
2547
+ owner: object;
2548
+ };
2549
+ }
2550
+ | any,
2470
2551
  destination: object | string | null = null
2471
2552
  ) {
2472
2553
  const webexMeetingInfo = meetingInfo?.body;
@@ -2479,17 +2560,32 @@ export default class Meeting extends StatelessWebexPlugin {
2479
2560
  }
2480
2561
 
2481
2562
  // MeetingInfo will be undefined for 1:1 calls
2482
- if (locusMeetingObject || (webexMeetingInfo && !(meetingInfo?.errors && meetingInfo?.errors.length > 0))) {
2483
- this.conversationUrl = locusMeetingObject?.conversationUrl || webexMeetingInfo?.conversationUrl || this.conversationUrl;
2563
+ if (
2564
+ locusMeetingObject ||
2565
+ (webexMeetingInfo && !(meetingInfo?.errors && meetingInfo?.errors.length > 0))
2566
+ ) {
2567
+ this.conversationUrl =
2568
+ locusMeetingObject?.conversationUrl ||
2569
+ webexMeetingInfo?.conversationUrl ||
2570
+ this.conversationUrl;
2484
2571
  this.locusUrl = locusMeetingObject?.url || webexMeetingInfo?.locusUrl || this.locusUrl;
2485
2572
  // @ts-ignore - config coming from registerPlugin
2486
- this.setSipUri(this.config.experimental.enableUnifiedMeetings ? locusMeetingObject?.info.sipUri || webexMeetingInfo?.sipUrl : locusMeetingObject?.info.sipUri || webexMeetingInfo?.sipMeetingUri || this.sipUri);
2573
+ this.setSipUri(
2574
+ this.config.experimental.enableUnifiedMeetings
2575
+ ? locusMeetingObject?.info.sipUri || webexMeetingInfo?.sipUrl
2576
+ : locusMeetingObject?.info.sipUri || webexMeetingInfo?.sipMeetingUri || this.sipUri
2577
+ );
2487
2578
  // @ts-ignore - config coming from registerPlugin
2488
2579
  if (this.config.experimental.enableUnifiedMeetings) {
2489
- this.meetingNumber = locusMeetingObject?.info.webExMeetingId || webexMeetingInfo?.meetingNumber;
2580
+ this.meetingNumber =
2581
+ locusMeetingObject?.info.webExMeetingId || webexMeetingInfo?.meetingNumber;
2490
2582
  this.meetingJoinUrl = webexMeetingInfo?.meetingJoinUrl;
2491
2583
  }
2492
- this.owner = locusMeetingObject?.info.owner || webexMeetingInfo?.owner || webexMeetingInfo?.hostId || this.owner;
2584
+ this.owner =
2585
+ locusMeetingObject?.info.owner ||
2586
+ webexMeetingInfo?.owner ||
2587
+ webexMeetingInfo?.hostId ||
2588
+ this.owner;
2493
2589
  this.permissionToken = webexMeetingInfo?.permissionToken;
2494
2590
  }
2495
2591
  }
@@ -2504,7 +2600,7 @@ export default class Meeting extends StatelessWebexPlugin {
2504
2600
  * @private
2505
2601
  * @memberof Meeting
2506
2602
  */
2507
- private parseLocus(locus: { url: string; participants: Array<any>; self: object }) {
2603
+ private parseLocus(locus: {url: string; participants: Array<any>; self: object}) {
2508
2604
  if (locus) {
2509
2605
  this.locusUrl = locus.url;
2510
2606
  // TODO: move this to parse participants module
@@ -2562,13 +2658,17 @@ export default class Meeting extends StatelessWebexPlugin {
2562
2658
  * @private
2563
2659
  * @memberof Meeting
2564
2660
  */
2565
- private setLocus(locus: {
2566
- mediaConnections: Array<any>;
2567
- locusUrl: string;
2568
- locusId: string;
2569
- mediaId: string;
2570
- host: object;
2571
- } | any) {
2661
+ private setLocus(
2662
+ locus:
2663
+ | {
2664
+ mediaConnections: Array<any>;
2665
+ locusUrl: string;
2666
+ locusId: string;
2667
+ mediaId: string;
2668
+ host: object;
2669
+ }
2670
+ | any
2671
+ ) {
2572
2672
  const mtgLocus: any = locus.locus || locus;
2573
2673
 
2574
2674
  // LocusInfo object saves the locus object
@@ -2602,13 +2702,16 @@ export default class Meeting extends StatelessWebexPlugin {
2602
2702
  // so we might need to either
2603
2703
  // A) wait until we have media flowing
2604
2704
  // B) trigger a second event when video is flowing
2605
- LoggerProxy.logger.log(`Meeting:index#setRemoteStream --> ontrack event received for peerConnection: ${event}`);
2705
+ LoggerProxy.logger.log(
2706
+ `Meeting:index#setRemoteStream --> ontrack event received for peerConnection: ${event}`
2707
+ );
2606
2708
 
2607
2709
  const MEDIA_ID = {
2608
2710
  AUDIO_TRACK: '0',
2609
2711
  VIDEO_TRACK: '1',
2610
- SHARE_TRACK: '2'
2712
+ SHARE_TRACK: '2',
2611
2713
  };
2714
+ // eslint-disable-next-line @typescript-eslint/no-shadow
2612
2715
  let eventType = null;
2613
2716
  const mediaTrack = event.track;
2614
2717
  let trackMediaID = null;
@@ -2617,31 +2720,22 @@ export default class Meeting extends StatelessWebexPlugin {
2617
2720
  // sdk tries to determine the transceive using the track id present
2618
2721
  if (event.transceiver && event.transceiver.mid) {
2619
2722
  trackMediaID = event.transceiver.mid;
2620
- }
2621
- else {
2723
+ } else {
2622
2724
  const {audioTransceiver, videoTransceiver, shareTransceiver} = event.target;
2623
2725
 
2624
2726
  // audio kind indicates its a audio stream
2625
2727
  if (mediaTrack.id === audioTransceiver.receiver.track.id) {
2626
2728
  trackMediaID = '0';
2627
- }
2628
- else
2629
- if (mediaTrack.id === videoTransceiver.receiver.track.id) {
2729
+ } else if (mediaTrack.id === videoTransceiver.receiver.track.id) {
2630
2730
  trackMediaID = '1';
2631
- }
2632
- else
2633
- if (mediaTrack.id === shareTransceiver.receiver.track.id) {
2731
+ } else if (mediaTrack.id === shareTransceiver.receiver.track.id) {
2634
2732
  trackMediaID = '2';
2635
- }
2636
- else {
2733
+ } else {
2637
2734
  trackMediaID = null;
2638
- Metrics.sendBehavioralMetric(
2639
- BEHAVIORAL_METRICS.MUTE_AUDIO_FAILURE,
2640
- {
2641
- correlation_id: this.correlationId,
2642
- locus_id: this.locusUrl.split('/').pop()
2643
- }
2644
- );
2735
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MUTE_AUDIO_FAILURE, {
2736
+ correlation_id: this.correlationId,
2737
+ locus_id: this.locusUrl.split('/').pop(),
2738
+ });
2645
2739
  }
2646
2740
  }
2647
2741
 
@@ -2674,12 +2768,12 @@ export default class Meeting extends StatelessWebexPlugin {
2674
2768
  this,
2675
2769
  {
2676
2770
  file: 'meeting/index',
2677
- function: 'setRemoteStream:pc.ontrack'
2771
+ function: 'setRemoteStream:pc.ontrack',
2678
2772
  },
2679
2773
  EVENT_TRIGGERS.MEDIA_READY,
2680
2774
  {
2681
2775
  type: eventType,
2682
- stream: MediaUtil.createMediaStream([mediaTrack])
2776
+ stream: MediaUtil.createMediaStream([mediaTrack]),
2683
2777
  }
2684
2778
  );
2685
2779
  }
@@ -2693,13 +2787,8 @@ export default class Meeting extends StatelessWebexPlugin {
2693
2787
  * @public
2694
2788
  * @memberof Meeting
2695
2789
  */
2696
- public uploadLogs(options: object = { file: 'meeting/index', function: 'uploadLogs' }) {
2697
- Trigger.trigger(
2698
- this,
2699
- options,
2700
- EVENTS.REQUEST_UPLOAD_LOGS,
2701
- this
2702
- );
2790
+ public uploadLogs(options: object = {file: 'meeting/index', function: 'uploadLogs'}) {
2791
+ Trigger.trigger(this, options, EVENTS.REQUEST_UPLOAD_LOGS, this);
2703
2792
  }
2704
2793
 
2705
2794
  /**
@@ -2711,7 +2800,9 @@ export default class Meeting extends StatelessWebexPlugin {
2711
2800
  * @deprecated after v1.89.3
2712
2801
  */
2713
2802
  public unsetRemoteStream() {
2714
- LoggerProxy.logger.warn('Meeting:index#unsetRemoteStream --> [DEPRECATION WARNING]: unsetRemoteStream has been deprecated after v1.89.3');
2803
+ LoggerProxy.logger.warn(
2804
+ 'Meeting:index#unsetRemoteStream --> [DEPRECATION WARNING]: unsetRemoteStream has been deprecated after v1.89.3'
2805
+ );
2715
2806
  this.mediaProperties.unsetRemoteMedia();
2716
2807
  }
2717
2808
 
@@ -2732,7 +2823,9 @@ export default class Meeting extends StatelessWebexPlugin {
2732
2823
  * @deprecated after v1.89.3
2733
2824
  */
2734
2825
  public closeRemoteStream() {
2735
- LoggerProxy.logger.warn('Meeting:index#closeRemoteStream --> [DEPRECATION WARNING]: closeRemoteStream has been deprecated after v1.89.3');
2826
+ LoggerProxy.logger.warn(
2827
+ 'Meeting:index#closeRemoteStream --> [DEPRECATION WARNING]: closeRemoteStream has been deprecated after v1.89.3'
2828
+ );
2736
2829
  this.closeRemoteTracks();
2737
2830
  }
2738
2831
 
@@ -2743,11 +2836,7 @@ export default class Meeting extends StatelessWebexPlugin {
2743
2836
  * @memberof Meeting
2744
2837
  */
2745
2838
  closeRemoteTracks() {
2746
- const {
2747
- remoteAudioTrack,
2748
- remoteVideoTrack,
2749
- remoteShare
2750
- } = this.mediaProperties;
2839
+ const {remoteAudioTrack, remoteVideoTrack, remoteShare} = this.mediaProperties;
2751
2840
 
2752
2841
  /**
2753
2842
  * Triggers an event to the developer
@@ -2755,16 +2844,17 @@ export default class Meeting extends StatelessWebexPlugin {
2755
2844
  * @returns {void}
2756
2845
  * @inner
2757
2846
  */
2847
+ // eslint-disable-next-line @typescript-eslint/no-shadow
2758
2848
  const triggerMediaStoppedEvent = (mediaType: string) => {
2759
2849
  Trigger.trigger(
2760
2850
  this,
2761
2851
  {
2762
2852
  file: 'meeting/index',
2763
- function: 'closeRemoteTracks'
2853
+ function: 'closeRemoteTracks',
2764
2854
  },
2765
2855
  EVENT_TRIGGERS.MEDIA_STOPPED,
2766
2856
  {
2767
- type: mediaType
2857
+ type: mediaType,
2768
2858
  }
2769
2859
  );
2770
2860
  };
@@ -2778,24 +2868,24 @@ export default class Meeting extends StatelessWebexPlugin {
2778
2868
  */
2779
2869
  // eslint-disable-next-line arrow-body-style
2780
2870
  const stopTrack = (track: MediaStreamTrack, type: string) => {
2781
- return Media.stopTracks(track)
2782
- .then(() => {
2783
- const isTrackStopped = track && track.readyState === ENDED;
2784
- const isWrongReadyState = track && !isTrackStopped;
2871
+ return Media.stopTracks(track).then(() => {
2872
+ const isTrackStopped = track && track.readyState === ENDED;
2873
+ const isWrongReadyState = track && !isTrackStopped;
2785
2874
 
2786
- if (isTrackStopped) {
2787
- triggerMediaStoppedEvent(type);
2788
- }
2789
- else if (isWrongReadyState) {
2790
- LoggerProxy.logger.warn(`Meeting:index#closeRemoteTracks --> Error: MediaStreamTrack.readyState is ${track.readyState} for ${type}`);
2791
- }
2792
- });
2875
+ if (isTrackStopped) {
2876
+ triggerMediaStoppedEvent(type);
2877
+ } else if (isWrongReadyState) {
2878
+ LoggerProxy.logger.warn(
2879
+ `Meeting:index#closeRemoteTracks --> Error: MediaStreamTrack.readyState is ${track.readyState} for ${type}`
2880
+ );
2881
+ }
2882
+ });
2793
2883
  };
2794
2884
 
2795
2885
  return Promise.all([
2796
2886
  stopTrack(remoteAudioTrack, EVENT_TYPES.REMOTE_AUDIO),
2797
2887
  stopTrack(remoteVideoTrack, EVENT_TYPES.REMOTE_VIDEO),
2798
- stopTrack(remoteShare, EVENT_TYPES.REMOTE_SHARE)
2888
+ stopTrack(remoteShare, EVENT_TYPES.REMOTE_SHARE),
2799
2889
  ]);
2800
2890
  }
2801
2891
 
@@ -2810,12 +2900,15 @@ export default class Meeting extends StatelessWebexPlugin {
2810
2900
  this,
2811
2901
  {
2812
2902
  file: 'meeting/index',
2813
- function: 'setLocalTracks'
2903
+ function: 'setLocalTracks',
2814
2904
  },
2815
2905
  EVENT_TRIGGERS.MEDIA_READY,
2816
2906
  {
2817
2907
  type: EVENT_TYPES.LOCAL,
2818
- stream: MediaUtil.createMediaStream([this.mediaProperties.audioTrack, this.mediaProperties.videoTrack])
2908
+ stream: MediaUtil.createMediaStream([
2909
+ this.mediaProperties.audioTrack,
2910
+ this.mediaProperties.videoTrack,
2911
+ ]),
2819
2912
  }
2820
2913
  );
2821
2914
  }
@@ -2828,16 +2921,19 @@ export default class Meeting extends StatelessWebexPlugin {
2828
2921
  * @private
2829
2922
  * @memberof Meeting
2830
2923
  */
2831
- private setLocalAudioTrack(audioTrack: MediaStreamTrack, emitEvent: boolean = true) {
2924
+ private setLocalAudioTrack(audioTrack: MediaStreamTrack, emitEvent = true) {
2832
2925
  if (audioTrack) {
2833
2926
  const settings = audioTrack.getSettings();
2834
2927
 
2835
2928
  this.mediaProperties.setMediaSettings('audio', {
2836
2929
  echoCancellation: settings.echoCancellation,
2837
- noiseSuppression: settings.noiseSuppression
2930
+ noiseSuppression: settings.noiseSuppression,
2838
2931
  });
2839
2932
 
2840
- LoggerProxy.logger.log('Meeting:index#setLocalAudioTrack --> Audio settings.', JSON.stringify(this.mediaProperties.mediaSettings.audio));
2933
+ LoggerProxy.logger.log(
2934
+ 'Meeting:index#setLocalAudioTrack --> Audio settings.',
2935
+ JSON.stringify(this.mediaProperties.mediaSettings.audio)
2936
+ );
2841
2937
  this.mediaProperties.setLocalAudioTrack(audioTrack);
2842
2938
  if (this.audio) this.audio.applyClientStateLocally(this);
2843
2939
  }
@@ -2855,16 +2951,15 @@ export default class Meeting extends StatelessWebexPlugin {
2855
2951
  * @private
2856
2952
  * @memberof Meeting
2857
2953
  */
2858
- private setLocalVideoTrack(videoTrack: MediaStreamTrack, emitEvent: boolean = true) {
2954
+ private setLocalVideoTrack(videoTrack: MediaStreamTrack, emitEvent = true) {
2859
2955
  if (videoTrack) {
2860
- const {
2861
- aspectRatio, frameRate, height, width, deviceId
2862
- } = videoTrack.getSettings();
2956
+ const {aspectRatio, frameRate, height, width, deviceId} = videoTrack.getSettings();
2863
2957
 
2864
2958
  const {localQualityLevel} = this.mediaProperties;
2865
2959
 
2866
2960
  if (Number(localQualityLevel.slice(0, -1)) > height) {
2867
- LoggerProxy.logger.warn(`Meeting:index#setLocalVideoTrack --> Local video quality of ${localQualityLevel} not supported,
2961
+ LoggerProxy.logger
2962
+ .warn(`Meeting:index#setLocalVideoTrack --> Local video quality of ${localQualityLevel} not supported,
2868
2963
  downscaling to highest possible resolution of ${height}p`);
2869
2964
 
2870
2965
  this.mediaProperties.setLocalQualityLevel(`${height}p`);
@@ -2874,13 +2969,19 @@ export default class Meeting extends StatelessWebexPlugin {
2874
2969
  if (this.video) this.video.applyClientStateLocally(this);
2875
2970
 
2876
2971
  this.mediaProperties.setMediaSettings('video', {
2877
- aspectRatio, frameRate, height, width
2972
+ aspectRatio,
2973
+ frameRate,
2974
+ height,
2975
+ width,
2878
2976
  });
2879
2977
  // store and save the selected video input device
2880
2978
  if (deviceId) {
2881
2979
  this.mediaProperties.setVideoDeviceId(deviceId);
2882
2980
  }
2883
- LoggerProxy.logger.log('Meeting:index#setLocalVideoTrack --> Video settings.', JSON.stringify(this.mediaProperties.mediaSettings.video));
2981
+ LoggerProxy.logger.log(
2982
+ 'Meeting:index#setLocalVideoTrack --> Video settings.',
2983
+ JSON.stringify(this.mediaProperties.mediaSettings.video)
2984
+ );
2884
2985
  }
2885
2986
 
2886
2987
  if (emitEvent) {
@@ -2928,9 +3029,12 @@ export default class Meeting extends StatelessWebexPlugin {
2928
3029
  height: settings.height,
2929
3030
  width: settings.width,
2930
3031
  displaySurface: settings.displaySurface,
2931
- cursor: settings.cursor
3032
+ cursor: settings.cursor,
2932
3033
  });
2933
- LoggerProxy.logger.log('Meeting:index#setLocalShareTrack --> Screen settings.', JSON.stringify(this.mediaProperties.mediaSettings.screen));
3034
+ LoggerProxy.logger.log(
3035
+ 'Meeting:index#setLocalShareTrack --> Screen settings.',
3036
+ JSON.stringify(this.mediaProperties.mediaSettings.screen)
3037
+ );
2934
3038
  }
2935
3039
 
2936
3040
  contentTracks.onended = () => this.handleShareTrackEnded(localShare);
@@ -2939,12 +3043,12 @@ export default class Meeting extends StatelessWebexPlugin {
2939
3043
  this,
2940
3044
  {
2941
3045
  file: 'meeting/index',
2942
- function: 'setLocalShareTrack'
3046
+ function: 'setLocalShareTrack',
2943
3047
  },
2944
3048
  EVENT_TRIGGERS.MEDIA_READY,
2945
3049
  {
2946
3050
  type: EVENT_TYPES.LOCAL_SHARE,
2947
- stream: localShare
3051
+ stream: localShare,
2948
3052
  }
2949
3053
  );
2950
3054
  }
@@ -2972,15 +3076,17 @@ export default class Meeting extends StatelessWebexPlugin {
2972
3076
  this,
2973
3077
  {
2974
3078
  file: 'meeting/index',
2975
- function: 'closeLocalStream'
3079
+ function: 'closeLocalStream',
2976
3080
  },
2977
- EVENT_TRIGGERS.MEDIA_STOPPED, {
2978
- type: EVENT_TYPES.LOCAL
3081
+ EVENT_TRIGGERS.MEDIA_STOPPED,
3082
+ {
3083
+ type: EVENT_TYPES.LOCAL,
2979
3084
  }
2980
3085
  );
2981
- }
2982
- else if (audioTrack || videoTrack) {
2983
- LoggerProxy.logger.warn('Meeting:index#closeLocalStream --> Warning: track might already been ended or unavaliable.');
3086
+ } else if (audioTrack || videoTrack) {
3087
+ LoggerProxy.logger.warn(
3088
+ 'Meeting:index#closeLocalStream --> Warning: track might already been ended or unavaliable.'
3089
+ );
2984
3090
  }
2985
3091
  });
2986
3092
  }
@@ -3001,16 +3107,18 @@ export default class Meeting extends StatelessWebexPlugin {
3001
3107
  this,
3002
3108
  {
3003
3109
  file: 'meeting/index',
3004
- function: 'closeLocalShare'
3110
+ function: 'closeLocalShare',
3005
3111
  },
3006
- EVENT_TRIGGERS.MEDIA_STOPPED, {
3007
- type: EVENT_TYPES.LOCAL_SHARE
3112
+ EVENT_TRIGGERS.MEDIA_STOPPED,
3113
+ {
3114
+ type: EVENT_TYPES.LOCAL_SHARE,
3008
3115
  }
3009
3116
  );
3010
- }
3011
- else if (track) {
3117
+ } else if (track) {
3012
3118
  // Track exists but with wrong readyState
3013
- LoggerProxy.logger.warn(`Meeting:index#closeLocalShare --> Error: MediaStreamTrack.readyState is ${track.readyState} for localShare`);
3119
+ LoggerProxy.logger.warn(
3120
+ `Meeting:index#closeLocalShare --> Error: MediaStreamTrack.readyState is ${track.readyState} for localShare`
3121
+ );
3014
3122
  }
3015
3123
  });
3016
3124
  }
@@ -3052,14 +3160,11 @@ export default class Meeting extends StatelessWebexPlugin {
3052
3160
  if (!this.hasWebsocketConnected) {
3053
3161
  Metrics.postEvent({
3054
3162
  event: eventType.MERCURY_CONNECTION_RESTORED,
3055
- meeting: this
3163
+ meeting: this,
3164
+ });
3165
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MERCURY_CONNECTION_RESTORED, {
3166
+ correlation_id: this.correlationId,
3056
3167
  });
3057
- Metrics.sendBehavioralMetric(
3058
- BEHAVIORAL_METRICS.MERCURY_CONNECTION_RESTORED,
3059
- {
3060
- correlation_id: this.correlationId
3061
- }
3062
- );
3063
3168
  }
3064
3169
  this.hasWebsocketConnected = true;
3065
3170
  });
@@ -3069,14 +3174,11 @@ export default class Meeting extends StatelessWebexPlugin {
3069
3174
  LoggerProxy.logger.error('Meeting:index#setMercuryListener --> Web socket offline');
3070
3175
  Metrics.postEvent({
3071
3176
  event: eventType.MERCURY_CONNECTION_LOST,
3072
- meeting: this
3177
+ meeting: this,
3178
+ });
3179
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MERCURY_CONNECTION_FAILURE, {
3180
+ correlation_id: this.correlationId,
3073
3181
  });
3074
- Metrics.sendBehavioralMetric(
3075
- BEHAVIORAL_METRICS.MERCURY_CONNECTION_FAILURE,
3076
- {
3077
- correlation_id: this.correlationId
3078
- }
3079
- );
3080
3182
  });
3081
3183
  }
3082
3184
 
@@ -3143,32 +3245,33 @@ export default class Meeting extends StatelessWebexPlugin {
3143
3245
  const LOG_HEADER = 'Meeting:index#muteAudio -->';
3144
3246
 
3145
3247
  // First, stop sending the local audio media
3146
- return logRequest(this.audio.handleClientRequest(this, true)
3147
- .then(() => {
3148
- MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
3149
- Metrics.postEvent({
3150
- event: eventType.MUTED,
3151
- meeting: this,
3152
- data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.AUDIO}
3153
- });
3154
- }).catch((error) => {
3155
- Metrics.sendBehavioralMetric(
3156
- BEHAVIORAL_METRICS.MUTE_AUDIO_FAILURE,
3157
- {
3248
+ return logRequest(
3249
+ this.audio
3250
+ .handleClientRequest(this, true)
3251
+ .then(() => {
3252
+ MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
3253
+ Metrics.postEvent({
3254
+ event: eventType.MUTED,
3255
+ meeting: this,
3256
+ data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.AUDIO},
3257
+ });
3258
+ })
3259
+ .catch((error) => {
3260
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MUTE_AUDIO_FAILURE, {
3158
3261
  correlation_id: this.correlationId,
3159
3262
  locus_id: this.locusUrl.split('/').pop(),
3160
3263
  reason: error.message,
3161
- stack: error.stack
3162
- }
3163
- );
3264
+ stack: error.stack,
3265
+ });
3164
3266
 
3165
- throw error;
3166
- }),
3167
- {
3168
- header: `${LOG_HEADER} muting audio`,
3169
- success: `${LOG_HEADER} muted audio successfully`,
3170
- failure: `${LOG_HEADER} muting audio failed, `
3171
- });
3267
+ throw error;
3268
+ }),
3269
+ {
3270
+ header: `${LOG_HEADER} muting audio`,
3271
+ success: `${LOG_HEADER} muted audio successfully`,
3272
+ failure: `${LOG_HEADER} muting audio failed, `,
3273
+ }
3274
+ );
3172
3275
  }
3173
3276
 
3174
3277
  /**
@@ -3195,33 +3298,34 @@ export default class Meeting extends StatelessWebexPlugin {
3195
3298
  const LOG_HEADER = 'Meeting:index#unmuteAudio -->';
3196
3299
 
3197
3300
  // First, send the control to unmute the participant on the server
3198
- return logRequest(this.audio.handleClientRequest(this, false)
3199
- .then(() => {
3200
- MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
3201
- Metrics.postEvent({
3202
- event: eventType.UNMUTED,
3203
- meeting: this,
3204
- data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.AUDIO}
3205
- });
3206
- }).catch((error) => {
3207
- Metrics.sendBehavioralMetric(
3208
- BEHAVIORAL_METRICS.UNMUTE_AUDIO_FAILURE,
3209
- {
3301
+ return logRequest(
3302
+ this.audio
3303
+ .handleClientRequest(this, false)
3304
+ .then(() => {
3305
+ MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
3306
+ Metrics.postEvent({
3307
+ event: eventType.UNMUTED,
3308
+ meeting: this,
3309
+ data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.AUDIO},
3310
+ });
3311
+ })
3312
+ .catch((error) => {
3313
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UNMUTE_AUDIO_FAILURE, {
3210
3314
  correlation_id: this.correlationId,
3211
3315
  locus_id: this.locusUrl.split('/').pop(),
3212
3316
  reason: error.message,
3213
- stack: error.stack
3214
- }
3215
- );
3216
-
3217
- throw error;
3218
- }),
3219
- {
3220
- header: `${LOG_HEADER} unmuting audio`,
3221
- success: `${LOG_HEADER} unmuted audio successfully`,
3222
- failure: `${LOG_HEADER} unmuting audio failed, `
3223
- });
3224
- }
3317
+ stack: error.stack,
3318
+ });
3319
+
3320
+ throw error;
3321
+ }),
3322
+ {
3323
+ header: `${LOG_HEADER} unmuting audio`,
3324
+ success: `${LOG_HEADER} unmuted audio successfully`,
3325
+ failure: `${LOG_HEADER} unmuting audio failed, `,
3326
+ }
3327
+ );
3328
+ }
3225
3329
 
3226
3330
  /**
3227
3331
  * Mute the video for a meeting
@@ -3246,32 +3350,33 @@ export default class Meeting extends StatelessWebexPlugin {
3246
3350
 
3247
3351
  const LOG_HEADER = 'Meeting:index#muteVideo -->';
3248
3352
 
3249
- return logRequest(this.video.handleClientRequest(this, true)
3250
- .then(() => {
3251
- MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
3252
- Metrics.postEvent({
3253
- event: eventType.MUTED,
3254
- meeting: this,
3255
- data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.VIDEO}
3256
- });
3257
- }).catch((error) => {
3258
- Metrics.sendBehavioralMetric(
3259
- BEHAVIORAL_METRICS.MUTE_VIDEO_FAILURE,
3260
- {
3353
+ return logRequest(
3354
+ this.video
3355
+ .handleClientRequest(this, true)
3356
+ .then(() => {
3357
+ MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
3358
+ Metrics.postEvent({
3359
+ event: eventType.MUTED,
3360
+ meeting: this,
3361
+ data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.VIDEO},
3362
+ });
3363
+ })
3364
+ .catch((error) => {
3365
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MUTE_VIDEO_FAILURE, {
3261
3366
  correlation_id: this.correlationId,
3262
3367
  locus_id: this.locusUrl.split('/').pop(),
3263
3368
  reason: error.message,
3264
- stack: error.stack
3265
- }
3266
- );
3369
+ stack: error.stack,
3370
+ });
3267
3371
 
3268
- throw error;
3269
- }),
3270
- {
3271
- header: `${LOG_HEADER} muting video`,
3272
- success: `${LOG_HEADER} muted video successfully`,
3273
- failure: `${LOG_HEADER} muting video failed, `
3274
- });
3372
+ throw error;
3373
+ }),
3374
+ {
3375
+ header: `${LOG_HEADER} muting video`,
3376
+ success: `${LOG_HEADER} muted video successfully`,
3377
+ failure: `${LOG_HEADER} muting video failed, `,
3378
+ }
3379
+ );
3275
3380
  }
3276
3381
 
3277
3382
  /**
@@ -3297,32 +3402,33 @@ export default class Meeting extends StatelessWebexPlugin {
3297
3402
 
3298
3403
  const LOG_HEADER = 'Meeting:index#unmuteVideo -->';
3299
3404
 
3300
- return logRequest(this.video.handleClientRequest(this, false)
3301
- .then(() => {
3302
- MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
3303
- Metrics.postEvent({
3304
- event: eventType.UNMUTED,
3305
- meeting: this,
3306
- data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.VIDEO}
3307
- });
3308
- }).catch((error) => {
3309
- Metrics.sendBehavioralMetric(
3310
- BEHAVIORAL_METRICS.UNMUTE_VIDEO_FAILURE,
3311
- {
3405
+ return logRequest(
3406
+ this.video
3407
+ .handleClientRequest(this, false)
3408
+ .then(() => {
3409
+ MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
3410
+ Metrics.postEvent({
3411
+ event: eventType.UNMUTED,
3412
+ meeting: this,
3413
+ data: {trigger: trigger.USER_INTERACTION, mediaType: mediaType.VIDEO},
3414
+ });
3415
+ })
3416
+ .catch((error) => {
3417
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UNMUTE_VIDEO_FAILURE, {
3312
3418
  correlation_id: this.correlationId,
3313
3419
  locus_id: this.locusUrl.split('/').pop(),
3314
3420
  reason: error.message,
3315
- stack: error.stack
3316
- }
3317
- );
3421
+ stack: error.stack,
3422
+ });
3318
3423
 
3319
- throw error;
3320
- }),
3321
- {
3322
- header: `${LOG_HEADER} unmuting video`,
3323
- success: `${LOG_HEADER} unmuted video successfully`,
3324
- failure: `${LOG_HEADER} unmuting video failed, `
3325
- });
3424
+ throw error;
3425
+ }),
3426
+ {
3427
+ header: `${LOG_HEADER} unmuting video`,
3428
+ success: `${LOG_HEADER} unmuted video successfully`,
3429
+ failure: `${LOG_HEADER} unmuting video failed, `,
3430
+ }
3431
+ );
3326
3432
  }
3327
3433
 
3328
3434
  /**
@@ -3366,12 +3472,14 @@ export default class Meeting extends StatelessWebexPlugin {
3366
3472
  this.addMedia({
3367
3473
  mediaSettings,
3368
3474
  localShare,
3369
- localStream
3475
+ localStream,
3370
3476
  }).then((mediaResponse) => ({
3371
3477
  join: joinResponse,
3372
3478
  media: mediaResponse,
3373
- local: [localStream, localShare]
3374
- }))))
3479
+ local: [localStream, localShare],
3480
+ }))
3481
+ )
3482
+ )
3375
3483
  .catch((error) => {
3376
3484
  LoggerProxy.logger.error('Meeting:index#joinWithMedia --> ', error);
3377
3485
 
@@ -3381,10 +3489,10 @@ export default class Meeting extends StatelessWebexPlugin {
3381
3489
  correlation_id: this.correlationId,
3382
3490
  locus_id: this.locusUrl.split('/').pop(),
3383
3491
  reason: error.message,
3384
- stack: error.stack
3492
+ stack: error.stack,
3385
3493
  },
3386
3494
  {
3387
- type: error.name
3495
+ type: error.name,
3388
3496
  }
3389
3497
  );
3390
3498
 
@@ -3401,28 +3509,34 @@ export default class Meeting extends StatelessWebexPlugin {
3401
3509
  * @memberof Meeting
3402
3510
  */
3403
3511
  public reconnect(options?: object) {
3404
- LoggerProxy.logger.log(`Meeting:index#reconnect --> attempting to reconnect meeting ${this.id}`);
3512
+ LoggerProxy.logger.log(
3513
+ `Meeting:index#reconnect --> attempting to reconnect meeting ${this.id}`
3514
+ );
3405
3515
 
3406
3516
  if (!this.reconnectionManager || !this.reconnectionManager.reconnect) {
3407
- return Promise.reject(new ParameterError('Cannot reconnect, ReconnectionManager must first be defined.'));
3517
+ return Promise.reject(
3518
+ new ParameterError('Cannot reconnect, ReconnectionManager must first be defined.')
3519
+ );
3408
3520
  }
3409
3521
 
3410
3522
  // @ts-ignore - currentMediaStatus coming from SelfUtil
3411
3523
  if (!MeetingUtil.isMediaEstablished(this.currentMediaStatus)) {
3412
- return Promise.reject(new ParameterError('Cannot reconnect, Media has not established to reconnect'));
3524
+ return Promise.reject(
3525
+ new ParameterError('Cannot reconnect, Media has not established to reconnect')
3526
+ );
3413
3527
  }
3414
3528
 
3415
3529
  try {
3416
3530
  LoggerProxy.logger.info('Meeting:index#reconnect --> Validating reconnect ability.');
3417
3531
  // @ts-ignore
3418
3532
  this.reconnectionManager.validate();
3419
- }
3420
- catch (error) {
3533
+ } catch (error) {
3421
3534
  // Unable to reconnect this call
3422
3535
  if (error instanceof ReconnectInProgress) {
3423
- LoggerProxy.logger.info('Meeting:index#reconnect --> Unable to reconnect, reconnection in progress.');
3424
- }
3425
- else {
3536
+ LoggerProxy.logger.info(
3537
+ 'Meeting:index#reconnect --> Unable to reconnect, reconnection in progress.'
3538
+ );
3539
+ } else {
3426
3540
  LoggerProxy.logger.log('Meeting:index#reconnect --> Unable to reconnect.', error);
3427
3541
  }
3428
3542
 
@@ -3433,7 +3547,7 @@ export default class Meeting extends StatelessWebexPlugin {
3433
3547
  this,
3434
3548
  {
3435
3549
  file: 'meeting/index',
3436
- function: 'reconnect'
3550
+ function: 'reconnect',
3437
3551
  },
3438
3552
  EVENT_TRIGGERS.MEETING_RECONNECTION_STARTING
3439
3553
  );
@@ -3445,7 +3559,7 @@ export default class Meeting extends StatelessWebexPlugin {
3445
3559
  this,
3446
3560
  {
3447
3561
  file: 'meeting/index',
3448
- function: 'reconnect'
3562
+ function: 'reconnect',
3449
3563
  },
3450
3564
  EVENT_TRIGGERS.MEETING_RECONNECTION_SUCCESS
3451
3565
  );
@@ -3456,29 +3570,26 @@ export default class Meeting extends StatelessWebexPlugin {
3456
3570
  this,
3457
3571
  {
3458
3572
  file: 'meeting/index',
3459
- function: 'reconnect'
3573
+ function: 'reconnect',
3460
3574
  },
3461
3575
  EVENT_TRIGGERS.MEETING_RECONNECTION_FAILURE,
3462
3576
  {
3463
- error: new ReconnectionError('Reconnection failure event', error)
3577
+ error: new ReconnectionError('Reconnection failure event', error),
3464
3578
  }
3465
3579
  );
3466
3580
 
3467
3581
  LoggerProxy.logger.error('Meeting:index#reconnect --> Meeting reconnect failed', error);
3468
3582
 
3469
- Metrics.sendBehavioralMetric(
3470
- BEHAVIORAL_METRICS.MEETING_RECONNECT_FAILURE,
3471
- {
3472
- correlation_id: this.correlationId,
3473
- locus_id: this.locusUrl.split('/').pop(),
3474
- reason: error.message,
3475
- stack: error.stack
3476
- }
3477
- );
3583
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_RECONNECT_FAILURE, {
3584
+ correlation_id: this.correlationId,
3585
+ locus_id: this.locusUrl.split('/').pop(),
3586
+ reason: error.message,
3587
+ stack: error.stack,
3588
+ });
3478
3589
 
3479
3590
  this.uploadLogs({
3480
3591
  file: 'meeting/index',
3481
- function: 'reconnect'
3592
+ function: 'reconnect',
3482
3593
  });
3483
3594
 
3484
3595
  return Promise.reject(new ReconnectionError('Reconnection failure event', error));
@@ -3532,14 +3643,11 @@ export default class Meeting extends StatelessWebexPlugin {
3532
3643
 
3533
3644
  this.triggerStopReceivingTranscriptionEvent();
3534
3645
 
3535
- Metrics.sendBehavioralMetric(
3536
- BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_FAILURE,
3537
- {
3538
- correlation_id: this.correlationId,
3539
- reason: 'unexpected error: transcription LLM web socket connection error had occured.',
3540
- event
3541
- }
3542
- );
3646
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_FAILURE, {
3647
+ correlation_id: this.correlationId,
3648
+ reason: 'unexpected error: transcription LLM web socket connection error had occured.',
3649
+ event,
3650
+ });
3543
3651
  });
3544
3652
  }
3545
3653
 
@@ -3557,10 +3665,12 @@ export default class Meeting extends StatelessWebexPlugin {
3557
3665
  try {
3558
3666
  const {datachannelUrl} = this.locusInfo.info;
3559
3667
  // @ts-ignore - fix type
3560
- const {body: {webSocketUrl}} = await this.request({
3668
+ const {
3669
+ body: {webSocketUrl},
3670
+ } = await this.request({
3561
3671
  method: HTTP_VERBS.POST,
3562
3672
  uri: datachannelUrl,
3563
- body: {deviceUrl: this.deviceUrl}
3673
+ body: {deviceUrl: this.deviceUrl},
3564
3674
  });
3565
3675
 
3566
3676
  LoggerProxy.logger.info(
@@ -3572,7 +3682,7 @@ export default class Meeting extends StatelessWebexPlugin {
3572
3682
  webSocketUrl,
3573
3683
  // @ts-ignore - fix type
3574
3684
  this.webex.sessionId,
3575
- this.members,
3685
+ this.members
3576
3686
  );
3577
3687
 
3578
3688
  LoggerProxy.logger.info(
@@ -3586,7 +3696,7 @@ export default class Meeting extends StatelessWebexPlugin {
3586
3696
  this,
3587
3697
  {
3588
3698
  file: 'meeting/index',
3589
- function: 'join'
3699
+ function: 'join',
3590
3700
  },
3591
3701
  EVENT_TRIGGERS.MEETING_STARTED_RECEIVING_TRANSCRIPTION,
3592
3702
  payload
@@ -3596,17 +3706,13 @@ export default class Meeting extends StatelessWebexPlugin {
3596
3706
  this.monitorTranscriptionSocketConnection();
3597
3707
  // @ts-ignore - fix type
3598
3708
  this.transcription.connect(this.webex.credentials.supertoken.access_token);
3599
- }
3600
- catch (error) {
3709
+ } catch (error) {
3601
3710
  LoggerProxy.logger.error(`Meeting:index#receiveTranscription --> ${error}`);
3602
- Metrics.sendBehavioralMetric(
3603
- BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_FAILURE,
3604
- {
3605
- correlation_id: this.correlationId,
3606
- reason: error.message,
3607
- stack: error.stack
3608
- }
3609
- );
3711
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_FAILURE, {
3712
+ correlation_id: this.correlationId,
3713
+ reason: error.message,
3714
+ stack: error.stack,
3715
+ });
3610
3716
  }
3611
3717
  }
3612
3718
 
@@ -3636,7 +3742,7 @@ export default class Meeting extends StatelessWebexPlugin {
3636
3742
  this,
3637
3743
  {
3638
3744
  file: 'meeting',
3639
- function: 'triggerStopReceivingTranscriptionEvent'
3745
+ function: 'triggerStopReceivingTranscriptionEvent',
3640
3746
  },
3641
3747
  EVENT_TRIGGERS.MEETING_STOPPED_RECEIVING_TRANSCRIPTION
3642
3748
  );
@@ -3683,10 +3789,13 @@ export default class Meeting extends StatelessWebexPlugin {
3683
3789
 
3684
3790
  if (!this.hasJoinedOnce) {
3685
3791
  this.hasJoinedOnce = true;
3686
- }
3687
- else {
3688
- LoggerProxy.logger.log(`Meeting:index#join --> Generating a new correlation id for meeting ${this.id}`);
3689
- LoggerProxy.logger.log(`Meeting:index#join --> Previous correlation id ${this.correlationId}`);
3792
+ } else {
3793
+ LoggerProxy.logger.log(
3794
+ `Meeting:index#join --> Generating a new correlation id for meeting ${this.id}`
3795
+ );
3796
+ LoggerProxy.logger.log(
3797
+ `Meeting:index#join --> Previous correlation id ${this.correlationId}`
3798
+ );
3690
3799
  this.setCorrelationId(uuid.v4());
3691
3800
  LoggerProxy.logger.log(`Meeting:index#join --> New correlation id ${this.correlationId}`);
3692
3801
  }
@@ -3698,7 +3807,7 @@ export default class Meeting extends StatelessWebexPlugin {
3698
3807
  Metrics.postEvent({
3699
3808
  event: eventType.CALL_INITIATED,
3700
3809
  meeting: this,
3701
- data: {trigger: trigger.USER_INTERACTION, isRoapCallEnabled: true}
3810
+ data: {trigger: trigger.USER_INTERACTION, isRoapCallEnabled: true},
3702
3811
  });
3703
3812
 
3704
3813
  LoggerProxy.logger.log('Meeting:index#join --> Joining a meeting');
@@ -3771,15 +3880,13 @@ export default class Meeting extends StatelessWebexPlugin {
3771
3880
  .then((join) => {
3772
3881
  joinSuccess(join);
3773
3882
  this.deferJoin = undefined;
3774
- Metrics.sendBehavioralMetric(
3775
- BEHAVIORAL_METRICS.JOIN_SUCCESS,
3776
- {
3777
- correlation_id: this.correlationId
3778
- }
3779
- );
3883
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_SUCCESS, {
3884
+ correlation_id: this.correlationId,
3885
+ });
3780
3886
 
3781
3887
  return join;
3782
- }).then(async (join) => {
3888
+ })
3889
+ .then(async (join) => {
3783
3890
  if (isBrowser) {
3784
3891
  // @ts-ignore - config coming from registerPlugin
3785
3892
  if (this.config.receiveTranscription || options.receiveTranscription) {
@@ -3788,9 +3895,10 @@ export default class Meeting extends StatelessWebexPlugin {
3788
3895
  LoggerProxy.logger.info('Meeting:index#join --> enabled to recieve transcription!');
3789
3896
  }
3790
3897
  }
3791
- }
3792
- else {
3793
- LoggerProxy.logger.error('Meeting:index#join --> Receving transcription is not supported on this platform');
3898
+ } else {
3899
+ LoggerProxy.logger.error(
3900
+ 'Meeting:index#join --> Receving transcription is not supported on this platform'
3901
+ );
3794
3902
  }
3795
3903
 
3796
3904
  return join;
@@ -3804,28 +3912,23 @@ export default class Meeting extends StatelessWebexPlugin {
3804
3912
  meeting: this,
3805
3913
  meetingId: this.id,
3806
3914
  data: {
3807
- errors: [
3808
- Metrics.parseLocusError(error.error, true)
3809
- ]
3810
- }
3915
+ errors: [Metrics.parseLocusError(error.error, true)],
3916
+ },
3811
3917
  });
3812
3918
 
3813
3919
  // TODO: change this to error codes and pre defined dictionary
3814
- Metrics.sendBehavioralMetric(
3815
- BEHAVIORAL_METRICS.JOIN_FAILURE,
3816
- {
3817
- correlation_id: this.correlationId,
3818
- reason: error.error?.message,
3819
- stack: error.stack
3820
- }
3821
- );
3920
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_FAILURE, {
3921
+ correlation_id: this.correlationId,
3922
+ reason: error.error?.message,
3923
+ stack: error.stack,
3924
+ });
3822
3925
 
3823
3926
  // Upload logs on join Failure
3824
3927
  Trigger.trigger(
3825
3928
  this,
3826
3929
  {
3827
3930
  file: 'meeting/index',
3828
- function: 'join'
3931
+ function: 'join',
3829
3932
  },
3830
3933
  EVENTS.REQUEST_UPLOAD_LOGS,
3831
3934
  this
@@ -3877,28 +3980,28 @@ export default class Meeting extends StatelessWebexPlugin {
3877
3980
 
3878
3981
  if (!this.dialInUrl) this.dialInUrl = `dialin:///${uuid.v4()}`;
3879
3982
 
3880
- return this.meetingRequest.dialIn({
3881
- correlationId,
3882
- dialInUrl: this.dialInUrl,
3883
- locusUrl,
3884
- clientUrl: this.deviceUrl
3885
- }).then((res) => {
3886
- this.locusInfo.onFullLocus(res.body.locus);
3887
- }).catch((error) => {
3888
- Metrics.sendBehavioralMetric(
3889
- BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE,
3890
- {
3983
+ return this.meetingRequest
3984
+ .dialIn({
3985
+ correlationId,
3986
+ dialInUrl: this.dialInUrl,
3987
+ locusUrl,
3988
+ clientUrl: this.deviceUrl,
3989
+ })
3990
+ .then((res) => {
3991
+ this.locusInfo.onFullLocus(res.body.locus);
3992
+ })
3993
+ .catch((error) => {
3994
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE, {
3891
3995
  correlation_id: this.correlationId,
3892
3996
  dial_in_url: this.dialInUrl,
3893
3997
  locus_id: locusUrl.split('/').pop(),
3894
3998
  client_url: this.deviceUrl,
3895
3999
  reason: error.error?.message,
3896
- stack: error.stack
3897
- }
3898
- );
4000
+ stack: error.stack,
4001
+ });
3899
4002
 
3900
- return Promise.reject(error);
3901
- });
4003
+ return Promise.reject(error);
4004
+ });
3902
4005
  }
3903
4006
 
3904
4007
  /**
@@ -3915,29 +4018,29 @@ export default class Meeting extends StatelessWebexPlugin {
3915
4018
 
3916
4019
  if (!this.dialOutUrl) this.dialOutUrl = `dialout:///${uuid.v4()}`;
3917
4020
 
3918
- return this.meetingRequest.dialOut({
3919
- correlationId,
3920
- dialOutUrl: this.dialOutUrl,
3921
- phoneNumber,
3922
- locusUrl,
3923
- clientUrl: this.deviceUrl
3924
- }).then((res) => {
3925
- this.locusInfo.onFullLocus(res.body.locus);
3926
- }).catch((error) => {
3927
- Metrics.sendBehavioralMetric(
3928
- BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE,
3929
- {
4021
+ return this.meetingRequest
4022
+ .dialOut({
4023
+ correlationId,
4024
+ dialOutUrl: this.dialOutUrl,
4025
+ phoneNumber,
4026
+ locusUrl,
4027
+ clientUrl: this.deviceUrl,
4028
+ })
4029
+ .then((res) => {
4030
+ this.locusInfo.onFullLocus(res.body.locus);
4031
+ })
4032
+ .catch((error) => {
4033
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE, {
3930
4034
  correlation_id: this.correlationId,
3931
4035
  dial_out_url: this.dialOutUrl,
3932
4036
  locus_id: locusUrl.split('/').pop(),
3933
4037
  client_url: this.deviceUrl,
3934
4038
  reason: error.error?.message,
3935
- stack: error.stack
3936
- }
3937
- );
4039
+ stack: error.stack,
4040
+ });
3938
4041
 
3939
- return Promise.reject(error);
3940
- });
4042
+ return Promise.reject(error);
4043
+ });
3941
4044
  }
3942
4045
 
3943
4046
  /**
@@ -3949,12 +4052,12 @@ export default class Meeting extends StatelessWebexPlugin {
3949
4052
  */
3950
4053
  public disconnectPhoneAudio() {
3951
4054
  return Promise.all([
3952
- this.isPhoneProvisioned(this.dialInDeviceStatus) ?
3953
- MeetingUtil.disconnectPhoneAudio(this, this.dialInUrl) :
3954
- Promise.resolve(),
3955
- this.isPhoneProvisioned(this.dialOutDeviceStatus) ?
3956
- MeetingUtil.disconnectPhoneAudio(this, this.dialOutUrl) :
3957
- Promise.resolve()
4055
+ this.isPhoneProvisioned(this.dialInDeviceStatus)
4056
+ ? MeetingUtil.disconnectPhoneAudio(this, this.dialInUrl)
4057
+ : Promise.resolve(),
4058
+ this.isPhoneProvisioned(this.dialOutDeviceStatus)
4059
+ ? MeetingUtil.disconnectPhoneAudio(this, this.dialOutUrl)
4060
+ : Promise.resolve(),
3958
4061
  ]);
3959
4062
  }
3960
4063
 
@@ -3980,17 +4083,17 @@ export default class Meeting extends StatelessWebexPlugin {
3980
4083
  share: true,
3981
4084
  share_audio: false,
3982
4085
  video: false,
3983
- whiteboard: false
4086
+ whiteboard: false,
3984
4087
  },
3985
4088
  tx: {
3986
4089
  audio: false,
3987
4090
  share: false,
3988
4091
  share_audio: false,
3989
4092
  video: false,
3990
- whiteboard: false
3991
- }
3992
- }
3993
- }
4093
+ whiteboard: false,
4094
+ },
4095
+ },
4096
+ },
3994
4097
  });
3995
4098
 
3996
4099
  Metrics.postEvent({event: eventType.MOVE_MEDIA, meeting: this});
@@ -4009,8 +4112,8 @@ export default class Meeting extends StatelessWebexPlugin {
4009
4112
  sendAudio: false,
4010
4113
  receiveAudio: false,
4011
4114
  sendShare: false,
4012
- receiveShare: true
4013
- }
4115
+ receiveShare: true,
4116
+ },
4014
4117
  };
4015
4118
 
4016
4119
  // clean up the local tracks
@@ -4022,50 +4125,44 @@ export default class Meeting extends StatelessWebexPlugin {
4022
4125
 
4023
4126
  this.mediaProperties.unsetMediaTracks();
4024
4127
 
4025
-
4026
4128
  // when a move to is intiated by the client , Locus delets the existing media node from the server as soon the DX answers the meeting
4027
4129
  // once the DX answers we establish connection back the media server with only receiveShare enabled
4028
4130
  // @ts-ignore - reconnectMedia does not accept any argument
4029
- await this.reconnectionManager.reconnectMedia(mediaSettings)
4030
- .then(() => {
4031
- Metrics.sendBehavioralMetric(
4032
- BEHAVIORAL_METRICS.MOVE_TO_SUCCESS,
4033
- );
4034
- });
4035
- }
4036
- catch (error) {
4131
+ await this.reconnectionManager.reconnectMedia(mediaSettings).then(() => {
4132
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MOVE_TO_SUCCESS);
4133
+ });
4134
+ } catch (error) {
4037
4135
  LoggerProxy.logger.error('Meeting:index#moveTo --> Failed to moveTo resourceId', error);
4038
- Metrics.sendBehavioralMetric(
4039
- BEHAVIORAL_METRICS.MOVE_TO_FAILURE,
4040
- {
4041
- correlation_id: this.correlationId,
4042
- locus_id: this.locusUrl.split('/').pop(),
4043
- reason: error.message,
4044
- stack: error.stack
4045
- }
4046
- );
4136
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MOVE_TO_FAILURE, {
4137
+ correlation_id: this.correlationId,
4138
+ locus_id: this.locusUrl.split('/').pop(),
4139
+ reason: error.message,
4140
+ stack: error.stack,
4141
+ });
4047
4142
  }
4048
4143
  });
4049
4144
 
4050
- LoggerProxy.logger.info('Meeting:index#moveTo --> Initated moved to using resourceId', resourceId);
4145
+ LoggerProxy.logger.info(
4146
+ 'Meeting:index#moveTo --> Initated moved to using resourceId',
4147
+ resourceId
4148
+ );
4051
4149
 
4052
- return MeetingUtil.joinMeetingOptions(this, {resourceId, moveToResource: true}).then(() => {
4053
- this.meetingFiniteStateMachine.join();
4054
- }).catch((error) => {
4055
- this.meetingFiniteStateMachine.fail(error);
4056
- Metrics.sendBehavioralMetric(
4057
- BEHAVIORAL_METRICS.MOVE_TO_FAILURE,
4058
- {
4150
+ return MeetingUtil.joinMeetingOptions(this, {resourceId, moveToResource: true})
4151
+ .then(() => {
4152
+ this.meetingFiniteStateMachine.join();
4153
+ })
4154
+ .catch((error) => {
4155
+ this.meetingFiniteStateMachine.fail(error);
4156
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MOVE_TO_FAILURE, {
4059
4157
  correlation_id: this.correlationId,
4060
4158
  locus_id: this.locusUrl.split('/').pop(),
4061
4159
  reason: error.message,
4062
- stack: error.stack
4063
- }
4064
- );
4065
- LoggerProxy.logger.error('Meeting:index#moveTo --> Failed to moveTo resourceId', error);
4160
+ stack: error.stack,
4161
+ });
4162
+ LoggerProxy.logger.error('Meeting:index#moveTo --> Failed to moveTo resourceId', error);
4066
4163
 
4067
- return Promise.reject(error);
4068
- });
4164
+ return Promise.reject(error);
4165
+ });
4069
4166
  }
4070
4167
 
4071
4168
  /**
@@ -4085,26 +4182,24 @@ export default class Meeting extends StatelessWebexPlugin {
4085
4182
  Metrics.postEvent({event: eventType.MOVE_MEDIA, meeting: this});
4086
4183
 
4087
4184
  return MeetingUtil.joinMeetingOptions(this)
4088
- .then(() => MeetingUtil.leaveMeeting(this, {
4089
- resourceId,
4090
- correlationId: oldCorrelationId,
4091
- moveMeeting: true
4092
- }).then(() => {
4093
- this.resourceId = '';
4094
- Metrics.sendBehavioralMetric(
4095
- BEHAVIORAL_METRICS.MOVE_FROM_SUCCESS,
4096
- );
4097
- })).catch((error) => {
4185
+ .then(() =>
4186
+ MeetingUtil.leaveMeeting(this, {
4187
+ resourceId,
4188
+ correlationId: oldCorrelationId,
4189
+ moveMeeting: true,
4190
+ }).then(() => {
4191
+ this.resourceId = '';
4192
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MOVE_FROM_SUCCESS);
4193
+ })
4194
+ )
4195
+ .catch((error) => {
4098
4196
  this.meetingFiniteStateMachine.fail(error);
4099
- Metrics.sendBehavioralMetric(
4100
- BEHAVIORAL_METRICS.MOVE_FROM_FAILURE,
4101
- {
4102
- correlation_id: this.correlationId,
4103
- locus_id: this.locusUrl.split('/').pop(),
4104
- reason: error.message,
4105
- stack: error.stack
4106
- }
4107
- );
4197
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MOVE_FROM_FAILURE, {
4198
+ correlation_id: this.correlationId,
4199
+ locus_id: this.locusUrl.split('/').pop(),
4200
+ reason: error.message,
4201
+ stack: error.stack,
4202
+ });
4108
4203
  LoggerProxy.logger.error('Meeting:index#moveTo --> Failed to moveTo resourceId', error);
4109
4204
 
4110
4205
  return Promise.reject(error);
@@ -4124,55 +4219,63 @@ export default class Meeting extends StatelessWebexPlugin {
4124
4219
  getMediaStreams = (
4125
4220
  mediaDirection: any,
4126
4221
  // This return an OBJECT {video: {height, widght}}
4222
+ // eslint-disable-next-line default-param-last
4127
4223
  audioVideo: any = VIDEO_RESOLUTIONS[this.mediaProperties.localQualityLevel],
4128
4224
  sharePreferences?: any
4129
4225
  ) => {
4130
4226
  if (
4131
4227
  mediaDirection &&
4132
- (
4133
- mediaDirection.sendAudio ||
4134
- mediaDirection.sendVideo ||
4135
- mediaDirection.sendShare
4136
- )
4228
+ (mediaDirection.sendAudio || mediaDirection.sendVideo || mediaDirection.sendShare)
4137
4229
  ) {
4138
- if (mediaDirection &&
4139
- (
4140
- mediaDirection.sendAudio &&
4141
- mediaDirection.sendVideo &&
4142
- mediaDirection.sendShare
4143
- ) &&
4230
+ if (
4231
+ mediaDirection &&
4232
+ mediaDirection.sendAudio &&
4233
+ mediaDirection.sendVideo &&
4234
+ mediaDirection.sendShare &&
4144
4235
  isBrowser('safari')
4145
4236
  ) {
4146
- LoggerProxy.logger.warn('Meeting:index#getMediaStreams --> Setting `sendShare` to FALSE, due to complications with Safari');
4237
+ LoggerProxy.logger.warn(
4238
+ 'Meeting:index#getMediaStreams --> Setting `sendShare` to FALSE, due to complications with Safari'
4239
+ );
4147
4240
 
4148
4241
  mediaDirection.sendShare = false;
4149
4242
 
4150
- LoggerProxy.logger.warn('Meeting:index#getMediaStreams --> Enabling `sendShare` along with `sendAudio` & `sendVideo`, on Safari, causes a failure while setting up a screen share at the same time as the camera+mic stream');
4151
- LoggerProxy.logger.warn('Meeting:index#getMediaStreams --> Please use `meeting.shareScreen()` to manually start the screen share after successfully joining the meeting');
4243
+ LoggerProxy.logger.warn(
4244
+ 'Meeting:index#getMediaStreams --> Enabling `sendShare` along with `sendAudio` & `sendVideo`, on Safari, causes a failure while setting up a screen share at the same time as the camera+mic stream'
4245
+ );
4246
+ LoggerProxy.logger.warn(
4247
+ 'Meeting:index#getMediaStreams --> Please use `meeting.shareScreen()` to manually start the screen share after successfully joining the meeting'
4248
+ );
4152
4249
  }
4153
4250
 
4154
4251
  if (audioVideo && isString(audioVideo)) {
4155
4252
  if (Object.keys(VIDEO_RESOLUTIONS).includes(audioVideo)) {
4156
4253
  this.mediaProperties.setLocalQualityLevel(audioVideo);
4157
4254
  audioVideo = {video: VIDEO_RESOLUTIONS[audioVideo].video};
4158
- }
4159
- else {
4160
- throw new ParameterError(`${audioVideo} not supported. Either pass level from pre-defined resolutions or pass complete audioVideo object`);
4255
+ } else {
4256
+ throw new ParameterError(
4257
+ `${audioVideo} not supported. Either pass level from pre-defined resolutions or pass complete audioVideo object`
4258
+ );
4161
4259
  }
4162
4260
  }
4163
4261
 
4164
4262
  if (!audioVideo.video) {
4165
- audioVideo = {...audioVideo, video: {...audioVideo.video, ...VIDEO_RESOLUTIONS[this.mediaProperties.localQualityLevel].video}};
4263
+ audioVideo = {
4264
+ ...audioVideo,
4265
+ video: {
4266
+ ...audioVideo.video,
4267
+ ...VIDEO_RESOLUTIONS[this.mediaProperties.localQualityLevel].video,
4268
+ },
4269
+ };
4166
4270
  }
4167
4271
  // extract deviceId if exists otherwise default to null.
4168
- const {deviceId: preferredVideoDevice} = (audioVideo && audioVideo.video || {deviceId: null});
4272
+ const {deviceId: preferredVideoDevice} = (audioVideo && audioVideo.video) || {deviceId: null};
4169
4273
  const lastVideoDeviceId = this.mediaProperties.getVideoDeviceId();
4170
4274
 
4171
4275
  if (preferredVideoDevice) {
4172
4276
  // Store new preferred video input device
4173
4277
  this.mediaProperties.setVideoDeviceId(preferredVideoDevice);
4174
- }
4175
- else if (lastVideoDeviceId) {
4278
+ } else if (lastVideoDeviceId) {
4176
4279
  // no new video preference specified so use last stored value,
4177
4280
  // works with empty object {} or media constraint.
4178
4281
  // eslint-disable-next-line no-param-reassign
@@ -4180,50 +4283,55 @@ export default class Meeting extends StatelessWebexPlugin {
4180
4283
  ...audioVideo,
4181
4284
  video: {
4182
4285
  ...audioVideo.video,
4183
- deviceId: lastVideoDeviceId
4184
- }
4286
+ deviceId: lastVideoDeviceId,
4287
+ },
4185
4288
  };
4186
4289
  }
4187
4290
 
4188
4291
  return Media.getSupportedDevice({
4189
4292
  sendAudio: mediaDirection.sendAudio,
4190
- sendVideo: mediaDirection.sendVideo
4293
+ sendVideo: mediaDirection.sendVideo,
4191
4294
  })
4192
- .catch((error) => Promise.reject(
4193
- new MediaError('Given constraints do not match permission set for either camera or microphone', error)
4194
- ))
4295
+ .catch((error) =>
4296
+ Promise.reject(
4297
+ new MediaError(
4298
+ 'Given constraints do not match permission set for either camera or microphone',
4299
+ error
4300
+ )
4301
+ )
4302
+ )
4195
4303
  .then((devicePermissions) =>
4196
4304
  Media.getUserMedia(
4197
4305
  {
4198
4306
  ...mediaDirection,
4199
4307
  sendAudio: devicePermissions.sendAudio,
4200
4308
  sendVideo: devicePermissions.sendVideo,
4201
- isSharing: this.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE
4309
+ isSharing: this.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE,
4202
4310
  },
4203
4311
  audioVideo,
4204
4312
  sharePreferences,
4205
4313
  // @ts-ignore - config coming from registerPlugin
4206
4314
  this.config
4207
- )
4208
- .catch((error) => {
4209
- // Whenever there is a failure when trying to access a user's device
4210
- // report it as an Behavioral metric
4211
- // This gives visibility into common errors and can help
4212
- // with further troubleshooting
4213
- const metricName = BEHAVIORAL_METRICS.GET_USER_MEDIA_FAILURE;
4214
- const data = {
4215
- correlation_id: this.correlationId,
4216
- locus_id: this.locusUrl?.split('/').pop(),
4217
- reason: error.message,
4218
- stack: error.stack
4219
- };
4220
- const metadata = {
4221
- type: error.name
4222
- };
4223
-
4224
- Metrics.sendBehavioralMetric(metricName, data, metadata);
4225
- throw new MediaError('Unable to retrieve media streams', error);
4226
- }));
4315
+ ).catch((error) => {
4316
+ // Whenever there is a failure when trying to access a user's device
4317
+ // report it as an Behavioral metric
4318
+ // This gives visibility into common errors and can help
4319
+ // with further troubleshooting
4320
+ const metricName = BEHAVIORAL_METRICS.GET_USER_MEDIA_FAILURE;
4321
+ const data = {
4322
+ correlation_id: this.correlationId,
4323
+ locus_id: this.locusUrl?.split('/').pop(),
4324
+ reason: error.message,
4325
+ stack: error.stack,
4326
+ };
4327
+ const metadata = {
4328
+ type: error.name,
4329
+ };
4330
+
4331
+ Metrics.sendBehavioralMetric(metricName, data, metadata);
4332
+ throw new MediaError('Unable to retrieve media streams', error);
4333
+ })
4334
+ );
4227
4335
  }
4228
4336
 
4229
4337
  return Promise.reject(
@@ -4231,7 +4339,6 @@ export default class Meeting extends StatelessWebexPlugin {
4231
4339
  );
4232
4340
  };
4233
4341
 
4234
-
4235
4342
  /**
4236
4343
  * Checks if the machine has at least one audio or video device
4237
4344
  * @param {Object} options
@@ -4240,7 +4347,13 @@ export default class Meeting extends StatelessWebexPlugin {
4240
4347
  * @returns {Object}
4241
4348
  * @memberof Meetings
4242
4349
  */
4243
- getSupportedDevices = ({ sendAudio = true, sendVideo = true }: { sendAudio: boolean; sendVideo: boolean }) => Media.getSupportedDevice({ sendAudio, sendVideo });
4350
+ getSupportedDevices = ({
4351
+ sendAudio = true,
4352
+ sendVideo = true,
4353
+ }: {
4354
+ sendAudio: boolean;
4355
+ sendVideo: boolean;
4356
+ }) => Media.getSupportedDevice({sendAudio, sendVideo});
4244
4357
 
4245
4358
  /**
4246
4359
  * Get the devices from the Media module
@@ -4260,15 +4373,22 @@ export default class Meeting extends StatelessWebexPlugin {
4260
4373
  // TODO: might have to send the same event to the developer
4261
4374
  // Add ip address info if geo hint is present
4262
4375
  // @ts-ignore fix type
4263
- options.data.intervalMetadata.peerReflexiveIP = this.webex.meetings.geoHintInfo?.clientAddress || options.data.intervalMetadata.peerReflexiveIP || MQA_STATS.DEFAULT_IP;
4264
- Metrics.postEvent({event: eventType.MEDIA_QUALITY, meeting: this, data: {intervalData: options.data, networkType: options.networkType}});
4376
+ options.data.intervalMetadata.peerReflexiveIP =
4377
+ this.webex.meetings.geoHintInfo?.clientAddress ||
4378
+ options.data.intervalMetadata.peerReflexiveIP ||
4379
+ MQA_STATS.DEFAULT_IP;
4380
+ Metrics.postEvent({
4381
+ event: eventType.MEDIA_QUALITY,
4382
+ meeting: this,
4383
+ data: {intervalData: options.data, networkType: options.networkType},
4384
+ });
4265
4385
  });
4266
4386
  this.statsAnalyzer.on(StatsAnalyzerEvents.LOCAL_MEDIA_STARTED, (data) => {
4267
4387
  Trigger.trigger(
4268
4388
  this,
4269
4389
  {
4270
4390
  file: 'meeting/index',
4271
- function: 'addMedia'
4391
+ function: 'addMedia',
4272
4392
  },
4273
4393
  EVENT_TRIGGERS.MEETING_MEDIA_LOCAL_STARTED,
4274
4394
  data
@@ -4277,8 +4397,8 @@ export default class Meeting extends StatelessWebexPlugin {
4277
4397
  event: eventType.SENDING_MEDIA_START,
4278
4398
  meeting: this,
4279
4399
  data: {
4280
- mediaType: data.type
4281
- }
4400
+ mediaType: data.type,
4401
+ },
4282
4402
  });
4283
4403
  });
4284
4404
  this.statsAnalyzer.on(StatsAnalyzerEvents.LOCAL_MEDIA_STOPPED, (data) => {
@@ -4286,8 +4406,8 @@ export default class Meeting extends StatelessWebexPlugin {
4286
4406
  event: eventType.SENDING_MEDIA_STOP,
4287
4407
  meeting: this,
4288
4408
  data: {
4289
- mediaType: data.type
4290
- }
4409
+ mediaType: data.type,
4410
+ },
4291
4411
  });
4292
4412
  });
4293
4413
  this.statsAnalyzer.on(StatsAnalyzerEvents.REMOTE_MEDIA_STARTED, (data) => {
@@ -4295,7 +4415,7 @@ export default class Meeting extends StatelessWebexPlugin {
4295
4415
  this,
4296
4416
  {
4297
4417
  file: 'meeting/index',
4298
- function: 'addMedia'
4418
+ function: 'addMedia',
4299
4419
  },
4300
4420
  EVENT_TRIGGERS.MEETING_MEDIA_REMOTE_STARTED,
4301
4421
  data
@@ -4304,8 +4424,8 @@ export default class Meeting extends StatelessWebexPlugin {
4304
4424
  event: eventType.RECEIVING_MEDIA_START,
4305
4425
  meeting: this,
4306
4426
  data: {
4307
- mediaType: data.type
4308
- }
4427
+ mediaType: data.type,
4428
+ },
4309
4429
  });
4310
4430
  });
4311
4431
  this.statsAnalyzer.on(StatsAnalyzerEvents.REMOTE_MEDIA_STOPPED, (data) => {
@@ -4313,8 +4433,8 @@ export default class Meeting extends StatelessWebexPlugin {
4313
4433
  event: eventType.RECEIVING_MEDIA_STOP,
4314
4434
  meeting: this,
4315
4435
  data: {
4316
- mediaType: data.type
4317
- }
4436
+ mediaType: data.type,
4437
+ },
4318
4438
  });
4319
4439
  });
4320
4440
  };
@@ -4363,17 +4483,17 @@ export default class Meeting extends StatelessWebexPlugin {
4363
4483
  share: false,
4364
4484
  share_audio: false,
4365
4485
  video: false,
4366
- whiteboard: false
4486
+ whiteboard: false,
4367
4487
  },
4368
4488
  tx: {
4369
4489
  audio: false,
4370
4490
  share: false,
4371
4491
  share_audio: false,
4372
4492
  video: false,
4373
- whiteboard: false
4374
- }
4375
- }
4376
- }
4493
+ whiteboard: false,
4494
+ },
4495
+ },
4496
+ },
4377
4497
  });
4378
4498
 
4379
4499
  return MeetingUtil.validateOptions(options)
@@ -4390,20 +4510,25 @@ export default class Meeting extends StatelessWebexPlugin {
4390
4510
 
4391
4511
  return this.preMedia(localStream, localShare, mediaSettings);
4392
4512
  })
4393
- .then(() => Media.attachMedia(this.mediaProperties, {
4394
- meetingId: this.id,
4395
- remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
4396
- // @ts-ignore - config coming from registerPlugin
4397
- enableRtx: this.config.enableRtx,
4398
- // @ts-ignore - config coming from registerPlugin
4399
- enableExtmap: this.config.enableExtmap,
4400
- setStartLocalSDPGenRemoteSDPRecvDelay: this.setStartLocalSDPGenRemoteSDPRecvDelay.bind(this)
4401
- }))
4402
- .then((peerConnection) => this.getDevices().then((devices) => {
4403
- MeetingUtil.handleDeviceLogging(devices);
4404
-
4405
- return peerConnection;
4406
- }))
4513
+ .then(() =>
4514
+ Media.attachMedia(this.mediaProperties, {
4515
+ meetingId: this.id,
4516
+ remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
4517
+ // @ts-ignore - config coming from registerPlugin
4518
+ enableRtx: this.config.enableRtx,
4519
+ // @ts-ignore - config coming from registerPlugin
4520
+ enableExtmap: this.config.enableExtmap,
4521
+ setStartLocalSDPGenRemoteSDPRecvDelay:
4522
+ this.setStartLocalSDPGenRemoteSDPRecvDelay.bind(this),
4523
+ })
4524
+ )
4525
+ .then((peerConnection) =>
4526
+ this.getDevices().then((devices) => {
4527
+ MeetingUtil.handleDeviceLogging(devices);
4528
+
4529
+ return peerConnection;
4530
+ })
4531
+ )
4407
4532
  .then((peerConnection) => {
4408
4533
  this.handleMediaLogging(this.mediaProperties);
4409
4534
  LoggerProxy.logger.info(`${LOG_HEADER} PeerConnection Received from attachMedia `);
@@ -4417,63 +4542,71 @@ export default class Meeting extends StatelessWebexPlugin {
4417
4542
  // @ts-ignore - config coming from registerPlugin
4418
4543
  this.statsAnalyzer = new StatsAnalyzer(this.config.stats, this.networkQualityMonitor);
4419
4544
  this.setupStatsAnalyzerEventHandlers();
4420
- this.networkQualityMonitor.on(EVENT_TRIGGERS.NETWORK_QUALITY, this.sendNetworkQualityEvent.bind(this));
4545
+ this.networkQualityMonitor.on(
4546
+ EVENT_TRIGGERS.NETWORK_QUALITY,
4547
+ this.sendNetworkQualityEvent.bind(this)
4548
+ );
4421
4549
  }
4422
4550
  })
4423
4551
  .catch((error) => {
4424
- LoggerProxy.logger.error(`${LOG_HEADER} Error adding media , setting up peerconnection, `, error);
4425
-
4426
- Metrics.sendBehavioralMetric(
4427
- BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE,
4428
- {
4429
- correlation_id: this.correlationId,
4430
- locus_id: this.locusUrl.split('/').pop(),
4431
- reason: error.message,
4432
- stack: error.stack,
4433
- turnDiscoverySkippedReason,
4434
- turnServerUsed
4435
- }
4552
+ LoggerProxy.logger.error(
4553
+ `${LOG_HEADER} Error adding media , setting up peerconnection, `,
4554
+ error
4436
4555
  );
4437
4556
 
4557
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE, {
4558
+ correlation_id: this.correlationId,
4559
+ locus_id: this.locusUrl.split('/').pop(),
4560
+ reason: error.message,
4561
+ stack: error.stack,
4562
+ turnDiscoverySkippedReason,
4563
+ turnServerUsed,
4564
+ });
4565
+
4438
4566
  throw error;
4439
4567
  })
4440
- .then(() => new Promise<void>((resolve, reject) => {
4441
- let timerCount = 0;
4442
-
4443
- // eslint-disable-next-line func-names
4444
- // eslint-disable-next-line prefer-arrow-callback
4445
- if (this.type === _CALL_) {
4446
- resolve();
4447
- }
4448
- const joiningTimer = setInterval(() => {
4449
- timerCount += 1;
4450
- if (this.meetingState === FULL_STATE.ACTIVE) {
4451
- clearInterval(joiningTimer);
4452
- resolve();
4453
- }
4568
+ .then(
4569
+ () =>
4570
+ new Promise<void>((resolve, reject) => {
4571
+ let timerCount = 0;
4572
+
4573
+ // eslint-disable-next-line func-names
4574
+ // eslint-disable-next-line prefer-arrow-callback
4575
+ if (this.type === _CALL_) {
4576
+ resolve();
4577
+ }
4578
+ const joiningTimer = setInterval(() => {
4579
+ timerCount += 1;
4580
+ if (this.meetingState === FULL_STATE.ACTIVE) {
4581
+ clearInterval(joiningTimer);
4582
+ resolve();
4583
+ }
4454
4584
 
4455
- if (timerCount === 4) {
4456
- clearInterval(joiningTimer);
4457
- reject(new Error('Meeting is still not active '));
4458
- }
4459
- }, 1000);
4460
- }))
4585
+ if (timerCount === 4) {
4586
+ clearInterval(joiningTimer);
4587
+ reject(new Error('Meeting is still not active '));
4588
+ }
4589
+ }, 1000);
4590
+ })
4591
+ )
4461
4592
  .then(() =>
4462
- logRequest(this.roap
4463
- .sendRoapMediaRequest({
4593
+ logRequest(
4594
+ this.roap.sendRoapMediaRequest({
4464
4595
  sdp: this.mediaProperties.peerConnection.sdp,
4465
4596
  roapSeq: this.roapSeq,
4466
- meeting: this // or can pass meeting ID
4467
- }), {
4468
- header: `${LOG_HEADER} Send Roap Media Request.`,
4469
- success: `${LOG_HEADER} Successfully send roap media request`,
4470
- failure: `${LOG_HEADER} Error joining the call on send roap media request, `
4471
- }))
4472
- .then(
4473
- () => this.mediaProperties.waitForIceConnectedState()
4474
- .catch(() => {
4475
- throw createMeetingsError(30202, 'Meeting connection failed');
4476
- })
4597
+ meeting: this, // or can pass meeting ID
4598
+ }),
4599
+ {
4600
+ header: `${LOG_HEADER} Send Roap Media Request.`,
4601
+ success: `${LOG_HEADER} Successfully send roap media request`,
4602
+ failure: `${LOG_HEADER} Error joining the call on send roap media request, `,
4603
+ }
4604
+ )
4605
+ )
4606
+ .then(() =>
4607
+ this.mediaProperties.waitForIceConnectedState().catch(() => {
4608
+ throw createMeetingsError(30202, 'Meeting connection failed');
4609
+ })
4477
4610
  )
4478
4611
  .then(() => {
4479
4612
  LoggerProxy.logger.info(`${LOG_HEADER} PeerConnection CONNECTED`);
@@ -4491,63 +4624,61 @@ export default class Meeting extends StatelessWebexPlugin {
4491
4624
  })
4492
4625
  .then(() => this.mediaProperties.getCurrentConnectionType())
4493
4626
  .then((connectionType) => {
4494
- Metrics.sendBehavioralMetric(
4495
- BEHAVIORAL_METRICS.ADD_MEDIA_SUCCESS,
4496
- {
4497
- correlation_id: this.correlationId,
4498
- locus_id: this.locusUrl.split('/').pop(),
4499
- connectionType
4500
- }
4501
- );
4627
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_SUCCESS, {
4628
+ correlation_id: this.correlationId,
4629
+ locus_id: this.locusUrl.split('/').pop(),
4630
+ connectionType,
4631
+ });
4502
4632
  })
4503
4633
  .catch((error) => {
4504
4634
  // Clean up stats analyzer, peer connection, and turn off listeners
4505
- const stopStatsAnalyzer = (this.statsAnalyzer) ? this.statsAnalyzer.stopAnalyzer() : Promise.resolve();
4635
+ const stopStatsAnalyzer = this.statsAnalyzer
4636
+ ? this.statsAnalyzer.stopAnalyzer()
4637
+ : Promise.resolve();
4506
4638
 
4507
- return stopStatsAnalyzer
4508
- .then(() => {
4509
- this.statsAnalyzer = null;
4639
+ return stopStatsAnalyzer.then(() => {
4640
+ this.statsAnalyzer = null;
4510
4641
 
4511
- if (this.mediaProperties.peerConnection) {
4512
- this.closePeerConnections();
4513
- this.unsetPeerConnections();
4514
- }
4642
+ if (this.mediaProperties.peerConnection) {
4643
+ this.closePeerConnections();
4644
+ this.unsetPeerConnections();
4645
+ }
4515
4646
 
4516
- LoggerProxy.logger.error(`${LOG_HEADER} Error adding media failed to initiate PC and send request, `, error);
4647
+ LoggerProxy.logger.error(
4648
+ `${LOG_HEADER} Error adding media failed to initiate PC and send request, `,
4649
+ error
4650
+ );
4517
4651
 
4518
- Metrics.sendBehavioralMetric(
4519
- BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE,
4520
- {
4521
- correlation_id: this.correlationId,
4522
- locus_id: this.locusUrl.split('/').pop(),
4523
- reason: error.message,
4524
- stack: error.stack,
4525
- code: error.code,
4526
- turnDiscoverySkippedReason,
4527
- turnServerUsed
4528
- }
4529
- );
4652
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE, {
4653
+ correlation_id: this.correlationId,
4654
+ locus_id: this.locusUrl.split('/').pop(),
4655
+ reason: error.message,
4656
+ stack: error.stack,
4657
+ code: error.code,
4658
+ turnDiscoverySkippedReason,
4659
+ turnServerUsed,
4660
+ });
4530
4661
 
4531
- // Upload logs on error while adding media
4532
- Trigger.trigger(
4533
- this,
4534
- {
4535
- file: 'meeting/index',
4536
- function: 'addMedia'
4537
- },
4538
- EVENTS.REQUEST_UPLOAD_LOGS,
4539
- this
4540
- );
4662
+ // Upload logs on error while adding media
4663
+ Trigger.trigger(
4664
+ this,
4665
+ {
4666
+ file: 'meeting/index',
4667
+ function: 'addMedia',
4668
+ },
4669
+ EVENTS.REQUEST_UPLOAD_LOGS,
4670
+ this
4671
+ );
4541
4672
 
4542
- // If addMedia failes for not establishing connection then
4543
- // leave the meeting with reson connection failed as meeting anyways will end
4544
- // and cannot be connected unless network condition is checked for firewall
4545
- if (error.code === InvalidSdpError.CODE) {
4546
- this.leave({reason: MEETING_REMOVED_REASON.MEETING_CONNECTION_FAILED});
4547
- }
4673
+ // If addMedia failes for not establishing connection then
4674
+ // leave the meeting with reson connection failed as meeting anyways will end
4675
+ // and cannot be connected unless network condition is checked for firewall
4676
+ if (error.code === InvalidSdpError.CODE) {
4677
+ this.leave({reason: MEETING_REMOVED_REASON.MEETING_CONNECTION_FAILED});
4678
+ }
4548
4679
 
4549
- throw error;
4550
- });
4680
+ throw error;
4681
+ });
4551
4682
  });
4552
4683
  }
4553
4684
 
@@ -4556,7 +4687,10 @@ export default class Meeting extends StatelessWebexPlugin {
4556
4687
  * @returns {Boolean}
4557
4688
  */
4558
4689
  canUpdateMedia() {
4559
- return this.mediaProperties.peerConnection.signalingState === SDP.STABLE && !RoapCollection.isBusy(this.correlationId);
4690
+ return (
4691
+ this.mediaProperties.peerConnection.signalingState === SDP.STABLE &&
4692
+ !RoapCollection.isBusy(this.correlationId)
4693
+ );
4560
4694
  }
4561
4695
 
4562
4696
  /**
@@ -4570,10 +4704,15 @@ export default class Meeting extends StatelessWebexPlugin {
4570
4704
  private enqueueMediaUpdate(mediaUpdateType: string, options: object) {
4571
4705
  return new Promise((resolve, reject) => {
4572
4706
  const queueItem = {
4573
- pendingPromiseResolve: resolve, pendingPromiseReject: reject, mediaUpdateType, options
4707
+ pendingPromiseResolve: resolve,
4708
+ pendingPromiseReject: reject,
4709
+ mediaUpdateType,
4710
+ options,
4574
4711
  };
4575
4712
 
4576
- LoggerProxy.logger.log(`Meeting:index#enqueueMediaUpdate --> enqueuing media update type=${mediaUpdateType}`);
4713
+ LoggerProxy.logger.log(
4714
+ `Meeting:index#enqueueMediaUpdate --> enqueuing media update type=${mediaUpdateType}`
4715
+ );
4577
4716
  this.queuedMediaUpdates.push(queueItem);
4578
4717
  });
4579
4718
  }
@@ -4592,9 +4731,9 @@ export default class Meeting extends StatelessWebexPlugin {
4592
4731
  this,
4593
4732
  {
4594
4733
  file: 'meeting/index',
4595
- function: 'mediaNegotiatedEvent'
4734
+ function: 'mediaNegotiatedEvent',
4596
4735
  },
4597
- EVENT_TRIGGERS.MEDIA_NEGOTIATED,
4736
+ EVENT_TRIGGERS.MEDIA_NEGOTIATED
4598
4737
  );
4599
4738
  }
4600
4739
  };
@@ -4607,12 +4746,13 @@ export default class Meeting extends StatelessWebexPlugin {
4607
4746
  * @memberof Meeting
4608
4747
  */
4609
4748
  processNextQueuedMediaUpdate = () => {
4610
- if (this.canUpdateMedia() && (this.queuedMediaUpdates.length > 0)) {
4611
- const {
4612
- pendingPromiseResolve, pendingPromiseReject, mediaUpdateType, options
4613
- } = this.queuedMediaUpdates.shift();
4749
+ if (this.canUpdateMedia() && this.queuedMediaUpdates.length > 0) {
4750
+ const {pendingPromiseResolve, pendingPromiseReject, mediaUpdateType, options} =
4751
+ this.queuedMediaUpdates.shift();
4614
4752
 
4615
- LoggerProxy.logger.log(`Meeting:index#processNextQueuedMediaUpdate --> performing delayed media update type=${mediaUpdateType}`);
4753
+ LoggerProxy.logger.log(
4754
+ `Meeting:index#processNextQueuedMediaUpdate --> performing delayed media update type=${mediaUpdateType}`
4755
+ );
4616
4756
  switch (mediaUpdateType) {
4617
4757
  case MEDIA_UPDATE_TYPE.ALL:
4618
4758
  this.updateMedia(options).then(pendingPromiseResolve, pendingPromiseReject);
@@ -4627,7 +4767,9 @@ export default class Meeting extends StatelessWebexPlugin {
4627
4767
  this.updateShare(options).then(pendingPromiseResolve, pendingPromiseReject);
4628
4768
  break;
4629
4769
  default:
4630
- LoggerProxy.logger.error(`Peer-connection-manager:index#processNextQueuedMediaUpdate --> unsupported media update type ${mediaUpdateType} found in the queue`);
4770
+ LoggerProxy.logger.error(
4771
+ `Peer-connection-manager:index#processNextQueuedMediaUpdate --> unsupported media update type ${mediaUpdateType} found in the queue`
4772
+ );
4631
4773
  break;
4632
4774
  }
4633
4775
  }
@@ -4657,67 +4799,93 @@ export default class Meeting extends StatelessWebexPlugin {
4657
4799
  if (!this.canUpdateMedia()) {
4658
4800
  return this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.ALL, options);
4659
4801
  }
4660
- const {
4661
- localStream, localShare, mediaSettings
4662
- } = options;
4802
+ const {localStream, localShare, mediaSettings} = options;
4663
4803
 
4664
4804
  const previousSendShareStatus = this.mediaProperties.mediaDirection.sendShare;
4665
-
4666
- return MeetingUtil.validateOptions(options)
4667
- .then(() => this.preMedia(localStream, localShare, mediaSettings))
4668
- .then(() => Media.updateMedia(this.mediaProperties, {
4669
- meetingId: this.id,
4670
- remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
4671
- // @ts-ignore - config coming from registerPlugin
4672
- enableRtx: this.config.enableRtx,
4673
- // @ts-ignore - config coming from registerPlugin
4674
- enableExtmap: this.config.enableExtmap,
4675
- })
4676
- .then((peerConnection) => {
4677
- LoggerProxy.logger.info(`${LOG_HEADER} PeerConnection received from updateMedia, ${peerConnection}`);
4678
- this.setRemoteStream(peerConnection);
4679
- if (mediaSettings.receiveShare || localShare) {
4680
- PeerConnectionManager.setContentSlides(peerConnection);
4681
- }
4805
+
4806
+ return MeetingUtil.validateOptions(options)
4807
+ .then(() => this.preMedia(localStream, localShare, mediaSettings))
4808
+ .then(() =>
4809
+ Media.updateMedia(this.mediaProperties, {
4810
+ meetingId: this.id,
4811
+ remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
4812
+ // @ts-ignore - config coming from registerPlugin
4813
+ enableRtx: this.config.enableRtx,
4814
+ // @ts-ignore - config coming from registerPlugin
4815
+ enableExtmap: this.config.enableExtmap,
4682
4816
  })
4683
- .catch((error) => {
4684
- LoggerProxy.logger.error(`${LOG_HEADER} Error updatedMedia, `, error);
4817
+ .then((peerConnection) => {
4818
+ LoggerProxy.logger.info(
4819
+ `${LOG_HEADER} PeerConnection received from updateMedia, ${peerConnection}`
4820
+ );
4821
+ this.setRemoteStream(peerConnection);
4822
+ if (mediaSettings.receiveShare || localShare) {
4823
+ PeerConnectionManager.setContentSlides(peerConnection);
4824
+ }
4825
+ })
4826
+ .catch((error) => {
4827
+ LoggerProxy.logger.error(`${LOG_HEADER} Error updatedMedia, `, error);
4685
4828
 
4686
- Metrics.sendBehavioralMetric(
4687
- BEHAVIORAL_METRICS.UPDATE_MEDIA_FAILURE,
4688
- {
4829
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPDATE_MEDIA_FAILURE, {
4689
4830
  correlation_id: this.correlationId,
4690
4831
  locus_id: this.locusUrl.split('/').pop(),
4691
4832
  reason: error.message,
4692
- stack: error.stack
4833
+ stack: error.stack,
4834
+ });
4835
+
4836
+ throw error;
4837
+ })
4838
+ .then(() =>
4839
+ logRequest(
4840
+ this.roap.sendRoapMediaRequest({
4841
+ sdp: this.mediaProperties.peerConnection.sdp,
4842
+ roapSeq: this.roapSeq,
4843
+ meeting: this, // or can pass meeting ID
4844
+ }),
4845
+ {
4846
+ header: `${LOG_HEADER} sendRoapMediaRequest being sent`,
4847
+ success: `${LOG_HEADER} sendRoadMediaRequest successful`,
4848
+ failure: `${LOG_HEADER} Error updateMedia on send roap media request, `,
4849
+ }
4850
+ )
4851
+ )
4852
+ .then(() => this.checkForStopShare(mediaSettings.sendShare, previousSendShareStatus))
4853
+ .then((startShare) => {
4854
+ // This is a special case if we do an /floor grant followed by /media
4855
+ // we actually get a OFFER from the server and a GLAR condition happens
4856
+ if (startShare) {
4857
+ // We are assuming that the clients are connected when doing an update
4858
+ return this.share();
4693
4859
  }
4694
- );
4695
4860
 
4696
- throw error;
4697
- })
4698
- .then(() =>
4699
- logRequest(this.roap
4700
- .sendRoapMediaRequest({
4701
- sdp: this.mediaProperties.peerConnection.sdp,
4702
- roapSeq: this.roapSeq,
4703
- meeting: this, // or can pass meeting ID
4704
- }),
4705
- {
4706
- header: `${LOG_HEADER} sendRoapMediaRequest being sent`,
4707
- success: `${LOG_HEADER} sendRoadMediaRequest successful`,
4708
- failure: `${LOG_HEADER} Error updateMedia on send roap media request, `
4709
- }))
4710
- .then(() => this.checkForStopShare(mediaSettings.sendShare, previousSendShareStatus))
4711
- .then((startShare) => {
4712
- // This is a special case if we do an /floor grant followed by /media
4713
- // we actually get a OFFER from the server and a GLAR condition happens
4714
- if (startShare) {
4715
- // We are assuming that the clients are connected when doing an update
4716
- return this.requestScreenShareFloor();
4717
- }
4861
+ throw error;
4862
+ })
4863
+ .then(() =>
4864
+ logRequest(
4865
+ this.roap.sendRoapMediaRequest({
4866
+ sdp: this.mediaProperties.peerConnection.sdp,
4867
+ roapSeq: this.roapSeq,
4868
+ meeting: this, // or can pass meeting ID
4869
+ }),
4870
+ {
4871
+ header: `${LOG_HEADER} sendRoapMediaRequest being sent`,
4872
+ success: `${LOG_HEADER} sendRoadMediaRequest successful`,
4873
+ failure: `${LOG_HEADER} Error updateMedia on send roap media request, `,
4874
+ }
4875
+ )
4876
+ )
4877
+ .then(() => this.checkForStopShare(mediaSettings.sendShare, previousSendShareStatus))
4878
+ .then((startShare) => {
4879
+ // This is a special case if we do an /floor grant followed by /media
4880
+ // we actually get a OFFER from the server and a GLAR condition happens
4881
+ if (startShare) {
4882
+ // We are assuming that the clients are connected when doing an update
4883
+ return this.requestScreenShareFloor();
4884
+ }
4718
4885
 
4719
- return Promise.resolve();
4720
- }));
4886
+ return Promise.resolve();
4887
+ })
4888
+ );
4721
4889
  }
4722
4890
 
4723
4891
  /**
@@ -4730,13 +4898,15 @@ export default class Meeting extends StatelessWebexPlugin {
4730
4898
  * @public
4731
4899
  * @memberof Meeting
4732
4900
  */
4733
- public async updateAudio(options: { sendAudio: boolean; receiveAudio: boolean; stream: MediaStream }) {
4901
+ public async updateAudio(options: {
4902
+ sendAudio: boolean;
4903
+ receiveAudio: boolean;
4904
+ stream: MediaStream;
4905
+ }) {
4734
4906
  if (!this.canUpdateMedia()) {
4735
4907
  return this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.AUDIO, options);
4736
4908
  }
4737
- const {
4738
- sendAudio, receiveAudio, stream
4739
- } = options;
4909
+ const {sendAudio, receiveAudio, stream} = options;
4740
4910
 
4741
4911
  const {audioTransceiver} = this.mediaProperties.peerConnection;
4742
4912
  let track = MeetingUtil.getTrack(stream).audioTrack;
@@ -4748,7 +4918,11 @@ export default class Meeting extends StatelessWebexPlugin {
4748
4918
  if (this.effects && this.effects.state) {
4749
4919
  const bnrEnabled = this.effects.state.bnr.enabled;
4750
4920
 
4751
- if (sendAudio && !this.isAudioMuted() && (bnrEnabled === BNR_STATUS.ENABLED || bnrEnabled === BNR_STATUS.SHOULD_ENABLE)) {
4921
+ if (
4922
+ sendAudio &&
4923
+ !this.isAudioMuted() &&
4924
+ (bnrEnabled === BNR_STATUS.ENABLED || bnrEnabled === BNR_STATUS.SHOULD_ENABLE)
4925
+ ) {
4752
4926
  LoggerProxy.logger.info('Meeting:index#updateAudio. Calling WebRTC enable bnr method');
4753
4927
  track = await this.internal_enableBNR(track);
4754
4928
  LoggerProxy.logger.info('Meeting:index#updateAudio. WebRTC enable bnr request completed');
@@ -4762,10 +4936,9 @@ export default class Meeting extends StatelessWebexPlugin {
4762
4936
  if (this.mediaProperties.mediaDirection) {
4763
4937
  previousMediaDirection = {
4764
4938
  sendTrack: this.mediaProperties.mediaDirection.sendAudio,
4765
- receiveTrack: this.mediaProperties.mediaDirection.receiveAudio
4939
+ receiveTrack: this.mediaProperties.mediaDirection.receiveAudio,
4766
4940
  };
4767
- }
4768
- else {
4941
+ } else {
4769
4942
  this.mediaProperties.mediaDirection = {};
4770
4943
  }
4771
4944
 
@@ -4777,12 +4950,12 @@ export default class Meeting extends StatelessWebexPlugin {
4777
4950
  track,
4778
4951
  transceiver: audioTransceiver,
4779
4952
  peerConnection: this.mediaProperties.peerConnection,
4780
- previousMediaDirection
4953
+ previousMediaDirection,
4781
4954
  },
4782
4955
  {
4783
4956
  mediaProperties: this.mediaProperties,
4784
4957
  meeting: this,
4785
- id: this.id
4958
+ id: this.id,
4786
4959
  }
4787
4960
  );
4788
4961
  })
@@ -4792,7 +4965,8 @@ export default class Meeting extends StatelessWebexPlugin {
4792
4965
  this.mediaProperties.mediaDirection.receiveAudio = receiveAudio;
4793
4966
 
4794
4967
  // audio state could be undefined if you have not sent audio before
4795
- this.audio = this.audio || createMuteState(AUDIO, this, this.mediaProperties.mediaDirection);
4968
+ this.audio =
4969
+ this.audio || createMuteState(AUDIO, this, this.mediaProperties.mediaDirection);
4796
4970
  });
4797
4971
  }
4798
4972
 
@@ -4806,7 +4980,7 @@ export default class Meeting extends StatelessWebexPlugin {
4806
4980
  * @public
4807
4981
  * @memberof Meeting
4808
4982
  */
4809
- public updateVideo(options: { sendVideo: boolean; receiveVideo: boolean; stream: MediaStream }) {
4983
+ public updateVideo(options: {sendVideo: boolean; receiveVideo: boolean; stream: MediaStream}) {
4810
4984
  if (!this.canUpdateMedia()) {
4811
4985
  return this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.VIDEO, options);
4812
4986
  }
@@ -4819,30 +4993,35 @@ export default class Meeting extends StatelessWebexPlugin {
4819
4993
  }
4820
4994
 
4821
4995
  return MeetingUtil.validateOptions({sendVideo, localStream: stream})
4822
- .then(() => MeetingUtil.updateTransceiver({
4823
- type: 'video',
4824
- sendTrack: options.sendVideo,
4825
- receiveTrack: options.receiveVideo,
4826
- track,
4827
- transceiver: videoTransceiver,
4828
- peerConnection: this.mediaProperties.peerConnection,
4829
- previousMediaDirection: {
4830
- sendTrack: this.mediaProperties.mediaDirection.sendVideo,
4831
- receiveTrack: this.mediaProperties.mediaDirection.receiveVideo
4832
- }
4833
- },
4834
- {
4835
- mediaProperties: this.mediaProperties,
4836
- meeting: this,
4837
- id: this.id
4838
- }))
4996
+ .then(() =>
4997
+ MeetingUtil.updateTransceiver(
4998
+ {
4999
+ type: 'video',
5000
+ sendTrack: options.sendVideo,
5001
+ receiveTrack: options.receiveVideo,
5002
+ track,
5003
+ transceiver: videoTransceiver,
5004
+ peerConnection: this.mediaProperties.peerConnection,
5005
+ previousMediaDirection: {
5006
+ sendTrack: this.mediaProperties.mediaDirection.sendVideo,
5007
+ receiveTrack: this.mediaProperties.mediaDirection.receiveVideo,
5008
+ },
5009
+ },
5010
+ {
5011
+ mediaProperties: this.mediaProperties,
5012
+ meeting: this,
5013
+ id: this.id,
5014
+ }
5015
+ )
5016
+ )
4839
5017
  .then(() => {
4840
5018
  this.setLocalVideoTrack(track);
4841
5019
  this.mediaProperties.mediaDirection.sendVideo = sendVideo;
4842
5020
  this.mediaProperties.mediaDirection.receiveVideo = receiveVideo;
4843
5021
 
4844
5022
  // video state could be undefined if you have not sent video before
4845
- this.video = this.video || createMuteState(VIDEO, this, this.mediaProperties.mediaDirection);
5023
+ this.video =
5024
+ this.video || createMuteState(VIDEO, this, this.mediaProperties.mediaDirection);
4846
5025
  });
4847
5026
  }
4848
5027
 
@@ -4862,8 +5041,7 @@ export default class Meeting extends StatelessWebexPlugin {
4862
5041
 
4863
5042
  if (!sendShare && previousShareStatus) {
4864
5043
  // When user stops sharing
4865
- return this.releaseScreenShareFloor()
4866
- .then(() => Promise.resolve(false));
5044
+ return this.releaseScreenShareFloor().then(() => Promise.resolve(false));
4867
5045
  }
4868
5046
 
4869
5047
  return Promise.resolve();
@@ -4878,7 +5056,12 @@ export default class Meeting extends StatelessWebexPlugin {
4878
5056
  * @public
4879
5057
  * @memberof Meeting
4880
5058
  */
4881
- public updateShare(options: { sendShare?: boolean; receiveShare?: boolean, stream?: any, skipSignalingCheck?: boolean }) {
5059
+ public updateShare(options: {
5060
+ sendShare?: boolean;
5061
+ receiveShare?: boolean;
5062
+ stream?: any;
5063
+ skipSignalingCheck?: boolean;
5064
+ }) {
4882
5065
  if (!options.skipSignalingCheck && !this.canUpdateMedia()) {
4883
5066
  return this.enqueueMediaUpdate(MEDIA_UPDATE_TYPE.SHARE, options);
4884
5067
  }
@@ -4895,30 +5078,33 @@ export default class Meeting extends StatelessWebexPlugin {
4895
5078
 
4896
5079
  return MeetingUtil.validateOptions({sendShare, localShare: stream})
4897
5080
  .then(() => this.checkForStopShare(sendShare, previousSendShareStatus))
4898
- .then((startShare) => MeetingUtil.updateTransceiver({
4899
- type: 'video',
4900
- sendTrack: sendShare,
4901
- receiveTrack: receiveShare,
4902
- track,
4903
- transceiver: shareTransceiver,
4904
- peerConnection: this.mediaProperties.peerConnection,
4905
- previousMediaDirection: {
4906
- sendTrack: this.mediaProperties.mediaDirection.sendShare,
4907
- receiveTrack: this.mediaProperties.mediaDirection.receiveShare
4908
- }
4909
- },
4910
- {
4911
- mediaProperties: this.mediaProperties,
4912
- meeting: this,
4913
- id: this.id
4914
- })
4915
- .then(() => {
5081
+ .then((startShare) =>
5082
+ MeetingUtil.updateTransceiver(
5083
+ {
5084
+ type: 'video',
5085
+ sendTrack: sendShare,
5086
+ receiveTrack: receiveShare,
5087
+ track,
5088
+ transceiver: shareTransceiver,
5089
+ peerConnection: this.mediaProperties.peerConnection,
5090
+ previousMediaDirection: {
5091
+ sendTrack: this.mediaProperties.mediaDirection.sendShare,
5092
+ receiveTrack: this.mediaProperties.mediaDirection.receiveShare,
5093
+ },
5094
+ },
5095
+ {
5096
+ mediaProperties: this.mediaProperties,
5097
+ meeting: this,
5098
+ id: this.id,
5099
+ }
5100
+ ).then(() => {
4916
5101
  if (startShare) {
4917
5102
  return this.requestScreenShareFloor();
4918
5103
  }
4919
5104
 
4920
5105
  return Promise.resolve();
4921
- }))
5106
+ })
5107
+ )
4922
5108
  .then(() => {
4923
5109
  this.mediaProperties.mediaDirection.sendShare = sendShare;
4924
5110
  this.mediaProperties.mediaDirection.receiveShare = receiveShare;
@@ -4930,17 +5116,15 @@ export default class Meeting extends StatelessWebexPlugin {
4930
5116
  .finally(() => {
4931
5117
  const delay = 1e3;
4932
5118
  // Check to see if share was stopped natively before onended was assigned.
4933
- const sharingModeIsActive = this.mediaProperties.peerConnection.shareTransceiver.direction === SENDRECV;
5119
+ const sharingModeIsActive =
5120
+ this.mediaProperties.peerConnection.shareTransceiver.direction === SENDRECV;
4934
5121
  const isSharingOutOfSync = sharingModeIsActive && !this.isLocalShareLive;
4935
5122
 
4936
5123
  if (isSharingOutOfSync) {
4937
5124
  // Adding a delay to avoid a 409 from server
4938
5125
  // which results in user still appearing as if sharing.
4939
5126
  // Also delay give time for changes to peerConnection.
4940
- setTimeout(
4941
- () => this.handleShareTrackEnded(stream),
4942
- delay
4943
- );
5127
+ setTimeout(() => this.handleShareTrackEnded(stream), delay);
4944
5128
  }
4945
5129
  });
4946
5130
  }
@@ -4984,7 +5168,7 @@ export default class Meeting extends StatelessWebexPlugin {
4984
5168
  .acknowledgeMeeting({
4985
5169
  locusUrl: this.locusUrl,
4986
5170
  deviceUrl: this.deviceUrl,
4987
- correlationId: this.correlationId
5171
+ correlationId: this.correlationId,
4988
5172
  })
4989
5173
  .then((response) => Promise.resolve(response))
4990
5174
  .then((response) => {
@@ -4992,14 +5176,14 @@ export default class Meeting extends StatelessWebexPlugin {
4992
5176
  Metrics.postEvent({event: eventType.ALERT_DISPLAYED, meeting: this});
4993
5177
 
4994
5178
  return Promise.resolve({
4995
- response
5179
+ response,
4996
5180
  });
4997
5181
  });
4998
5182
  }
4999
5183
 
5000
5184
  // TODO: outside of 1:1 incoming, and all outgoing calls
5001
5185
  return Promise.resolve({
5002
- message: 'noop'
5186
+ message: 'noop',
5003
5187
  });
5004
5188
  }
5005
5189
 
@@ -5011,15 +5195,17 @@ export default class Meeting extends StatelessWebexPlugin {
5011
5195
  * @memberof Meeting
5012
5196
  */
5013
5197
  public decline(reason: string) {
5014
- return MeetingUtil.declineMeeting(this, reason).then((decline) => {
5015
- this.meetingFiniteStateMachine.decline();
5198
+ return MeetingUtil.declineMeeting(this, reason)
5199
+ .then((decline) => {
5200
+ this.meetingFiniteStateMachine.decline();
5016
5201
 
5017
- return Promise.resolve(decline);
5018
- }).catch((error) => {
5019
- this.meetingFiniteStateMachine.fail(error);
5202
+ return Promise.resolve(decline);
5203
+ })
5204
+ .catch((error) => {
5205
+ this.meetingFiniteStateMachine.fail(error);
5020
5206
 
5021
- return Promise.reject(error);
5022
- });
5207
+ return Promise.reject(error);
5208
+ });
5023
5209
  }
5024
5210
 
5025
5211
  /**
@@ -5030,8 +5216,12 @@ export default class Meeting extends StatelessWebexPlugin {
5030
5216
  * @public
5031
5217
  * @memberof Meeting
5032
5218
  */
5033
- public leave(options: { resourceId?: string, reason?: any } = {} as any) {
5034
- Metrics.postEvent({event: eventType.LEAVE, meeting: this, data: {trigger: trigger.USER_INTERACTION, canProceed: false}});
5219
+ public leave(options: {resourceId?: string; reason?: any} = {} as any) {
5220
+ Metrics.postEvent({
5221
+ event: eventType.LEAVE,
5222
+ meeting: this,
5223
+ data: {trigger: trigger.USER_INTERACTION, canProceed: false},
5224
+ });
5035
5225
  const leaveReason = options.reason || MEETING_REMOVED_REASON.CLIENT_LEAVE_REQUEST;
5036
5226
 
5037
5227
  LoggerProxy.logger.log('Meeting:index#leave --> Leaving a meeting');
@@ -5046,7 +5236,7 @@ export default class Meeting extends StatelessWebexPlugin {
5046
5236
  this,
5047
5237
  {
5048
5238
  file: 'meeting/index',
5049
- function: 'leave'
5239
+ function: 'leave',
5050
5240
  },
5051
5241
  EVENTS.REQUEST_UPLOAD_LOGS,
5052
5242
  this
@@ -5059,19 +5249,20 @@ export default class Meeting extends StatelessWebexPlugin {
5059
5249
  this,
5060
5250
  {
5061
5251
  file: 'meeting/index',
5062
- function: 'leave'
5252
+ function: 'leave',
5063
5253
  },
5064
5254
  EVENTS.DESTROY_MEETING,
5065
5255
  {
5066
5256
  reason: options.reason,
5067
- meetingId: this.id
5257
+ meetingId: this.id,
5068
5258
  }
5069
5259
  );
5070
5260
  }
5071
5261
  LoggerProxy.logger.log('Meeting:index#leave --> LEAVE REASON ', leaveReason);
5072
5262
 
5073
5263
  return leave;
5074
- }).catch((error) => {
5264
+ })
5265
+ .catch((error) => {
5075
5266
  this.meetingFiniteStateMachine.fail(error);
5076
5267
  LoggerProxy.logger.error('Meeting:index#leave --> Failed to leave ', error);
5077
5268
  // upload logs on leave irrespective of meeting delete
@@ -5079,21 +5270,18 @@ export default class Meeting extends StatelessWebexPlugin {
5079
5270
  this,
5080
5271
  {
5081
5272
  file: 'meeting/index',
5082
- function: 'leave'
5273
+ function: 'leave',
5083
5274
  },
5084
5275
  EVENTS.REQUEST_UPLOAD_LOGS,
5085
5276
  this
5086
5277
  );
5087
- Metrics.sendBehavioralMetric(
5088
- BEHAVIORAL_METRICS.MEETING_LEAVE_FAILURE,
5089
- {
5090
- correlation_id: this.correlationId,
5091
- locus_id: this.locusUrl.split('/').pop(),
5092
- reason: error.message,
5093
- stack: error.stack,
5094
- code: error.code
5095
- }
5096
- );
5278
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_LEAVE_FAILURE, {
5279
+ correlation_id: this.correlationId,
5280
+ locus_id: this.locusUrl.split('/').pop(),
5281
+ reason: error.message,
5282
+ stack: error.stack,
5283
+ code: error.code,
5284
+ });
5097
5285
 
5098
5286
  return Promise.reject(error);
5099
5287
  });
@@ -5122,14 +5310,15 @@ export default class Meeting extends StatelessWebexPlugin {
5122
5310
  personUrl: this.locusInfo.self.url,
5123
5311
  deviceUrl: this.deviceUrl,
5124
5312
  uri: whiteboard.url,
5125
- resourceUrl: channelUrl
5313
+ resourceUrl: channelUrl,
5126
5314
  };
5127
5315
 
5128
5316
  if (resourceToken) {
5129
5317
  body.resourceToken = resourceToken;
5130
5318
  }
5131
5319
 
5132
- return this.meetingRequest.changeMeetingFloor(body)
5320
+ return this.meetingRequest
5321
+ .changeMeetingFloor(body)
5133
5322
  .then(() => {
5134
5323
  this.isSharing = false;
5135
5324
 
@@ -5138,16 +5327,13 @@ export default class Meeting extends StatelessWebexPlugin {
5138
5327
  .catch((error) => {
5139
5328
  LoggerProxy.logger.error('Meeting:index#startWhiteboardShare --> Error ', error);
5140
5329
 
5141
- Metrics.sendBehavioralMetric(
5142
- BEHAVIORAL_METRICS.MEETING_START_WHITEBOARD_SHARE_FAILURE,
5143
- {
5144
- correlation_id: this.correlationId,
5145
- locus_id: this.locusUrl.split('/').pop(),
5146
- reason: error.message,
5147
- stack: error.stack,
5148
- board: {channelUrl}
5149
- }
5150
- );
5330
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_START_WHITEBOARD_SHARE_FAILURE, {
5331
+ correlation_id: this.correlationId,
5332
+ locus_id: this.locusUrl.split('/').pop(),
5333
+ reason: error.message,
5334
+ stack: error.stack,
5335
+ board: {channelUrl},
5336
+ });
5151
5337
 
5152
5338
  return Promise.reject(error);
5153
5339
  });
@@ -5169,12 +5355,13 @@ export default class Meeting extends StatelessWebexPlugin {
5169
5355
  if (whiteboard) {
5170
5356
  Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_STOPPED, meeting: this});
5171
5357
 
5172
- return this.meetingRequest.changeMeetingFloor({
5173
- disposition: FLOOR_ACTION.RELEASED,
5174
- personUrl: this.locusInfo.self.url,
5175
- deviceUrl: this.deviceUrl,
5176
- uri: whiteboard.url
5177
- })
5358
+ return this.meetingRequest
5359
+ .changeMeetingFloor({
5360
+ disposition: FLOOR_ACTION.RELEASED,
5361
+ personUrl: this.locusInfo.self.url,
5362
+ deviceUrl: this.deviceUrl,
5363
+ uri: whiteboard.url,
5364
+ })
5178
5365
  .catch((error) => {
5179
5366
  LoggerProxy.logger.error('Meeting:index#stopWhiteboardShare --> Error ', error);
5180
5367
 
@@ -5186,14 +5373,13 @@ export default class Meeting extends StatelessWebexPlugin {
5186
5373
  locus_id: this.locusUrl.split('/').pop(),
5187
5374
  reason: error.message,
5188
5375
  stack: error.stack,
5189
- board: {channelUrl}
5376
+ board: {channelUrl},
5190
5377
  }
5191
5378
  );
5192
5379
 
5193
5380
  return Promise.reject(error);
5194
5381
  })
5195
- .finally(() => {
5196
- });
5382
+ .finally(() => {});
5197
5383
  }
5198
5384
 
5199
5385
  return Promise.reject(new ParameterError('Cannot stop share without whiteboard.'));
@@ -5208,16 +5394,17 @@ export default class Meeting extends StatelessWebexPlugin {
5208
5394
  private requestScreenShareFloor() {
5209
5395
  const content = this.locusInfo.mediaShares.find((element) => element.name === CONTENT);
5210
5396
 
5211
- if (content && (this.shareStatus !== SHARE_STATUS.LOCAL_SHARE_ACTIVE)) {
5397
+ if (content && this.shareStatus !== SHARE_STATUS.LOCAL_SHARE_ACTIVE) {
5212
5398
  Metrics.postEvent({event: eventType.SHARE_INITIATED, meeting: this});
5213
5399
 
5214
- return this.meetingRequest.changeMeetingFloor({
5215
- disposition: FLOOR_ACTION.GRANTED,
5216
- personUrl: this.locusInfo.self.url,
5217
- deviceUrl: this.deviceUrl,
5218
- uri: content.url,
5219
- resourceUrl: this.resourceUrl
5220
- })
5400
+ return this.meetingRequest
5401
+ .changeMeetingFloor({
5402
+ disposition: FLOOR_ACTION.GRANTED,
5403
+ personUrl: this.locusInfo.self.url,
5404
+ deviceUrl: this.deviceUrl,
5405
+ uri: content.url,
5406
+ resourceUrl: this.resourceUrl,
5407
+ })
5221
5408
  .then(() => {
5222
5409
  this.isSharing = true;
5223
5410
 
@@ -5226,15 +5413,12 @@ export default class Meeting extends StatelessWebexPlugin {
5226
5413
  .catch((error) => {
5227
5414
  LoggerProxy.logger.error('Meeting:index#share --> Error ', error);
5228
5415
 
5229
- Metrics.sendBehavioralMetric(
5230
- BEHAVIORAL_METRICS.MEETING_SHARE_FAILURE,
5231
- {
5232
- correlation_id: this.correlationId,
5233
- locus_id: this.locusUrl.split('/').pop(),
5234
- reason: error.message,
5235
- stack: error.stack
5236
- }
5237
- );
5416
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_SHARE_FAILURE, {
5417
+ correlation_id: this.correlationId,
5418
+ locus_id: this.locusUrl.split('/').pop(),
5419
+ reason: error.message,
5420
+ stack: error.stack,
5421
+ });
5238
5422
 
5239
5423
  return Promise.reject(error);
5240
5424
  });
@@ -5255,7 +5439,7 @@ export default class Meeting extends StatelessWebexPlugin {
5255
5439
  return this.updateShare({
5256
5440
  sendShare: false,
5257
5441
  receiveShare: this.mediaProperties.mediaDirection.receiveShare,
5258
- ...options
5442
+ ...options,
5259
5443
  });
5260
5444
  }
5261
5445
 
@@ -5268,7 +5452,7 @@ export default class Meeting extends StatelessWebexPlugin {
5268
5452
  private releaseScreenShareFloor() {
5269
5453
  const content = this.locusInfo.mediaShares.find((element) => element.name === CONTENT);
5270
5454
 
5271
- if (content && (this.mediaProperties.mediaDirection.sendShare)) {
5455
+ if (content && this.mediaProperties.mediaDirection.sendShare) {
5272
5456
  Metrics.postEvent({event: eventType.SHARE_STOPPED, meeting: this});
5273
5457
  Media.stopTracks(this.mediaProperties.shareTrack);
5274
5458
 
@@ -5279,25 +5463,23 @@ export default class Meeting extends StatelessWebexPlugin {
5279
5463
  return Promise.resolve();
5280
5464
  }
5281
5465
 
5282
- return this.meetingRequest.changeMeetingFloor({
5283
- disposition: FLOOR_ACTION.RELEASED,
5284
- personUrl: this.locusInfo.self.url,
5285
- deviceUrl: this.deviceUrl,
5286
- uri: content.url,
5287
- resourceUrl: this.resourceUrl
5288
- })
5466
+ return this.meetingRequest
5467
+ .changeMeetingFloor({
5468
+ disposition: FLOOR_ACTION.RELEASED,
5469
+ personUrl: this.locusInfo.self.url,
5470
+ deviceUrl: this.deviceUrl,
5471
+ uri: content.url,
5472
+ resourceUrl: this.resourceUrl,
5473
+ })
5289
5474
  .catch((error) => {
5290
5475
  LoggerProxy.logger.error('Meeting:index#releaseScreenShareFloor --> Error ', error);
5291
5476
 
5292
- Metrics.sendBehavioralMetric(
5293
- BEHAVIORAL_METRICS.STOP_FLOOR_REQUEST_FAILURE,
5294
- {
5295
- correlation_id: this.correlationId,
5296
- locus_id: this.locusUrl.split('/').pop(),
5297
- reason: error.message,
5298
- stack: error.stack
5299
- }
5300
- );
5477
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.STOP_FLOOR_REQUEST_FAILURE, {
5478
+ correlation_id: this.correlationId,
5479
+ locus_id: this.locusUrl.split('/').pop(),
5480
+ reason: error.message,
5481
+ stack: error.stack,
5482
+ });
5301
5483
 
5302
5484
  return Promise.reject(error);
5303
5485
  })
@@ -5392,18 +5574,21 @@ export default class Meeting extends StatelessWebexPlugin {
5392
5574
  public sendDTMF(tones: string) {
5393
5575
  if (this.locusInfo && this.locusInfo.self) {
5394
5576
  if (this.locusInfo.self.enableDTMF) {
5395
- return this.meetingRequest
5396
- .sendDTMF({
5397
- locusUrl: this.locusInfo.self.url,
5398
- deviceUrl: this.deviceUrl,
5399
- tones
5400
- });
5577
+ return this.meetingRequest.sendDTMF({
5578
+ locusUrl: this.locusInfo.self.url,
5579
+ deviceUrl: this.deviceUrl,
5580
+ tones,
5581
+ });
5401
5582
  }
5402
5583
 
5403
- return this.rejectWithErrorLog('Meeting:index#sendDTMF --> cannot send DTMF, meeting does not have DTMF enabled');
5584
+ return this.rejectWithErrorLog(
5585
+ 'Meeting:index#sendDTMF --> cannot send DTMF, meeting does not have DTMF enabled'
5586
+ );
5404
5587
  }
5405
5588
 
5406
- return this.rejectWithErrorLog('Meeting:index#sendDTMF --> cannot send DTMF, meeting does not have a connection to the "locus" call control service. Have you joined?');
5589
+ return this.rejectWithErrorLog(
5590
+ 'Meeting:index#sendDTMF --> cannot send DTMF, meeting does not have a connection to the "locus" call control service. Have you joined?'
5591
+ );
5407
5592
  }
5408
5593
 
5409
5594
  /**
@@ -5440,12 +5625,16 @@ export default class Meeting extends StatelessWebexPlugin {
5440
5625
 
5441
5626
  // TODO: We need a real time value for Audio, Video and Share send indicator
5442
5627
  if (mediaDirection.receiveVideo !== true || !remoteVideoTrack) {
5443
- return this.rejectWithErrorLog('Meeting:index#changeVideoLayout --> cannot change video layout, you are not recieving any video/share stream');
5628
+ return this.rejectWithErrorLog(
5629
+ 'Meeting:index#changeVideoLayout --> cannot change video layout, you are not recieving any video/share stream'
5630
+ );
5444
5631
  }
5445
5632
 
5446
5633
  if (layoutType) {
5447
5634
  if (!LAYOUT_TYPES.includes(layoutType)) {
5448
- this.rejectWithErrorLog('Meeting:index#changeVideoLayout --> cannot change video layout, invalid layoutType recieved.');
5635
+ this.rejectWithErrorLog(
5636
+ 'Meeting:index#changeVideoLayout --> cannot change video layout, invalid layoutType recieved.'
5637
+ );
5449
5638
  }
5450
5639
 
5451
5640
  layoutInfo.layoutType = layoutType;
@@ -5471,15 +5660,17 @@ export default class Meeting extends StatelessWebexPlugin {
5471
5660
  const contentHeight = Math.round(content.height);
5472
5661
 
5473
5662
  // Stop any "twitching" caused by very slight size changes
5474
- if (!this.lastVideoLayoutInfo.content ||
5663
+ if (
5664
+ !this.lastVideoLayoutInfo.content ||
5475
5665
  Math.abs(this.lastVideoLayoutInfo.content.height - contentHeight) > 2 ||
5476
5666
  Math.abs(this.lastVideoLayoutInfo.content.width - contentWidth) > 2
5477
5667
  ) {
5478
5668
  layoutInfo.content = {width: contentWidth, height: contentHeight};
5479
5669
  }
5480
- }
5481
- else {
5482
- return this.rejectWithErrorLog('Meeting:index#changeVideoLayout --> unable to send renderInfo for content, you are not receiving remote share');
5670
+ } else {
5671
+ return this.rejectWithErrorLog(
5672
+ 'Meeting:index#changeVideoLayout --> unable to send renderInfo for content, you are not receiving remote share'
5673
+ );
5483
5674
  }
5484
5675
  }
5485
5676
 
@@ -5498,7 +5689,7 @@ export default class Meeting extends StatelessWebexPlugin {
5498
5689
  },
5499
5690
  EVENT_TRIGGERS.MEETING_CONTROLS_LAYOUT_UPDATE,
5500
5691
  {
5501
- layout: envelope.layout
5692
+ layout: envelope.layout,
5502
5693
  }
5503
5694
  );
5504
5695
  });
@@ -5509,7 +5700,7 @@ export default class Meeting extends StatelessWebexPlugin {
5509
5700
  deviceUrl: this.deviceUrl,
5510
5701
  layoutType,
5511
5702
  main: layoutInfo.main,
5512
- content: layoutInfo.content
5703
+ content: layoutInfo.content,
5513
5704
  })
5514
5705
  .then((response) => {
5515
5706
  if (response && response.body && response.body.locus) {
@@ -5536,12 +5727,16 @@ export default class Meeting extends StatelessWebexPlugin {
5536
5727
  }
5537
5728
 
5538
5729
  if (!this.mediaProperties.mediaDirection.sendVideo) {
5539
- return this.rejectWithErrorLog('Meeting:index#setLocalVideoQuality --> unable to change video quality, sendVideo is disabled');
5730
+ return this.rejectWithErrorLog(
5731
+ 'Meeting:index#setLocalVideoQuality --> unable to change video quality, sendVideo is disabled'
5732
+ );
5540
5733
  }
5541
5734
 
5542
5735
  // If level is already the same, don't do anything
5543
5736
  if (level === this.mediaProperties.localQualityLevel) {
5544
- LoggerProxy.logger.warn(`Meeting:index#setLocalQualityLevel --> Quality already set to ${level}`);
5737
+ LoggerProxy.logger.warn(
5738
+ `Meeting:index#setLocalQualityLevel --> Quality already set to ${level}`
5739
+ );
5545
5740
 
5546
5741
  return Promise.resolve();
5547
5742
  }
@@ -5552,25 +5747,27 @@ export default class Meeting extends StatelessWebexPlugin {
5552
5747
  const mediaDirection = {
5553
5748
  sendAudio: this.mediaProperties.mediaDirection.sendAudio,
5554
5749
  sendVideo: this.mediaProperties.mediaDirection.sendVideo,
5555
- sendShare: this.mediaProperties.mediaDirection.sendShare
5750
+ sendShare: this.mediaProperties.mediaDirection.sendShare,
5556
5751
  };
5557
5752
 
5558
5753
  // When changing local video quality level
5559
5754
  // Need to stop current track first as chrome doesn't support resolution upscaling(for eg. changing 480p to 720p)
5560
5755
  // Without feeding it a new track
5561
5756
  // open bug link: https://bugs.chromium.org/p/chromium/issues/detail?id=943469
5562
- if (isBrowser('chrome') && this.mediaProperties.videoTrack) Media.stopTracks(this.mediaProperties.videoTrack);
5757
+ if (isBrowser('chrome') && this.mediaProperties.videoTrack)
5758
+ Media.stopTracks(this.mediaProperties.videoTrack);
5563
5759
 
5564
- return this.getMediaStreams(mediaDirection, VIDEO_RESOLUTIONS[level])
5565
- .then(async ([localStream]) => {
5760
+ return this.getMediaStreams(mediaDirection, VIDEO_RESOLUTIONS[level]).then(
5761
+ async ([localStream]) => {
5566
5762
  await this.updateVideo({
5567
5763
  sendVideo: true,
5568
5764
  receiveVideo: true,
5569
- stream: localStream
5765
+ stream: localStream,
5570
5766
  });
5571
5767
 
5572
5768
  return localStream;
5573
- });
5769
+ }
5770
+ );
5574
5771
  }
5575
5772
 
5576
5773
  /**
@@ -5582,16 +5779,25 @@ export default class Meeting extends StatelessWebexPlugin {
5582
5779
  LoggerProxy.logger.log(`Meeting:index#setRemoteQualityLevel --> Setting quality to ${level}`);
5583
5780
 
5584
5781
  if (!QUALITY_LEVELS[level]) {
5585
- return this.rejectWithErrorLog(`Meeting:index#setRemoteQualityLevel --> ${level} not defined`);
5782
+ return this.rejectWithErrorLog(
5783
+ `Meeting:index#setRemoteQualityLevel --> ${level} not defined`
5784
+ );
5586
5785
  }
5587
5786
 
5588
- if (!this.mediaProperties.mediaDirection.receiveAudio && !this.mediaProperties.mediaDirection.receiveVideo) {
5589
- return this.rejectWithErrorLog('Meeting:index#setRemoteQualityLevel --> unable to change remote quality, receiveVideo and receiveAudio is disabled');
5787
+ if (
5788
+ !this.mediaProperties.mediaDirection.receiveAudio &&
5789
+ !this.mediaProperties.mediaDirection.receiveVideo
5790
+ ) {
5791
+ return this.rejectWithErrorLog(
5792
+ 'Meeting:index#setRemoteQualityLevel --> unable to change remote quality, receiveVideo and receiveAudio is disabled'
5793
+ );
5590
5794
  }
5591
5795
 
5592
5796
  // If level is already the same, don't do anything
5593
5797
  if (level === this.mediaProperties.remoteQualityLevel) {
5594
- LoggerProxy.logger.warn(`Meeting:index#setRemoteQualityLevel --> Quality already set to ${level}`);
5798
+ LoggerProxy.logger.warn(
5799
+ `Meeting:index#setRemoteQualityLevel --> Quality already set to ${level}`
5800
+ );
5595
5801
 
5596
5802
  return Promise.resolve();
5597
5803
  }
@@ -5617,7 +5823,7 @@ export default class Meeting extends StatelessWebexPlugin {
5617
5823
 
5618
5824
  const previousLevel = {
5619
5825
  local: this.mediaProperties.localQualityLevel,
5620
- remote: this.mediaProperties.remoteQualityLevel
5826
+ remote: this.mediaProperties.remoteQualityLevel,
5621
5827
  };
5622
5828
 
5623
5829
  // If level is already the same, don't do anything
@@ -5625,7 +5831,9 @@ export default class Meeting extends StatelessWebexPlugin {
5625
5831
  level === this.mediaProperties.localQualityLevel &&
5626
5832
  level === this.mediaProperties.remoteQualityLevel
5627
5833
  ) {
5628
- LoggerProxy.logger.warn(`Meeting:index#setMeetingQuality --> Quality already set to ${level}`);
5834
+ LoggerProxy.logger.warn(
5835
+ `Meeting:index#setMeetingQuality --> Quality already set to ${level}`
5836
+ );
5629
5837
 
5630
5838
  return Promise.resolve();
5631
5839
  }
@@ -5635,9 +5843,8 @@ export default class Meeting extends StatelessWebexPlugin {
5635
5843
 
5636
5844
  return (sendVideo ? this.setLocalVideoQuality(level) : Promise.resolve())
5637
5845
  .then(() =>
5638
- ((receiveAudio || receiveVideo) ?
5639
- this.setRemoteQualityLevel(level) :
5640
- Promise.resolve()))
5846
+ receiveAudio || receiveVideo ? this.setRemoteQualityLevel(level) : Promise.resolve()
5847
+ )
5641
5848
  .catch((error) => {
5642
5849
  // From troubleshooting it seems that the stream itself doesn't change the max-fs if the peer connection isn't stable
5643
5850
  this.mediaProperties.setLocalQualityLevel(previousLevel.local);
@@ -5651,10 +5858,10 @@ export default class Meeting extends StatelessWebexPlugin {
5651
5858
  correlation_id: this.correlationId,
5652
5859
  locus_id: this.locusUrl.split('/').pop(),
5653
5860
  reason: error.message,
5654
- stack: error.stack
5861
+ stack: error.stack,
5655
5862
  },
5656
5863
  {
5657
- type: error.name
5864
+ type: error.name,
5658
5865
  }
5659
5866
  );
5660
5867
 
@@ -5663,20 +5870,20 @@ export default class Meeting extends StatelessWebexPlugin {
5663
5870
  }
5664
5871
 
5665
5872
  /**
5666
- * @param {Object} options parameter
5667
- * @param {Boolean} options.sendAudio send audio from the display share
5668
- * @param {Boolean} options.sendShare send video from the display share
5669
- * @param {Object} options.sharePreferences
5670
- * @param {MediaTrackConstraints} options.sharePreferences.shareConstraints constraints to apply to video
5671
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints}
5672
- * @param {Boolean} options.sharePreferences.highFrameRate if shareConstraints isn't provided, set default values based off of this boolean
5673
- * @returns {Promise}
5674
- */
5873
+ * @param {Object} options parameter
5874
+ * @param {Boolean} options.sendAudio send audio from the display share
5875
+ * @param {Boolean} options.sendShare send video from the display share
5876
+ * @param {Object} options.sharePreferences
5877
+ * @param {MediaTrackConstraints} options.sharePreferences.shareConstraints constraints to apply to video
5878
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints}
5879
+ * @param {Boolean} options.sharePreferences.highFrameRate if shareConstraints isn't provided, set default values based off of this boolean
5880
+ * @returns {Promise}
5881
+ */
5675
5882
  shareScreen(
5676
5883
  options: {
5677
5884
  sendAudio: boolean;
5678
5885
  sendShare: boolean;
5679
- sharePreferences: { shareConstraints: MediaTrackConstraints };
5886
+ sharePreferences: {shareConstraints: MediaTrackConstraints};
5680
5887
  } = {} as any
5681
5888
  ) {
5682
5889
  LoggerProxy.logger.log('Meeting:index#shareScreen --> Getting local share');
@@ -5684,16 +5891,18 @@ export default class Meeting extends StatelessWebexPlugin {
5684
5891
  const shareConstraints = {
5685
5892
  sendShare: true,
5686
5893
  sendAudio: false,
5687
- ...options
5894
+ ...options,
5688
5895
  };
5689
5896
 
5690
5897
  // @ts-ignore - config coming from registerPlugin
5691
5898
  return Media.getDisplayMedia(shareConstraints, this.config)
5692
- .then((shareStream) => this.updateShare({
5693
- sendShare: true,
5694
- receiveShare: this.mediaProperties.mediaDirection.receiveShare,
5695
- stream: shareStream
5696
- }))
5899
+ .then((shareStream) =>
5900
+ this.updateShare({
5901
+ sendShare: true,
5902
+ receiveShare: this.mediaProperties.mediaDirection.receiveShare,
5903
+ stream: shareStream,
5904
+ })
5905
+ )
5697
5906
  .catch((error) => {
5698
5907
  // Whenever there is a failure when trying to access a user's display
5699
5908
  // report it as an Behavioral metric
@@ -5707,10 +5916,10 @@ export default class Meeting extends StatelessWebexPlugin {
5707
5916
  correlation_id: this.correlationId,
5708
5917
  locus_id: this.locusUrl.split('/').pop(),
5709
5918
  reason: error.message,
5710
- stack: error.stack
5919
+ stack: error.stack,
5711
5920
  };
5712
5921
  const metadata = {
5713
- type: error.name
5922
+ type: error.name,
5714
5923
  };
5715
5924
 
5716
5925
  Metrics.sendBehavioralMetric(metricName, data, metadata);
@@ -5728,28 +5937,29 @@ export default class Meeting extends StatelessWebexPlugin {
5728
5937
  private handleShareTrackEnded(localShare: MediaStream) {
5729
5938
  if (this.wirelessShare) {
5730
5939
  this.leave({reason: MEETING_REMOVED_REASON.USER_ENDED_SHARE_STREAMS});
5731
- }
5732
- else {
5940
+ } else {
5733
5941
  // Skip checking for a stable peerConnection
5734
5942
  // to allow immediately stopping screenshare
5735
5943
  this.stopShare({
5736
- skipSignalingCheck: true
5737
- })
5738
- .catch((error) => {
5739
- LoggerProxy.logger.log('Meeting:index#handleShareTrackEnded --> Error stopping share: ', error);
5740
- });
5944
+ skipSignalingCheck: true,
5945
+ }).catch((error) => {
5946
+ LoggerProxy.logger.log(
5947
+ 'Meeting:index#handleShareTrackEnded --> Error stopping share: ',
5948
+ error
5949
+ );
5950
+ });
5741
5951
  }
5742
5952
 
5743
5953
  Trigger.trigger(
5744
5954
  this,
5745
5955
  {
5746
5956
  file: 'meeting/index',
5747
- function: 'handleShareTrackEnded'
5957
+ function: 'handleShareTrackEnded',
5748
5958
  },
5749
5959
  EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
5750
5960
  {
5751
5961
  type: EVENT_TYPES.LOCAL_SHARE,
5752
- stream: localShare
5962
+ stream: localShare,
5753
5963
  }
5754
5964
  );
5755
5965
  }
@@ -5770,12 +5980,12 @@ export default class Meeting extends StatelessWebexPlugin {
5770
5980
  this,
5771
5981
  {
5772
5982
  file: 'meeting/index',
5773
- function: 'addMedia'
5983
+ function: 'addMedia',
5774
5984
  },
5775
5985
  EVENT_TRIGGERS.NETWORK_QUALITY,
5776
5986
  {
5777
5987
  networkQualityScore: res.networkQualityScore,
5778
- mediaType: res.mediaType
5988
+ mediaType: res.mediaType,
5779
5989
  }
5780
5990
  );
5781
5991
  }
@@ -5787,7 +5997,7 @@ export default class Meeting extends StatelessWebexPlugin {
5787
5997
  * @private
5788
5998
  * @returns {undefined}
5789
5999
  */
5790
- private handleMediaLogging({ audioTrack, videoTrack }: any) {
6000
+ private handleMediaLogging({audioTrack, videoTrack}: any) {
5791
6001
  MeetingUtil.handleVideoLogging(videoTrack);
5792
6002
  MeetingUtil.handleAudioLogging(audioTrack);
5793
6003
  }
@@ -5817,7 +6027,7 @@ export default class Meeting extends StatelessWebexPlugin {
5817
6027
  const start = this[`startSetupDelay${typeMedia}`];
5818
6028
  const end = this[`endSetupDelay${typeMedia}`];
5819
6029
 
5820
- return (start && end) ? end - start : undefined;
6030
+ return start && end ? end - start : undefined;
5821
6031
  }
5822
6032
 
5823
6033
  /**
@@ -5845,14 +6055,14 @@ export default class Meeting extends StatelessWebexPlugin {
5845
6055
  const start = this[`startSendingMediaDelay${typeMedia}`];
5846
6056
  const end = this[`endSendingMediaDelay${typeMedia}`];
5847
6057
 
5848
- return (start && end) ? end - start : undefined;
6058
+ return start && end ? end - start : undefined;
5849
6059
  }
5850
6060
 
5851
6061
  /**
5852
6062
  *
5853
6063
  * @returns {undefined}
5854
6064
  */
5855
- setStartLocalSDPGenRemoteSDPRecvDelay() {
6065
+ setStartLocalSDPGenRemoteSDPRecvDelay() {
5856
6066
  if (!this.startLocalSDPGenRemoteSDPRecvDelay) {
5857
6067
  this.startLocalSDPGenRemoteSDPRecvDelay = performance.now();
5858
6068
  this.endLocalSDPGenRemoteSDPRecvDelay = undefined;
@@ -5880,9 +6090,7 @@ export default class Meeting extends StatelessWebexPlugin {
5880
6090
  if (start && end) {
5881
6091
  const calculatedDelay = end - start;
5882
6092
 
5883
- return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
5884
- undefined :
5885
- calculatedDelay;
6093
+ return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
5886
6094
  }
5887
6095
 
5888
6096
  return undefined;
@@ -5916,9 +6124,7 @@ export default class Meeting extends StatelessWebexPlugin {
5916
6124
  if (start && end) {
5917
6125
  const calculatedDelay = end - start;
5918
6126
 
5919
- return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
5920
- undefined :
5921
- calculatedDelay;
6127
+ return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
5922
6128
  }
5923
6129
 
5924
6130
  return undefined;
@@ -5952,9 +6158,7 @@ export default class Meeting extends StatelessWebexPlugin {
5952
6158
  if (start && end) {
5953
6159
  const calculatedDelay = end - start;
5954
6160
 
5955
- return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
5956
- undefined :
5957
- calculatedDelay;
6161
+ return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
5958
6162
  }
5959
6163
 
5960
6164
  return undefined;
@@ -5968,10 +6172,9 @@ export default class Meeting extends StatelessWebexPlugin {
5968
6172
  const start = this.startCallInitiateJoinReq;
5969
6173
  const end = this.endJoinReqResp;
5970
6174
 
5971
- return (start && end) ? end - start : undefined;
6175
+ return start && end ? end - start : undefined;
5972
6176
  }
5973
6177
 
5974
-
5975
6178
  /**
5976
6179
  * End the current meeting for all
5977
6180
  * @returns {Promise}
@@ -5979,16 +6182,17 @@ export default class Meeting extends StatelessWebexPlugin {
5979
6182
  * @memberof Meeting
5980
6183
  */
5981
6184
  public endMeetingForAll() {
5982
- Metrics.postEvent({event: eventType.LEAVE, meeting: this, data: {trigger: trigger.USER_INTERACTION, canProceed: false}});
6185
+ Metrics.postEvent({
6186
+ event: eventType.LEAVE,
6187
+ meeting: this,
6188
+ data: {trigger: trigger.USER_INTERACTION, canProceed: false},
6189
+ });
5983
6190
 
5984
6191
  LoggerProxy.logger.log('Meeting:index#endMeetingForAll --> End meeting for All');
5985
- Metrics.sendBehavioralMetric(
5986
- BEHAVIORAL_METRICS.MEETING_END_ALL_INITIATED,
5987
- {
5988
- correlation_id: this.correlationId,
5989
- locus_id: this.locusId
5990
- }
5991
- );
6192
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_END_ALL_INITIATED, {
6193
+ correlation_id: this.correlationId,
6194
+ locus_id: this.locusId,
6195
+ });
5992
6196
 
5993
6197
  return MeetingUtil.endMeetingForAll(this)
5994
6198
  .then((end) => {
@@ -6000,36 +6204,37 @@ export default class Meeting extends StatelessWebexPlugin {
6000
6204
  this,
6001
6205
  {
6002
6206
  file: 'meeting/index',
6003
- function: 'endMeetingForAll'
6207
+ function: 'endMeetingForAll',
6004
6208
  },
6005
6209
  EVENTS.REQUEST_UPLOAD_LOGS,
6006
6210
  this
6007
6211
  );
6008
6212
 
6009
6213
  return end;
6010
- }).catch((error) => {
6214
+ })
6215
+ .catch((error) => {
6011
6216
  this.meetingFiniteStateMachine.fail(error);
6012
- LoggerProxy.logger.error('Meeting:index#endMeetingForAll --> Failed to end meeting ', error);
6217
+ LoggerProxy.logger.error(
6218
+ 'Meeting:index#endMeetingForAll --> Failed to end meeting ',
6219
+ error
6220
+ );
6013
6221
  // upload logs on leave irrespective of meeting delete
6014
6222
  Trigger.trigger(
6015
6223
  this,
6016
6224
  {
6017
6225
  file: 'meeting/index',
6018
- function: 'endMeetingForAll'
6226
+ function: 'endMeetingForAll',
6019
6227
  },
6020
6228
  EVENTS.REQUEST_UPLOAD_LOGS,
6021
6229
  this
6022
6230
  );
6023
- Metrics.sendBehavioralMetric(
6024
- BEHAVIORAL_METRICS.MEETING_END_ALL_FAILURE,
6025
- {
6026
- correlation_id: this.correlationId,
6027
- locus_id: this.locusUrl.split('/').pop(),
6028
- reason: error.message,
6029
- stack: error.stack,
6030
- code: error.code
6031
- }
6032
- );
6231
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_END_ALL_FAILURE, {
6232
+ correlation_id: this.correlationId,
6233
+ locus_id: this.locusUrl.split('/').pop(),
6234
+ reason: error.message,
6235
+ stack: error.stack,
6236
+ code: error.code,
6237
+ });
6033
6238
 
6034
6239
  return Promise.reject(error);
6035
6240
  });
@@ -6079,11 +6284,12 @@ export default class Meeting extends StatelessWebexPlugin {
6079
6284
  LoggerProxy.logger.info('Meeting:index#internal_enableBNR. Internal enable BNR called');
6080
6285
  const bnrAudioTrack = await WebRTCMedia.Effects.BNR.enableBNR(audioTrack);
6081
6286
 
6082
- LoggerProxy.logger.info('Meeting:index#internal_enableBNR. BNR enabled track obtained from WebRTC & returned as stream');
6287
+ LoggerProxy.logger.info(
6288
+ 'Meeting:index#internal_enableBNR. BNR enabled track obtained from WebRTC & returned as stream'
6289
+ );
6083
6290
 
6084
6291
  return bnrAudioTrack;
6085
- }
6086
- catch (error) {
6292
+ } catch (error) {
6087
6293
  LoggerProxy.logger.error('Meeting:index#internal_enableBNR.', error);
6088
6294
  throw error;
6089
6295
  }
@@ -6096,7 +6302,10 @@ export default class Meeting extends StatelessWebexPlugin {
6096
6302
  * @memberof Meeting
6097
6303
  */
6098
6304
  public enableBNR() {
6099
- if (typeof this.mediaProperties === 'undefined' || typeof this.mediaProperties.audioTrack === 'undefined') {
6305
+ if (
6306
+ typeof this.mediaProperties === 'undefined' ||
6307
+ typeof this.mediaProperties.audioTrack === 'undefined'
6308
+ ) {
6100
6309
  return Promise.reject(new Error("Meeting doesn't have an audioTrack attached"));
6101
6310
  }
6102
6311
 
@@ -6108,20 +6317,23 @@ export default class Meeting extends StatelessWebexPlugin {
6108
6317
 
6109
6318
  const LOG_HEADER = 'Meeting:index#enableBNR -->';
6110
6319
 
6111
- return logRequest(this.effects.handleClientRequest(true, this)
6112
- .then((res) => {
6113
- LoggerProxy.logger.info('Meeting:index#enableBNR. Enable bnr completed');
6320
+ return logRequest(
6321
+ this.effects
6322
+ .handleClientRequest(true, this)
6323
+ .then((res) => {
6324
+ LoggerProxy.logger.info('Meeting:index#enableBNR. Enable bnr completed');
6114
6325
 
6115
- return res;
6116
- })
6117
- .catch((error) => {
6118
- throw error;
6119
- }),
6120
- {
6121
- header: `${LOG_HEADER} enable bnr`,
6122
- success: `${LOG_HEADER} enable bnr success`,
6123
- failure: `${LOG_HEADER} enable bnr failure, `
6124
- });
6326
+ return res;
6327
+ })
6328
+ .catch((error) => {
6329
+ throw error;
6330
+ }),
6331
+ {
6332
+ header: `${LOG_HEADER} enable bnr`,
6333
+ success: `${LOG_HEADER} enable bnr success`,
6334
+ failure: `${LOG_HEADER} enable bnr failure, `,
6335
+ }
6336
+ );
6125
6337
  }
6126
6338
 
6127
6339
  /**
@@ -6131,7 +6343,10 @@ export default class Meeting extends StatelessWebexPlugin {
6131
6343
  * @memberof Meeting
6132
6344
  */
6133
6345
  public disableBNR() {
6134
- if (typeof this.mediaProperties === 'undefined' || typeof this.mediaProperties.audioTrack === 'undefined') {
6346
+ if (
6347
+ typeof this.mediaProperties === 'undefined' ||
6348
+ typeof this.mediaProperties.audioTrack === 'undefined'
6349
+ ) {
6135
6350
  return Promise.reject(new Error("Meeting doesn't have an audioTrack attached"));
6136
6351
  }
6137
6352
 
@@ -6143,20 +6358,23 @@ export default class Meeting extends StatelessWebexPlugin {
6143
6358
 
6144
6359
  const LOG_HEADER = 'Meeting:index#disableBNR -->';
6145
6360
 
6146
- return logRequest(this.effects.handleClientRequest(false, this)
6147
- .then((res) => {
6148
- LoggerProxy.logger.info('Meeting:index#disableBNR. Disable bnr completed');
6361
+ return logRequest(
6362
+ this.effects
6363
+ .handleClientRequest(false, this)
6364
+ .then((res) => {
6365
+ LoggerProxy.logger.info('Meeting:index#disableBNR. Disable bnr completed');
6149
6366
 
6150
- return res;
6151
- })
6152
- .catch((error) => {
6153
- throw error;
6154
- }),
6155
- {
6156
- header: `${LOG_HEADER} disable bnr`,
6157
- success: `${LOG_HEADER} disable bnr success`,
6158
- failure: `${LOG_HEADER} disable bnr failure, `
6159
- });
6367
+ return res;
6368
+ })
6369
+ .catch((error) => {
6370
+ throw error;
6371
+ }),
6372
+ {
6373
+ header: `${LOG_HEADER} disable bnr`,
6374
+ success: `${LOG_HEADER} disable bnr success`,
6375
+ failure: `${LOG_HEADER} disable bnr failure, `,
6376
+ }
6377
+ );
6160
6378
  }
6161
6379
 
6162
6380
  /**
@@ -6167,22 +6385,30 @@ export default class Meeting extends StatelessWebexPlugin {
6167
6385
  */
6168
6386
  startKeepAlive = () => {
6169
6387
  if (this.keepAliveTimerId) {
6170
- LoggerProxy.logger.warn('Meeting:index#startKeepAlive --> keepAlive not started: keepAliveTimerId already exists');
6388
+ LoggerProxy.logger.warn(
6389
+ 'Meeting:index#startKeepAlive --> keepAlive not started: keepAliveTimerId already exists'
6390
+ );
6171
6391
 
6172
6392
  return;
6173
6393
  }
6174
6394
  if (!this.joinedWith?.keepAliveUrl) {
6175
- LoggerProxy.logger.warn('Meeting:index#startKeepAlive --> keepAlive not started: no keepAliveUrl');
6395
+ LoggerProxy.logger.warn(
6396
+ 'Meeting:index#startKeepAlive --> keepAlive not started: no keepAliveUrl'
6397
+ );
6176
6398
 
6177
6399
  return;
6178
6400
  }
6179
6401
  if (!this.joinedWith?.keepAliveSecs) {
6180
- LoggerProxy.logger.warn('Meeting:index#startKeepAlive --> keepAlive not started: no keepAliveSecs');
6402
+ LoggerProxy.logger.warn(
6403
+ 'Meeting:index#startKeepAlive --> keepAlive not started: no keepAliveSecs'
6404
+ );
6181
6405
 
6182
6406
  return;
6183
6407
  }
6184
6408
  if (this.joinedWith.keepAliveSecs <= 1) {
6185
- LoggerProxy.logger.warn('Meeting:index#startKeepAlive --> keepAlive not started: keepAliveSecs <= 1');
6409
+ LoggerProxy.logger.warn(
6410
+ 'Meeting:index#startKeepAlive --> keepAlive not started: keepAliveSecs <= 1'
6411
+ );
6186
6412
 
6187
6413
  return;
6188
6414
  }
@@ -6190,13 +6416,12 @@ export default class Meeting extends StatelessWebexPlugin {
6190
6416
  const keepAliveInterval = (this.joinedWith.keepAliveSecs - 1) * 750; // taken from UCF
6191
6417
 
6192
6418
  this.keepAliveTimerId = setInterval(() => {
6193
- this.meetingRequest.keepAlive({keepAliveUrl})
6194
- .catch((error) => {
6195
- LoggerProxy.logger.warn(
6196
- `Meeting:index#startKeepAlive --> Stopping sending keepAlives to ${keepAliveUrl} after error ${error}`
6197
- );
6198
- this.stopKeepAlive();
6199
- });
6419
+ this.meetingRequest.keepAlive({keepAliveUrl}).catch((error) => {
6420
+ LoggerProxy.logger.warn(
6421
+ `Meeting:index#startKeepAlive --> Stopping sending keepAlives to ${keepAliveUrl} after error ${error}`
6422
+ );
6423
+ this.stopKeepAlive();
6424
+ });
6200
6425
  }, keepAliveInterval);
6201
6426
  };
6202
6427
 
@@ -6235,7 +6460,7 @@ export default class Meeting extends StatelessWebexPlugin {
6235
6460
  const skinToneData = SkinTones[skinToneType] || SkinTones.normal;
6236
6461
  const reaction: Reaction = {
6237
6462
  ...reactionData,
6238
- tone: skinToneData
6463
+ tone: skinToneData,
6239
6464
  };
6240
6465
 
6241
6466
  if (reactionChannelUrl) {