@webex/plugin-meetings 2.35.3 → 2.36.0

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 (220) hide show
  1. package/dist/common/browser-detection.js.map +1 -1
  2. package/dist/common/collection.js.map +1 -1
  3. package/dist/common/config.js.map +1 -1
  4. package/dist/common/errors/captcha-error.js +7 -0
  5. package/dist/common/errors/captcha-error.js.map +1 -1
  6. package/dist/common/errors/intent-to-join.js +8 -0
  7. package/dist/common/errors/intent-to-join.js.map +1 -1
  8. package/dist/common/errors/join-meeting.js +8 -0
  9. package/dist/common/errors/join-meeting.js.map +1 -1
  10. package/dist/common/errors/media.js +7 -0
  11. package/dist/common/errors/media.js.map +1 -1
  12. package/dist/common/errors/parameter.js.map +1 -1
  13. package/dist/common/errors/password-error.js +7 -0
  14. package/dist/common/errors/password-error.js.map +1 -1
  15. package/dist/common/errors/permission.js +7 -0
  16. package/dist/common/errors/permission.js.map +1 -1
  17. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  18. package/dist/common/errors/reconnection.js +7 -0
  19. package/dist/common/errors/reconnection.js.map +1 -1
  20. package/dist/common/errors/stats.js +7 -0
  21. package/dist/common/errors/stats.js.map +1 -1
  22. package/dist/common/errors/webex-errors.js.map +1 -1
  23. package/dist/common/errors/webex-meetings-error.js +5 -2
  24. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  25. package/dist/common/events/events-scope.js.map +1 -1
  26. package/dist/common/events/events.js.map +1 -1
  27. package/dist/common/events/trigger-proxy.js.map +1 -1
  28. package/dist/common/events/util.js.map +1 -1
  29. package/dist/common/logs/logger-config.js.map +1 -1
  30. package/dist/common/logs/logger-proxy.js.map +1 -1
  31. package/dist/common/logs/request.js +3 -0
  32. package/dist/common/logs/request.js.map +1 -1
  33. package/dist/common/queue.js.map +1 -1
  34. package/dist/config.js.map +1 -1
  35. package/dist/constants.js.map +1 -1
  36. package/dist/locus-info/controlsUtils.js.map +1 -1
  37. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  38. package/dist/locus-info/fullState.js.map +1 -1
  39. package/dist/locus-info/hostUtils.js.map +1 -1
  40. package/dist/locus-info/index.js +43 -5
  41. package/dist/locus-info/index.js.map +1 -1
  42. package/dist/locus-info/infoUtils.js.map +1 -1
  43. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  44. package/dist/locus-info/parser.js +12 -3
  45. package/dist/locus-info/parser.js.map +1 -1
  46. package/dist/locus-info/selfUtils.js.map +1 -1
  47. package/dist/media/index.js.map +1 -1
  48. package/dist/media/properties.js +12 -0
  49. package/dist/media/properties.js.map +1 -1
  50. package/dist/media/util.js.map +1 -1
  51. package/dist/mediaQualityMetrics/config.js.map +1 -1
  52. package/dist/meeting/effectsState.js +8 -1
  53. package/dist/meeting/effectsState.js.map +1 -1
  54. package/dist/meeting/index.js +206 -46
  55. package/dist/meeting/index.js.map +1 -1
  56. package/dist/meeting/muteState.js +6 -0
  57. package/dist/meeting/muteState.js.map +1 -1
  58. package/dist/meeting/request.js +82 -24
  59. package/dist/meeting/request.js.map +1 -1
  60. package/dist/meeting/state.js.map +1 -1
  61. package/dist/meeting/util.js.map +1 -1
  62. package/dist/meeting-info/collection.js +4 -1
  63. package/dist/meeting-info/collection.js.map +1 -1
  64. package/dist/meeting-info/index.js +5 -0
  65. package/dist/meeting-info/index.js.map +1 -1
  66. package/dist/meeting-info/meeting-info-v2.js +14 -2
  67. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  68. package/dist/meeting-info/request.js +3 -0
  69. package/dist/meeting-info/request.js.map +1 -1
  70. package/dist/meeting-info/util.js.map +1 -1
  71. package/dist/meeting-info/utilv2.js.map +1 -1
  72. package/dist/meetings/collection.js +4 -1
  73. package/dist/meetings/collection.js.map +1 -1
  74. package/dist/meetings/index.js +72 -20
  75. package/dist/meetings/index.js.map +1 -1
  76. package/dist/meetings/request.js +4 -0
  77. package/dist/meetings/request.js.map +1 -1
  78. package/dist/meetings/util.js.map +1 -1
  79. package/dist/member/index.js +30 -7
  80. package/dist/member/index.js.map +1 -1
  81. package/dist/member/util.js +2 -1
  82. package/dist/member/util.js.map +1 -1
  83. package/dist/members/collection.js +1 -0
  84. package/dist/members/collection.js.map +1 -1
  85. package/dist/members/index.js +12 -1
  86. package/dist/members/index.js.map +1 -1
  87. package/dist/members/request.js +19 -9
  88. package/dist/members/request.js.map +1 -1
  89. package/dist/members/util.js.map +1 -1
  90. package/dist/metrics/config.js.map +1 -1
  91. package/dist/metrics/constants.js.map +1 -1
  92. package/dist/metrics/index.js +8 -0
  93. package/dist/metrics/index.js.map +1 -1
  94. package/dist/networkQualityMonitor/index.js +10 -2
  95. package/dist/networkQualityMonitor/index.js.map +1 -1
  96. package/dist/peer-connection-manager/index.js +11 -4
  97. package/dist/peer-connection-manager/index.js.map +1 -1
  98. package/dist/personal-meeting-room/index.js +11 -0
  99. package/dist/personal-meeting-room/index.js.map +1 -1
  100. package/dist/personal-meeting-room/request.js +2 -1
  101. package/dist/personal-meeting-room/request.js.map +1 -1
  102. package/dist/personal-meeting-room/util.js.map +1 -1
  103. package/dist/reachability/index.js +17 -7
  104. package/dist/reachability/index.js.map +1 -1
  105. package/dist/reachability/request.js +1 -0
  106. package/dist/reachability/request.js.map +1 -1
  107. package/dist/reactions/reactions.js +111 -0
  108. package/dist/reactions/reactions.js.map +1 -0
  109. package/dist/reactions/reactions.type.js +40 -0
  110. package/dist/reactions/reactions.type.js.map +1 -0
  111. package/dist/reconnection-manager/index.js +21 -2
  112. package/dist/reconnection-manager/index.js.map +1 -1
  113. package/dist/roap/collection.js +1 -0
  114. package/dist/roap/collection.js.map +1 -1
  115. package/dist/roap/handler.js +14 -2
  116. package/dist/roap/handler.js.map +1 -1
  117. package/dist/roap/index.js +11 -1
  118. package/dist/roap/index.js.map +1 -1
  119. package/dist/roap/request.js +7 -2
  120. package/dist/roap/request.js.map +1 -1
  121. package/dist/roap/state.js.map +1 -1
  122. package/dist/roap/turnDiscovery.js +9 -1
  123. package/dist/roap/turnDiscovery.js.map +1 -1
  124. package/dist/roap/util.js.map +1 -1
  125. package/dist/statsAnalyzer/global.js.map +1 -1
  126. package/dist/statsAnalyzer/index.js +19 -1
  127. package/dist/statsAnalyzer/index.js.map +1 -1
  128. package/dist/statsAnalyzer/mqaUtil.js +9 -3
  129. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  130. package/dist/transcription/index.js +10 -3
  131. package/dist/transcription/index.js.map +1 -1
  132. package/package.json +17 -17
  133. package/src/common/{browser-detection.js → browser-detection.ts} +1 -1
  134. package/src/common/collection.ts +6 -6
  135. package/src/common/{config.js → config.ts} +1 -1
  136. package/src/common/errors/{captcha-error.js → captcha-error.ts} +5 -1
  137. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +6 -1
  138. package/src/common/errors/{join-meeting.js → join-meeting.ts} +6 -1
  139. package/src/common/errors/{media.js → media.ts} +5 -1
  140. package/src/common/errors/parameter.ts +3 -2
  141. package/src/common/errors/{password-error.js → password-error.ts} +5 -1
  142. package/src/common/errors/{permission.js → permission.ts} +5 -1
  143. package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
  144. package/src/common/errors/{reconnection.js → reconnection.ts} +5 -1
  145. package/src/common/errors/{stats.js → stats.ts} +5 -1
  146. package/src/common/errors/{webex-errors.js → webex-errors.ts} +1 -2
  147. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +3 -1
  148. package/src/common/events/{events-scope.js → events-scope.ts} +1 -1
  149. package/src/common/events/{events.js → events.ts} +0 -0
  150. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +1 -2
  151. package/src/common/events/{util.js → util.ts} +1 -1
  152. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  153. package/src/common/logs/{logger-proxy.js → logger-proxy.ts} +1 -1
  154. package/src/common/logs/{request.js → request.ts} +12 -2
  155. package/src/common/queue.ts +1 -2
  156. package/src/{config.js → config.ts} +1 -0
  157. package/src/constants.ts +1 -0
  158. package/src/locus-info/{controlsUtils.js → controlsUtils.ts} +4 -4
  159. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  160. package/src/locus-info/{fullState.js → fullState.ts} +1 -1
  161. package/src/locus-info/{hostUtils.js → hostUtils.ts} +5 -5
  162. package/src/locus-info/{index.js → index.ts} +67 -32
  163. package/src/locus-info/{infoUtils.js → infoUtils.ts} +3 -4
  164. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +13 -13
  165. package/src/locus-info/{parser.js → parser.ts} +22 -12
  166. package/src/locus-info/{selfUtils.js → selfUtils.ts} +17 -19
  167. package/src/media/{index.js → index.ts} +108 -39
  168. package/src/media/{properties.js → properties.ts} +16 -4
  169. package/src/media/{util.js → util.ts} +2 -3
  170. package/src/mediaQualityMetrics/{config.js → config.ts} +1 -1
  171. package/src/meeting/{effectsState.js → effectsState.ts} +12 -6
  172. package/src/meeting/{index.js → index.ts} +365 -157
  173. package/src/meeting/{muteState.js → muteState.ts} +16 -11
  174. package/src/meeting/{request.js → request.ts} +147 -36
  175. package/src/meeting/{state.js → state.ts} +6 -6
  176. package/src/meeting/{util.js → util.ts} +4 -4
  177. package/src/meeting-info/{collection.js → collection.ts} +4 -1
  178. package/src/meeting-info/{index.js → index.ts} +10 -6
  179. package/src/meeting-info/{meeting-info-v2.js → meeting-info-v2.ts} +28 -10
  180. package/src/meeting-info/{request.js → request.ts} +6 -2
  181. package/src/meeting-info/{util.js → util.ts} +6 -5
  182. package/src/meeting-info/{utilv2.js → utilv2.ts} +8 -7
  183. package/src/meetings/{collection.js → collection.ts} +5 -2
  184. package/src/meetings/{index.js → index.ts} +88 -22
  185. package/src/meetings/{request.js → request.ts} +6 -1
  186. package/src/meetings/{util.js → util.ts} +5 -3
  187. package/src/member/{index.js → index.ts} +46 -15
  188. package/src/member/{util.js → util.ts} +17 -16
  189. package/src/members/{collection.js → collection.ts} +2 -1
  190. package/src/members/{index.js → index.ts} +39 -26
  191. package/src/members/{request.js → request.ts} +16 -5
  192. package/src/members/{util.js → util.ts} +7 -7
  193. package/src/metrics/{config.js → config.ts} +0 -2
  194. package/src/metrics/{constants.js → constants.ts} +0 -0
  195. package/src/metrics/{index.js → index.ts} +27 -8
  196. package/src/networkQualityMonitor/{index.js → index.ts} +18 -3
  197. package/src/peer-connection-manager/{index.js → index.ts} +72 -28
  198. package/src/personal-meeting-room/{index.js → index.ts} +17 -4
  199. package/src/personal-meeting-room/{request.js → request.ts} +3 -1
  200. package/src/personal-meeting-room/{util.js → util.ts} +1 -1
  201. package/src/reachability/{index.js → index.ts} +28 -17
  202. package/src/reachability/request.ts +4 -2
  203. package/src/reactions/reactions.ts +104 -0
  204. package/src/reactions/reactions.type.ts +36 -0
  205. package/src/reconnection-manager/{index.js → index.ts} +42 -13
  206. package/src/roap/{collection.js → collection.ts} +1 -0
  207. package/src/roap/{handler.js → handler.ts} +15 -4
  208. package/src/roap/{index.js → index.ts} +23 -10
  209. package/src/roap/{request.js → request.ts} +19 -3
  210. package/src/roap/{state.js → state.ts} +3 -2
  211. package/src/roap/turnDiscovery.ts +14 -5
  212. package/src/roap/{util.js → util.ts} +1 -2
  213. package/src/statsAnalyzer/{global.js → global.ts} +0 -0
  214. package/src/statsAnalyzer/{index.js → index.ts} +36 -17
  215. package/src/statsAnalyzer/{mqaUtil.js → mqaUtil.ts} +6 -1
  216. package/src/transcription/{index.js → index.ts} +16 -11
  217. package/test/integration/spec/space-meeting.js +1 -2
  218. package/test/unit/spec/meeting/index.js +113 -14
  219. package/test/unit/spec/meeting/request.js +25 -1
  220. package/test/unit/spec/roap/util.js +1 -1
@@ -1,3 +1,4 @@
1
+ // @ts-ignore - Types not available for @webex/common
1
2
  import {Defer} from '@webex/common';
2
3
 
3
4
  import Metrics from '../metrics';
@@ -6,6 +7,7 @@ import LoggerProxy from '../common/logs/logger-proxy';
6
7
  import {ROAP} from '../constants';
7
8
 
8
9
  import RoapRequest from './request';
10
+ import Meeting from '../meeting';
9
11
 
10
12
  const TURN_DISCOVERY_TIMEOUT = 10; // in seconds
11
13
 
@@ -48,7 +50,7 @@ export default class TurnDiscovery {
48
50
  * @private
49
51
  * @memberof Roap
50
52
  */
51
- waitForTurnDiscoveryResponse() {
53
+ private waitForTurnDiscoveryResponse() {
52
54
  if (!this.defer) {
53
55
  LoggerProxy.logger.warn('Roap:turnDiscovery#waitForTurnDiscoveryResponse --> TURN discovery is not in progress');
54
56
 
@@ -76,7 +78,8 @@ export default class TurnDiscovery {
76
78
  * @public
77
79
  * @memberof Roap
78
80
  */
79
- handleTurnDiscoveryResponse(roapMessage) {
81
+ public handleTurnDiscoveryResponse(roapMessage: object) {
82
+ // @ts-ignore - Fix missing type
80
83
  const {headers} = roapMessage;
81
84
 
82
85
  if (!this.defer) {
@@ -125,7 +128,7 @@ export default class TurnDiscovery {
125
128
  * @private
126
129
  * @memberof Roap
127
130
  */
128
- sendRoapTurnDiscoveryRequest(meeting, isReconnecting) {
131
+ private sendRoapTurnDiscoveryRequest(meeting: Meeting, isReconnecting: boolean) {
129
132
  const seq = meeting.roapSeq + 1;
130
133
 
131
134
  if (this.defer) {
@@ -148,7 +151,9 @@ export default class TurnDiscovery {
148
151
  .sendRoap({
149
152
  roapMessage,
150
153
  correlationId: meeting.correlationId,
154
+ // @ts-ignore - Fix missing type
151
155
  locusSelfUrl: meeting.selfUrl,
156
+ // @ts-ignore - Fix missing type
152
157
  mediaId: isReconnecting ? '' : meeting.mediaId,
153
158
  audioMuted: meeting.isAudioMuted(),
154
159
  videoMuted: meeting.isVideoMuted(),
@@ -170,7 +175,7 @@ export default class TurnDiscovery {
170
175
  * @param {Meeting} meeting
171
176
  * @returns {Promise}
172
177
  */
173
- sendRoapOK(meeting) {
178
+ sendRoapOK(meeting: Meeting) {
174
179
  LoggerProxy.logger.info('Roap:turnDiscovery#sendRoapOK --> sending OK');
175
180
 
176
181
  return this.roapRequest.sendRoap({
@@ -179,7 +184,9 @@ export default class TurnDiscovery {
179
184
  version: ROAP.ROAP_VERSION,
180
185
  seq: meeting.roapSeq
181
186
  },
187
+ // @ts-ignore - fix type
182
188
  locusSelfUrl: meeting.selfUrl,
189
+ // @ts-ignore - fix type
183
190
  mediaId: meeting.mediaId,
184
191
  correlationId: meeting.correlationId,
185
192
  audioMuted: meeting.isAudioMuted(),
@@ -201,7 +208,8 @@ export default class TurnDiscovery {
201
208
  * media connection just after a reconnection
202
209
  * @returns {Promise}
203
210
  */
204
- doTurnDiscovery(meeting, isReconnecting) {
211
+ doTurnDiscovery(meeting: Meeting, isReconnecting: boolean) {
212
+ // @ts-ignore - fix type
205
213
  const isAnyClusterReachable = meeting.webex.meetings.reachability.isAnyClusterReachable();
206
214
 
207
215
  if (isAnyClusterReachable) {
@@ -209,6 +217,7 @@ export default class TurnDiscovery {
209
217
  return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: 'reachability'});
210
218
  }
211
219
 
220
+ // @ts-ignore - fix type
212
221
  if (!meeting.config.experimental.enableTurnDiscovery) {
213
222
  LoggerProxy.logger.info('Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it');
214
223
 
@@ -1,4 +1,3 @@
1
-
2
1
  import PeerConnectionManager from '../peer-connection-manager';
3
2
  import {
4
3
  _ANSWER_,
@@ -10,7 +9,7 @@ import {
10
9
  import LoggerProxy from '../common/logs/logger-proxy';
11
10
  import ParameterError from '../common/errors/parameter';
12
11
 
13
- const RoapUtil = {};
12
+ const RoapUtil: any = {};
14
13
  const ROAP_ANSWER = _ANSWER_.toLowerCase();
15
14
 
16
15
  RoapUtil.shouldHandleMedia = (meeting) => {
File without changes
@@ -29,6 +29,21 @@ export const EVENTS = {
29
29
  * @extends {EventsScope}
30
30
  */
31
31
  export class StatsAnalyzer extends EventsScope {
32
+ config: any;
33
+ correlationId: any;
34
+ lastEmittedStartStopEvent: any;
35
+ lastMqaDataSent: any;
36
+ lastStatsResults: any;
37
+ localMQEStats: any;
38
+ meetingMediaStatus: any;
39
+ mqaInterval: NodeJS.Timeout;
40
+ mqaSentCount: any;
41
+ networkQualityMonitor: any;
42
+ peerConnection: any;
43
+ statsInterval: NodeJS.Timeout;
44
+ statsResults: any;
45
+ statsStarted: any;
46
+
32
47
  /**
33
48
  * Creates a new instance of StatsAnalyzer
34
49
  * @constructor
@@ -37,7 +52,7 @@ export class StatsAnalyzer extends EventsScope {
37
52
  * @param {Object} networkQualityMonitor class for assessing network characteristics (jitter, packetLoss, latency)
38
53
  * @param {Object} statsResults Default properties for stats
39
54
  */
40
- constructor(config, networkQualityMonitor = {}, statsResults = defaultStats) {
55
+ constructor(config: any, networkQualityMonitor: object = {}, statsResults: object = defaultStats) {
41
56
  super();
42
57
  this.statsStarted = false;
43
58
  this.statsResults = statsResults;
@@ -170,7 +185,7 @@ export class StatsAnalyzer extends EventsScope {
170
185
  * @memberof StatsAnalyzer
171
186
  * @returns {void}
172
187
  */
173
- updateMediaStatus(status) {
188
+ public updateMediaStatus(status: object) {
174
189
  this.meetingMediaStatus = status;
175
190
  }
176
191
 
@@ -181,7 +196,7 @@ export class StatsAnalyzer extends EventsScope {
181
196
  * @memberof StatsAnalyzer
182
197
  * @returns {void}
183
198
  */
184
- sendMqaData() {
199
+ public sendMqaData() {
185
200
  const audioReceiver = mqaData.intervals[0].audioReceive[0];
186
201
  const audioSender = mqaData.intervals[0].audioTransmit[0];
187
202
  const videoReceiver = mqaData.intervals[0].videoReceive[0];
@@ -236,6 +251,7 @@ export class StatsAnalyzer extends EventsScope {
236
251
  mqaData.intervals[0].intervalMetadata.peripherals.push({information: this.peerConnection?.videoTransceiver?.sender?.track?.label || _UNKNOWN_, name: MEDIA_DEVICES.CAMERA});
237
252
 
238
253
 
254
+ // @ts-ignore
239
255
  mqaData.networkType = this.statsResults.connectionType.local.networkType;
240
256
 
241
257
  this.mqaSentCount += 1;
@@ -257,6 +273,7 @@ export class StatsAnalyzer extends EventsScope {
257
273
  EVENTS.MEDIA_QUALITY,
258
274
  {
259
275
  data: mqaData.intervals[0],
276
+ // @ts-ignore
260
277
  networkType: mqaData.networkType
261
278
  }
262
279
  );
@@ -270,7 +287,7 @@ export class StatsAnalyzer extends EventsScope {
270
287
  * @param {PeerConnection} peerConnection
271
288
  * @returns {void}
272
289
  */
273
- updatePeerconnection(peerConnection) {
290
+ updatePeerconnection(peerConnection: any) {
274
291
  this.peerConnection = peerConnection;
275
292
  }
276
293
 
@@ -282,7 +299,7 @@ export class StatsAnalyzer extends EventsScope {
282
299
  * @param {PeerConnection} peerConnection
283
300
  * @returns {Promise}
284
301
  */
285
- startAnalyzer(peerConnection) {
302
+ public startAnalyzer(peerConnection: any) {
286
303
  if (!this.statsStarted) {
287
304
  this.statsStarted = true;
288
305
  this.peerConnection = peerConnection;
@@ -310,7 +327,7 @@ export class StatsAnalyzer extends EventsScope {
310
327
  * @memberof StatsAnalyzer
311
328
  * @returns {void}
312
329
  */
313
- stopAnalyzer() {
330
+ public stopAnalyzer() {
314
331
  const sendOneLastMqa = this.mqaInterval && this.statsInterval;
315
332
 
316
333
  if (this.statsInterval) {
@@ -344,7 +361,7 @@ export class StatsAnalyzer extends EventsScope {
344
361
  * @returns {void}
345
362
  * @memberof StatsAnalyzer
346
363
  */
347
- parseGetStatsResult(getStatsResult, type, isSender) {
364
+ private parseGetStatsResult(getStatsResult: any, type: string, isSender: boolean) {
348
365
  if (!getStatsResult) {
349
366
  return;
350
367
  }
@@ -361,6 +378,7 @@ export class StatsAnalyzer extends EventsScope {
361
378
  break;
362
379
  case 'remote-inbound-rtp':
363
380
  case 'remote-outbound-rtp':
381
+ // @ts-ignore
364
382
  this.compareSentAndReceived(getStatsResult, type, isSender);
365
383
  break;
366
384
  case 'remotecandidate':
@@ -371,6 +389,7 @@ export class StatsAnalyzer extends EventsScope {
371
389
  this.parseCandidate(getStatsResult, type, isSender, false);
372
390
  break;
373
391
  case 'media-source':
392
+ // @ts-ignore
374
393
  this.parseAudioSource(getStatsResult, type);
375
394
  break;
376
395
  default:
@@ -386,7 +405,7 @@ export class StatsAnalyzer extends EventsScope {
386
405
  * @param {boolean} isSender
387
406
  * @returns {void}
388
407
  */
389
- filterAndParseGetStatsResults(getStatsResults, type, isSender) {
408
+ private filterAndParseGetStatsResults(getStatsResults: Array<any>, type: string, isSender: boolean) {
390
409
  const {types} = DEFAULT_GET_STATS_FILTER;
391
410
 
392
411
  getStatsResults.forEach((result) => {
@@ -402,7 +421,7 @@ export class StatsAnalyzer extends EventsScope {
402
421
  * @param {boolean} type
403
422
  * @returns {void}
404
423
  */
405
- parseAudioSource(result, type) {
424
+ parseAudioSource(result: any, type: any) {
406
425
  if (!result) {
407
426
  return;
408
427
  }
@@ -427,7 +446,7 @@ export class StatsAnalyzer extends EventsScope {
427
446
  * @memberof StatsAnalyzer
428
447
  * @returns {void}
429
448
  */
430
- emitStartStopEvents = (mediaType, previousValue, currentValue, isLocal) => {
449
+ emitStartStopEvents = (mediaType: string, previousValue: number, currentValue: number, isLocal: boolean) => {
431
450
  if (mediaType !== 'audio' && mediaType !== 'video' && mediaType !== 'share') {
432
451
  throw new Error(`Unsupported mediaType: ${mediaType}`);
433
452
  }
@@ -475,7 +494,7 @@ export class StatsAnalyzer extends EventsScope {
475
494
  * @memberof StatsAnalyzer
476
495
  * @returns {void}
477
496
  */
478
- compareLastStatsResult() {
497
+ private compareLastStatsResult() {
479
498
  if (this.lastStatsResults !== null && this.meetingMediaStatus) {
480
499
  // compare audio stats sent
481
500
  let mediaType = STATS.AUDIO_CORRELATE;
@@ -633,7 +652,7 @@ export class StatsAnalyzer extends EventsScope {
633
652
  * @memberof StatsAnalyzer
634
653
  * @returns {Promise}
635
654
  */
636
- getStatsAndParse() {
655
+ private getStatsAndParse() {
637
656
  if (!this.peerConnection) {
638
657
  return Promise.resolve();
639
658
  }
@@ -694,7 +713,7 @@ export class StatsAnalyzer extends EventsScope {
694
713
  * @param {*} type
695
714
  * @returns {void}
696
715
  */
697
- processOutboundRTPResult(result, type) {
716
+ private processOutboundRTPResult(result: any, type: any) {
698
717
  const mediaType = type || STATS.AUDIO_CORRELATE;
699
718
  const sendrecvType = STATS.SEND_DIRECTION;
700
719
 
@@ -758,7 +777,7 @@ export class StatsAnalyzer extends EventsScope {
758
777
  * @param {*} type
759
778
  * @returns {void}
760
779
  */
761
- processInboundRTPResult(result, type) {
780
+ private processInboundRTPResult(result: any, type: any) {
762
781
  const mediaType = type || STATS.AUDIO_CORRELATE;
763
782
  const sendrecvType = STATS.RECEIVE_DIRECTION;
764
783
 
@@ -860,7 +879,7 @@ export class StatsAnalyzer extends EventsScope {
860
879
  *
861
880
  * @returns {void}
862
881
  */
863
- parseCandidate = (result, type, isSender, isRemote) => {
882
+ parseCandidate = (result: any, type: any, isSender: boolean, isRemote: boolean) => {
864
883
  if (!result || !result.id) {
865
884
  return;
866
885
  }
@@ -935,7 +954,7 @@ export class StatsAnalyzer extends EventsScope {
935
954
  * @returns {void}
936
955
  * @memberof StatsAnalyzer
937
956
  */
938
- processTrackResult(result, mediaType) {
957
+ private processTrackResult(result: any, mediaType: any) {
939
958
  if (!result || result.type !== 'track') {
940
959
  return;
941
960
  }
@@ -979,7 +998,7 @@ export class StatsAnalyzer extends EventsScope {
979
998
  * @returns {void}
980
999
  * @memberof StatsAnalyzer
981
1000
  */
982
- compareSentAndReceived(result, type) {
1001
+ private compareSentAndReceived(result: any, type: any) {
983
1002
  if (!type) {
984
1003
  return;
985
1004
  }
@@ -1,4 +1,3 @@
1
-
2
1
  import {mean, max} from 'lodash';
3
2
 
4
3
  import {STATS} from '../constants';
@@ -17,6 +16,7 @@ export const getAudioReceiverMqa = ({audioReceiver, statsResults, lastMqaDataSen
17
16
  audioReceiver.common.mediaHopByHopLost = (statsResults[mediaType][sendrecvType].totalPacketsLost - lastMqaDataSent[mediaType][sendrecvType].totalPacketsLost) || 0;
18
17
  audioReceiver.common.rtpHopByHopLost = statsResults[mediaType][sendrecvType].totalPacketsLost - lastMqaDataSent[mediaType][sendrecvType].totalPacketsLost || 0;
19
18
 
19
+ // @ts-ignore
20
20
  audioReceiver.streams[0].common.maxRtpJitter = max(statsResults[mediaType][sendrecvType].meanRtpJitter) * 1000 || 0;
21
21
  audioReceiver.streams[0].common.meanRtpJitter = mean(statsResults[mediaType][sendrecvType].meanRtpJitter) * 1000 || 0;
22
22
  audioReceiver.streams[0].common.rtpJitter = audioReceiver.streams[0].common.maxRtpJitter;
@@ -43,6 +43,7 @@ export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent})
43
43
  audioSender.common.common.direction = statsResults[mediaType].direction;
44
44
  audioSender.common.transportType = statsResults.connectionType.local.transport[0];
45
45
 
46
+ // @ts-ignore
46
47
  audioSender.common.maxRemoteJitter = max(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
47
48
  audioSender.common.meanRemoteJitter = mean(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
48
49
 
@@ -56,6 +57,7 @@ export const getAudioSenderMqa = ({audioSender, statsResults, lastMqaDataSent})
56
57
 
57
58
  audioSender.common.remoteLossRate = totalpacketsLostForaMin > 0 ? (totalpacketsLostForaMin * 100 / audioSender.common.rtpPackets) : 0; // This is the packets sent with in last min || 0;
58
59
 
60
+ // @ts-ignore
59
61
  audioSender.common.maxRoundTripTime = max(statsResults[mediaType][sendrecvType].meanRoundTripTime) * 1000 || 0;
60
62
  audioSender.common.meanRoundTripTime = mean(statsResults[mediaType][sendrecvType].meanRoundTripTime) * 1000 || 0;
61
63
  audioSender.common.roundTripTime = audioSender.common.maxRoundTripTime;
@@ -97,6 +99,7 @@ export const getVideoReceiverMqa = ({
97
99
 
98
100
  // calculate this values
99
101
 
102
+ // @ts-ignore
100
103
  videoReceiver.common.maxRemoteJitter = max(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
101
104
  videoReceiver.common.meanRemoteJitter = mean(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
102
105
 
@@ -134,6 +137,7 @@ export const getVideoSenderMqa = ({
134
137
  videoSender.common.common.direction = statsResults[mediaType].direction;
135
138
  videoSender.common.transportType = statsResults.connectionType.local.transport[0];
136
139
 
140
+ // @ts-ignore
137
141
  videoSender.common.maxRemoteJitter = max(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
138
142
  videoSender.common.meanRemoteJitter = mean(statsResults[mediaType][sendrecvType].meanRemoteJitter) * 1000 || 0;
139
143
 
@@ -146,6 +150,7 @@ export const getVideoSenderMqa = ({
146
150
 
147
151
  videoSender.common.remoteLossRate = totalpacketsLostForaMin > 0 ? (totalpacketsLostForaMin) * 100 / (videoSender.common.rtpPackets + totalpacketsLostForaMin) : 0; // This is the packets sent with in last min || 0;
148
152
 
153
+ // @ts-ignore
149
154
  videoSender.common.maxRoundTripTime = max(statsResults[mediaType][sendrecvType].meanRoundTripTime) * 1000 || 0;
150
155
  videoSender.common.meanRoundTripTime = mean(statsResults[mediaType][sendrecvType].meanRoundTripTime) * 1000 || 0;
151
156
  videoSender.common.roundTripTime = videoSender.common.maxRoundTripTime;
@@ -6,6 +6,12 @@ import {v4 as uuidv4} from 'uuid';
6
6
  * @class Transcription
7
7
  */
8
8
  export default class Transcription {
9
+ webSocketUrl: any;
10
+ sessionID: any;
11
+ members: any;
12
+ memberCSIs: any;
13
+ webSocket: any;
14
+
9
15
  /**
10
16
  * @param {string} webSocketUrl
11
17
  * @param {sessionID} sessionId
@@ -13,7 +19,7 @@ export default class Transcription {
13
19
  * @constructor
14
20
  * @memberof Transcription
15
21
  */
16
- constructor(webSocketUrl, sessionId, members) {
22
+ constructor(webSocketUrl: string, sessionId: any, members: object) {
17
23
  this.webSocketUrl = webSocketUrl;
18
24
  this.sessionID = sessionId;
19
25
  this.members = members;
@@ -32,7 +38,7 @@ export default class Transcription {
32
38
  * @param {string} sessionID
33
39
  * @returns {void}
34
40
  */
35
- connect(token) {
41
+ connect(token: string) {
36
42
  this.webSocket.onopen = () => {
37
43
  this.webSocket.send(JSON.stringify({
38
44
  id: uuidv4(),
@@ -46,10 +52,10 @@ export default class Transcription {
46
52
  /**
47
53
  * Sets callback to invoke when the web socket connection is closed.
48
54
  *
49
- * @param {function} callback
55
+ * @param {Function} callback
50
56
  * @returns {void}
51
57
  */
52
- onCloseSocket(callback) {
58
+ onCloseSocket(callback: Function) {
53
59
  if (callback) {
54
60
  this.webSocket.onclose = (event) => {
55
61
  callback(event);
@@ -61,10 +67,10 @@ export default class Transcription {
61
67
  * Sets callback to invoke when a web socket connection error occurs.
62
68
  * An event parameter will be send to the callback.
63
69
  *
64
- * @param {function} callback
70
+ * @param {Function} callback
65
71
  * @returns {void}
66
72
  */
67
- onErrorSocket(callback) {
73
+ onErrorSocket(callback: Function) {
68
74
  if (callback) {
69
75
  this.webSocket.onerror = (event) => {
70
76
  callback(event);
@@ -79,7 +85,7 @@ export default class Transcription {
79
85
  * @param {object} csis
80
86
  * @returns {object}
81
87
  */
82
- getSpeaker(csis) {
88
+ private getSpeaker(csis: any) {
83
89
  for (const csi of csis) {
84
90
  const member = this.memberCSIs[csi];
85
91
 
@@ -89,7 +95,7 @@ export default class Transcription {
89
95
  }
90
96
 
91
97
  return Object.values(this.members.membersCollection.members)
92
- .find((member) => {
98
+ .find((member: any) => {
93
99
  const memberCSIs = member.participant.status.csis;
94
100
  let selfIsSpeaking = false;
95
101
 
@@ -108,10 +114,10 @@ export default class Transcription {
108
114
  /**
109
115
  * Sends transcription data to given callback as it arrives.
110
116
  *
111
- * @param {function} callback
117
+ * @param {Function} callback
112
118
  * @returns {void}
113
119
  */
114
- subscribe(callback) {
120
+ subscribe(callback: Function) {
115
121
  let data, csis, speaker, transcription;
116
122
 
117
123
  this.webSocket.onmessage = (event) => {
@@ -144,4 +150,3 @@ export default class Transcription {
144
150
  this.webSocket.close();
145
151
  }
146
152
  }
147
-
@@ -2,7 +2,6 @@
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import {skipInNode, jenkinsOnly} from '@webex/test-helper-mocha';
4
4
  import {patterns} from '@webex/common';
5
-
6
5
  import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
7
6
 
8
7
  import CMR from '../../utils/cmr';
@@ -10,7 +9,7 @@ import testUtils from '../../utils/testUtils';
10
9
 
11
10
  require('dotenv').config();
12
11
 
13
- const webexTestUsers = require('../../utils/webex-test-users.js');
12
+ const webexTestUsers = require('../../utils/webex-test-users');
14
13
 
15
14
  let userSet, alice, bob, chris, guest;
16
15
 
@@ -1420,9 +1420,9 @@ describe('plugin-meetings', () => {
1420
1420
  });
1421
1421
  });
1422
1422
  });
1423
- describe('#share', () => {
1424
- it('should have #share', () => {
1425
- assert.exists(meeting.share);
1423
+ describe('#requestScreenShareFloor', () => {
1424
+ it('should have #requestScreenShareFloor', () => {
1425
+ assert.exists(meeting.requestScreenShareFloor);
1426
1426
  });
1427
1427
  beforeEach(() => {
1428
1428
  meeting.locusInfo.mediaShares = [{name: 'content', url: url1}];
@@ -1430,7 +1430,7 @@ describe('plugin-meetings', () => {
1430
1430
  meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
1431
1431
  });
1432
1432
  it('should send the share', async () => {
1433
- const share = meeting.share();
1433
+ const share = meeting.requestScreenShareFloor();
1434
1434
 
1435
1435
  assert.exists(share.then);
1436
1436
  await share;
@@ -3457,22 +3457,34 @@ describe('plugin-meetings', () => {
3457
3457
  sandbox = null;
3458
3458
  });
3459
3459
 
3460
- describe('#stopFloorRequest', () => {
3461
- it('should have #stopFloorRequest', () => {
3462
- assert.exists(meeting.stopFloorRequest);
3460
+ describe('#releaseScreenShareFloor', () => {
3461
+ it('should have #releaseScreenShareFloor', () => {
3462
+ assert.exists(meeting.releaseScreenShareFloor);
3463
3463
  });
3464
3464
  beforeEach(() => {
3465
- meeting.locusInfo.mediaShares = [{name: 'content', url: url1}];
3465
+ meeting.selfId = 'some self id';
3466
+ meeting.locusInfo.mediaShares = [{name: 'content', url: url1, floor: {beneficiary: {id: meeting.selfId}}}];
3466
3467
  meeting.locusInfo.self = {url: url2};
3468
+ meeting.mediaProperties = {mediaDirection: {sendShare: true}};
3467
3469
  meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
3468
3470
  });
3469
- it('should call change meeting floor', async () => {
3470
- const share = meeting.share();
3471
+ it('should call changeMeetingFloor()', async () => {
3472
+ const share = meeting.releaseScreenShareFloor();
3471
3473
 
3472
3474
  assert.exists(share.then);
3473
3475
  await share;
3474
3476
  assert.calledOnce(meeting.meetingRequest.changeMeetingFloor);
3475
3477
  });
3478
+ it('should not call changeMeetingFloor() if someone else already has the floor', async () => {
3479
+ // change selfId so that it doesn't match the beneficiary id from meeting.locusInfo.mediaShares
3480
+ meeting.selfId = 'new self id';
3481
+
3482
+ const share = meeting.releaseScreenShareFloor();
3483
+
3484
+ assert.exists(share.then);
3485
+ await share;
3486
+ assert.notCalled(meeting.meetingRequest.changeMeetingFloor);
3487
+ });
3476
3488
  });
3477
3489
 
3478
3490
  describe('#setSipUri', () => {
@@ -4003,7 +4015,7 @@ describe('plugin-meetings', () => {
4003
4015
  if (newPayload.previous.content.beneficiaryId === USER_IDS.ME) {
4004
4016
  eventTrigger.share.push({
4005
4017
  eventName: EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
4006
- functionName: 'stopFloorRequest'
4018
+ functionName: 'localShare'
4007
4019
  });
4008
4020
  }
4009
4021
  else if (newPayload.current.content.beneficiaryId === USER_IDS.ME) {
@@ -4054,7 +4066,7 @@ describe('plugin-meetings', () => {
4054
4066
  if (newPayload.current.content.beneficiaryId === USER_IDS.ME) {
4055
4067
  eventTrigger.share.push({
4056
4068
  eventName: EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
4057
- functionName: 'stopFloorRequest'
4069
+ functionName: 'localShare'
4058
4070
  });
4059
4071
  }
4060
4072
  else {
@@ -4073,7 +4085,7 @@ describe('plugin-meetings', () => {
4073
4085
  if (newPayload.previous.content.beneficiaryId === USER_IDS.ME) {
4074
4086
  eventTrigger.share.push({
4075
4087
  eventName: EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
4076
- functionName: 'stopFloorRequest'
4088
+ functionName: 'localShare'
4077
4089
  });
4078
4090
  }
4079
4091
  else if (newPayload.current.content.beneficiaryId === USER_IDS.ME) {
@@ -4116,7 +4128,7 @@ describe('plugin-meetings', () => {
4116
4128
  if (beneficiaryId === USER_IDS.ME) {
4117
4129
  eventTrigger.share.push({
4118
4130
  eventName: EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
4119
- functionName: 'stopFloorRequest'
4131
+ functionName: 'localShare'
4120
4132
  });
4121
4133
  }
4122
4134
  else {
@@ -4582,6 +4594,93 @@ describe('plugin-meetings', () => {
4582
4594
  meeting.stopKeepAlive();
4583
4595
  });
4584
4596
  });
4597
+
4598
+ describe('#sendReaction', () => {
4599
+ it('should have #sendReaction', () => {
4600
+ assert.exists(meeting.sendReaction);
4601
+ });
4602
+
4603
+ beforeEach(() => {
4604
+ meeting.meetingRequest.sendReaction = sinon.stub().returns(Promise.resolve());
4605
+ });
4606
+
4607
+ it('should send reaction with the right data and return a promise', async () => {
4608
+ meeting.locusInfo.controls = {reactions: {reactionChannelUrl: 'Fake URL'}};
4609
+
4610
+ const reactionPromise = meeting.sendReaction('thumbs_down', 'light');
4611
+
4612
+ assert.exists(reactionPromise.then);
4613
+ await reactionPromise;
4614
+ assert.calledOnceWithExactly(meeting.meetingRequest.sendReaction, {
4615
+ reactionChannelUrl: 'Fake URL',
4616
+ reaction: {
4617
+ type: 'thumb_down',
4618
+ codepoints: '1F44E',
4619
+ shortcodes: ':thumbsdown:',
4620
+ tone: {
4621
+ type: 'light_skin_tone',
4622
+ codepoints: '1F3FB',
4623
+ shortcodes: ':skin-tone-2:'
4624
+ }
4625
+ },
4626
+ participantId: meeting.members.selfId,
4627
+ });
4628
+ });
4629
+
4630
+ it('should fail sending a reaction if data channel is undefined', async () => {
4631
+ meeting.locusInfo.controls = {reactions: {reactionChannelUrl: undefined}};
4632
+
4633
+ await assert.isRejected(meeting.sendReaction('thumbs_down', 'light'), Error, 'Error sending reaction, service url not found.');
4634
+
4635
+ assert.notCalled(meeting.meetingRequest.sendReaction);
4636
+ });
4637
+
4638
+ it('should fail sending a reaction if reactionType is invalid ', async () => {
4639
+ meeting.locusInfo.controls = {reactions: {reactionChannelUrl: 'Fake URL'}};
4640
+
4641
+ await assert.isRejected(meeting.sendReaction('invalid_reaction', 'light'), Error, 'invalid_reaction is not a valid reaction.');
4642
+
4643
+ assert.notCalled(meeting.meetingRequest.sendReaction);
4644
+ });
4645
+
4646
+ it('should send a reaction with default skin tone if provided skinToneType is invalid ', async () => {
4647
+ meeting.locusInfo.controls = {reactions: {reactionChannelUrl: 'Fake URL'}};
4648
+
4649
+ const reactionPromise = meeting.sendReaction('thumbs_down', 'invalid_skin_tone');
4650
+
4651
+ assert.exists(reactionPromise.then);
4652
+ await reactionPromise;
4653
+ assert.calledOnceWithExactly(meeting.meetingRequest.sendReaction, {
4654
+ reactionChannelUrl: 'Fake URL',
4655
+ reaction: {
4656
+ type: 'thumb_down',
4657
+ codepoints: '1F44E',
4658
+ shortcodes: ':thumbsdown:',
4659
+ tone: {type: 'normal_skin_tone', codepoints: '', shortcodes: ''}
4660
+ },
4661
+ participantId: meeting.members.selfId,
4662
+ });
4663
+ });
4664
+
4665
+ it('should send a reaction with default skin tone if none provided', async () => {
4666
+ meeting.locusInfo.controls = {reactions: {reactionChannelUrl: 'Fake URL'}};
4667
+
4668
+ const reactionPromise = meeting.sendReaction('thumbs_down');
4669
+
4670
+ assert.exists(reactionPromise.then);
4671
+ await reactionPromise;
4672
+ assert.calledOnceWithExactly(meeting.meetingRequest.sendReaction, {
4673
+ reactionChannelUrl: 'Fake URL',
4674
+ reaction: {
4675
+ type: 'thumb_down',
4676
+ codepoints: '1F44E',
4677
+ shortcodes: ':thumbsdown:',
4678
+ tone: {type: 'normal_skin_tone', codepoints: '', shortcodes: ''}
4679
+ },
4680
+ participantId: meeting.members.selfId,
4681
+ });
4682
+ });
4683
+ });
4585
4684
  });
4586
4685
  });
4587
4686
  });