@webex/plugin-meetings 2.37.1 → 2.38.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 (69) hide show
  1. package/dist/config.js +1 -1
  2. package/dist/config.js.map +1 -1
  3. package/dist/constants.js +2 -1
  4. package/dist/constants.js.map +1 -1
  5. package/dist/locus-info/index.js +24 -0
  6. package/dist/locus-info/index.js.map +1 -1
  7. package/dist/locus-info/parser.js +1 -0
  8. package/dist/locus-info/parser.js.map +1 -1
  9. package/dist/media/properties.js.map +1 -1
  10. package/dist/meeting/index.js +405 -352
  11. package/dist/meeting/index.js.map +1 -1
  12. package/dist/meeting/request.js +0 -27
  13. package/dist/meeting/request.js.map +1 -1
  14. package/dist/meeting/util.js +0 -56
  15. package/dist/meeting/util.js.map +1 -1
  16. package/dist/meeting-info/meeting-info-v2.js +2 -0
  17. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  18. package/dist/meetings/index.js +27 -17
  19. package/dist/meetings/index.js.map +1 -1
  20. package/dist/meetings/request.js +14 -12
  21. package/dist/meetings/request.js.map +1 -1
  22. package/dist/member/util.js +3 -1
  23. package/dist/member/util.js.map +1 -1
  24. package/dist/members/request.js +3 -1
  25. package/dist/members/request.js.map +1 -1
  26. package/dist/reachability/index.js +4 -4
  27. package/dist/reachability/index.js.map +1 -1
  28. package/dist/reactions/reactions.type.js +1 -0
  29. package/dist/reactions/reactions.type.js.map +1 -1
  30. package/dist/recording-controller/enums.js +17 -0
  31. package/dist/recording-controller/enums.js.map +1 -0
  32. package/dist/recording-controller/index.js +343 -0
  33. package/dist/recording-controller/index.js.map +1 -0
  34. package/dist/recording-controller/util.js +63 -0
  35. package/dist/recording-controller/util.js.map +1 -0
  36. package/dist/roap/turnDiscovery.js.map +1 -1
  37. package/dist/statsAnalyzer/mqaUtil.js +18 -6
  38. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  39. package/package.json +23 -18
  40. package/src/config.ts +1 -1
  41. package/src/constants.ts +1 -0
  42. package/src/locus-info/index.ts +24 -0
  43. package/src/locus-info/parser.ts +1 -0
  44. package/src/media/properties.ts +1 -1
  45. package/src/meeting/index.ts +121 -70
  46. package/src/meeting/request.ts +0 -31
  47. package/src/meeting/util.ts +0 -60
  48. package/src/meeting-info/meeting-info-v2.ts +2 -0
  49. package/src/meetings/index.ts +8 -3
  50. package/src/meetings/request.ts +1 -1
  51. package/src/member/util.ts +2 -1
  52. package/src/members/request.ts +1 -0
  53. package/src/reachability/index.ts +2 -1
  54. package/src/reactions/reactions.type.ts +2 -1
  55. package/src/recording-controller/enums.ts +8 -0
  56. package/src/recording-controller/index.ts +315 -0
  57. package/src/recording-controller/util.ts +58 -0
  58. package/src/roap/turnDiscovery.ts +1 -1
  59. package/src/statsAnalyzer/mqaUtil.ts +6 -0
  60. package/test/integration/spec/journey.js +1 -1
  61. package/test/integration/spec/space-meeting.js +1 -1
  62. package/test/integration/spec/transcription.js +1 -1
  63. package/test/unit/spec/meeting/index.js +33 -6
  64. package/test/unit/spec/meeting/utils.js +0 -127
  65. package/test/unit/spec/recording-controller/index.js +231 -0
  66. package/test/unit/spec/recording-controller/util.js +102 -0
  67. package/test/unit/spec/roap/index.ts +2 -1
  68. package/test/unit/spec/roap/turnDiscovery.ts +5 -4
  69. package/tsconfig.json +6 -0
@@ -30,6 +30,7 @@ import ReconnectionManager from '../reconnection-manager';
30
30
  import MeetingRequest from './request';
31
31
  import Members from '../members/index';
32
32
  import MeetingUtil from './util';
33
+ import RecordingUtil from '../recording-controller/util';
33
34
  import MediaUtil from '../media/util';
34
35
  import Transcription from '../transcription';
35
36
  import PasswordError from '../common/errors/password-error';
@@ -88,6 +89,7 @@ import {SkinTones, Reactions} from '../reactions/reactions';
88
89
  import {Reaction, ReactionType, SkinToneType} from '../reactions/reactions.type';
89
90
 
90
91
  import InMeetingActions from './in-meeting-actions';
92
+ import RecordingController from '../recording-controller';
91
93
 
92
94
  const {isBrowser} = BrowserDetection();
93
95
 
@@ -452,6 +454,7 @@ export default class Meeting extends StatelessWebexPlugin {
452
454
  passwordStatus: string;
453
455
  queuedMediaUpdates: any[];
454
456
  recording: any;
457
+ recordingController: RecordingController;
455
458
  requiredCaptcha: any;
456
459
  shareStatus: string;
457
460
  statsAnalyzer: StatsAnalyzer;
@@ -885,6 +888,7 @@ export default class Meeting extends StatelessWebexPlugin {
885
888
  */
886
889
  // @ts-ignore - Fix type
887
890
  this.locusInfo = new LocusInfo(this.updateMeetingObject.bind(this), this.webex, this.id);
891
+
888
892
  // We had to add listeners first before setting up the locus instance
889
893
  /**
890
894
  * @instance
@@ -984,6 +988,20 @@ export default class Meeting extends StatelessWebexPlugin {
984
988
  */
985
989
  this.keepAliveTimerId = null;
986
990
 
991
+ /**
992
+ * The class that helps to control recording functions: start, stop, pause, resume, etc
993
+ * @instance
994
+ * @type {RecordingController}
995
+ * @public
996
+ * @memberof Meeting
997
+ */
998
+ this.recordingController = new RecordingController(this.meetingRequest, {
999
+ serviceUrl: this.locusInfo?.links?.services?.record?.url,
1000
+ sessionId: this.locusInfo?.fullState?.sessionId,
1001
+ locusUrl: this.locusInfo?.url,
1002
+ displayHints: [],
1003
+ });
1004
+
987
1005
  this.setUpLocusInfoListeners();
988
1006
  this.locusInfo.init(attrs.locus ? attrs.locus : {});
989
1007
  this.hasJoinedOnce = false;
@@ -1155,22 +1173,25 @@ export default class Meeting extends StatelessWebexPlugin {
1155
1173
  // we have to pass the wbxappapi hostname as the siteFullName parameter
1156
1174
  const {hostname} = new URL(this.requiredCaptcha.refreshURL);
1157
1175
 
1158
- return this.meetingRequest
1159
- .refreshCaptcha({
1160
- captchaRefreshUrl: `${this.requiredCaptcha.refreshURL}&siteFullName=${hostname}`,
1161
- captchaId: this.requiredCaptcha.captchaId,
1162
- })
1163
- .then((response) => {
1164
- this.requiredCaptcha.captchaId = response.body.captchaID;
1165
- this.requiredCaptcha.verificationImageURL = response.body.verificationImageURL;
1166
- this.requiredCaptcha.verificationAudioURL = response.body.verificationAudioURL;
1167
- })
1168
- .catch((error) => {
1169
- LoggerProxy.logger.error(
1170
- `Meeting:index#refreshCaptcha --> Error Unable to refresh captcha for ${this.destination} - ${error}`
1171
- );
1172
- throw error;
1173
- });
1176
+ return (
1177
+ this.meetingRequest
1178
+ // @ts-ignore
1179
+ .refreshCaptcha({
1180
+ captchaRefreshUrl: `${this.requiredCaptcha.refreshURL}&siteFullName=${hostname}`,
1181
+ captchaId: this.requiredCaptcha.captchaId,
1182
+ })
1183
+ .then((response) => {
1184
+ this.requiredCaptcha.captchaId = response.body.captchaID;
1185
+ this.requiredCaptcha.verificationImageURL = response.body.verificationImageURL;
1186
+ this.requiredCaptcha.verificationAudioURL = response.body.verificationAudioURL;
1187
+ })
1188
+ .catch((error) => {
1189
+ LoggerProxy.logger.error(
1190
+ `Meeting:index#refreshCaptcha --> Error Unable to refresh captcha for ${this.destination} - ${error}`
1191
+ );
1192
+ throw error;
1193
+ })
1194
+ );
1174
1195
  }
1175
1196
 
1176
1197
  /**
@@ -1183,6 +1204,7 @@ export default class Meeting extends StatelessWebexPlugin {
1183
1204
  // meeting update listeners
1184
1205
  this.setUpLocusInfoSelfListener();
1185
1206
  this.setUpLocusInfoMeetingListener();
1207
+ this.setUpLocusServicesListener();
1186
1208
  // members update listeners
1187
1209
  this.setUpLocusFullStateListener();
1188
1210
  this.setUpLocusUrlListener();
@@ -1997,6 +2019,23 @@ export default class Meeting extends StatelessWebexPlugin {
1997
2019
  this.members.locusUrlUpdate(payload);
1998
2020
  this.locusUrl = payload;
1999
2021
  this.locusId = this.locusUrl?.split('/').pop();
2022
+ this.recordingController.setLocusUrl(this.locusUrl);
2023
+ });
2024
+ }
2025
+
2026
+ /**
2027
+ * Set up the locus info service link listener
2028
+ * update the locusInfo for recording controller
2029
+ * does not currently re-emit the event as it's internal only
2030
+ * payload is unused
2031
+ * @returns {undefined}
2032
+ * @private
2033
+ * @memberof Meeting
2034
+ */
2035
+ private setUpLocusServicesListener() {
2036
+ this.locusInfo.on(LOCUSINFO.EVENTS.LINKS_SERVICES, (payload) => {
2037
+ this.recordingController.setServiceUrl(payload?.services?.record?.url);
2038
+ this.recordingController.setSessionId(this.locusInfo?.fullState?.sessionId);
2000
2039
  });
2001
2040
  }
2002
2041
 
@@ -2046,10 +2085,10 @@ export default class Meeting extends StatelessWebexPlugin {
2046
2085
  canAdmitParticipant: MeetingUtil.canAdmitParticipant(payload.info.userDisplayHints),
2047
2086
  canLock: MeetingUtil.canUserLock(payload.info.userDisplayHints),
2048
2087
  canUnlock: MeetingUtil.canUserUnlock(payload.info.userDisplayHints),
2049
- canStartRecording: MeetingUtil.canUserRecord(payload.info.userDisplayHints),
2050
- canStopRecording: MeetingUtil.canUserStop(payload.info.userDisplayHints),
2051
- canPauseRecording: MeetingUtil.canUserPause(payload.info.userDisplayHints),
2052
- canResumeRecording: MeetingUtil.canUserResume(payload.info.userDisplayHints),
2088
+ canStartRecording: RecordingUtil.canUserStart(payload.info.userDisplayHints),
2089
+ canStopRecording: RecordingUtil.canUserStop(payload.info.userDisplayHints),
2090
+ canPauseRecording: RecordingUtil.canUserPause(payload.info.userDisplayHints),
2091
+ canResumeRecording: RecordingUtil.canUserResume(payload.info.userDisplayHints),
2053
2092
  canRaiseHand: MeetingUtil.canUserRaiseHand(payload.info.userDisplayHints),
2054
2093
  canLowerAllHands: MeetingUtil.canUserLowerAllHands(payload.info.userDisplayHints),
2055
2094
  canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(
@@ -2073,6 +2112,8 @@ export default class Meeting extends StatelessWebexPlugin {
2073
2112
  waitingForOthersToJoin: MeetingUtil.waitingForOthersToJoin(payload.info.userDisplayHints),
2074
2113
  });
2075
2114
 
2115
+ this.recordingController.setDisplayHints(payload.info.userDisplayHints);
2116
+
2076
2117
  if (changed) {
2077
2118
  Trigger.trigger(
2078
2119
  this,
@@ -2294,7 +2335,7 @@ export default class Meeting extends StatelessWebexPlugin {
2294
2335
  .catch((error) => {
2295
2336
  // @ts-ignore
2296
2337
  LoggerProxy.logger.error(
2297
- `Meeting:index#setUpLocusInfoMeetingListener --> REMOTE_RESPONSE. Issue with leave for meeting, meeting still in collection: ${this.meeting}, error: ${error}`
2338
+ `Meeting:index#setUpLocusInfoMeetingListener --> REMOTE_RESPONSE. Issue with leave for meeting, meeting still in collection: ${this}, error: ${error}`
2298
2339
  );
2299
2340
  });
2300
2341
  }
@@ -2329,7 +2370,7 @@ export default class Meeting extends StatelessWebexPlugin {
2329
2370
  .catch((error) => {
2330
2371
  // @ts-ignore
2331
2372
  LoggerProxy.logger.error(
2332
- `Meeting:index#setUpLocusInfoMeetingListener --> DESTROY_MEETING. Issue with leave for meeting, meeting still in collection: ${this.meeting}, error: ${error}`
2373
+ `Meeting:index#setUpLocusInfoMeetingListener --> DESTROY_MEETING. Issue with leave for meeting, meeting still in collection: ${this}, error: ${error}`
2333
2374
  );
2334
2375
  });
2335
2376
  } else {
@@ -2571,6 +2612,7 @@ export default class Meeting extends StatelessWebexPlugin {
2571
2612
  this.locusUrl = locusMeetingObject?.url || webexMeetingInfo?.locusUrl || this.locusUrl;
2572
2613
  // @ts-ignore - config coming from registerPlugin
2573
2614
  this.setSipUri(
2615
+ // @ts-ignore
2574
2616
  this.config.experimental.enableUnifiedMeetings
2575
2617
  ? locusMeetingObject?.info.sipUri || webexMeetingInfo?.sipUrl
2576
2618
  : locusMeetingObject?.info.sipUri || webexMeetingInfo?.sipMeetingUri || this.sipUri
@@ -3667,6 +3709,7 @@ export default class Meeting extends StatelessWebexPlugin {
3667
3709
  // @ts-ignore - fix type
3668
3710
  const {
3669
3711
  body: {webSocketUrl},
3712
+ // @ts-ignore
3670
3713
  } = await this.request({
3671
3714
  method: HTTP_VERBS.POST,
3672
3715
  uri: datachannelUrl,
@@ -3980,28 +4023,31 @@ export default class Meeting extends StatelessWebexPlugin {
3980
4023
 
3981
4024
  if (!this.dialInUrl) this.dialInUrl = `dialin:///${uuid.v4()}`;
3982
4025
 
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, {
3995
- correlation_id: this.correlationId,
3996
- dial_in_url: this.dialInUrl,
3997
- locus_id: locusUrl.split('/').pop(),
3998
- client_url: this.deviceUrl,
3999
- reason: error.error?.message,
4000
- stack: error.stack,
4001
- });
4026
+ return (
4027
+ this.meetingRequest
4028
+ // @ts-ignore
4029
+ .dialIn({
4030
+ correlationId,
4031
+ dialInUrl: this.dialInUrl,
4032
+ locusUrl,
4033
+ clientUrl: this.deviceUrl,
4034
+ })
4035
+ .then((res) => {
4036
+ this.locusInfo.onFullLocus(res.body.locus);
4037
+ })
4038
+ .catch((error) => {
4039
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE, {
4040
+ correlation_id: this.correlationId,
4041
+ dial_in_url: this.dialInUrl,
4042
+ locus_id: locusUrl.split('/').pop(),
4043
+ client_url: this.deviceUrl,
4044
+ reason: error.error?.message,
4045
+ stack: error.stack,
4046
+ });
4002
4047
 
4003
- return Promise.reject(error);
4004
- });
4048
+ return Promise.reject(error);
4049
+ })
4050
+ );
4005
4051
  }
4006
4052
 
4007
4053
  /**
@@ -4018,29 +4064,32 @@ export default class Meeting extends StatelessWebexPlugin {
4018
4064
 
4019
4065
  if (!this.dialOutUrl) this.dialOutUrl = `dialout:///${uuid.v4()}`;
4020
4066
 
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, {
4034
- correlation_id: this.correlationId,
4035
- dial_out_url: this.dialOutUrl,
4036
- locus_id: locusUrl.split('/').pop(),
4037
- client_url: this.deviceUrl,
4038
- reason: error.error?.message,
4039
- stack: error.stack,
4040
- });
4067
+ return (
4068
+ this.meetingRequest
4069
+ // @ts-ignore
4070
+ .dialOut({
4071
+ correlationId,
4072
+ dialOutUrl: this.dialOutUrl,
4073
+ phoneNumber,
4074
+ locusUrl,
4075
+ clientUrl: this.deviceUrl,
4076
+ })
4077
+ .then((res) => {
4078
+ this.locusInfo.onFullLocus(res.body.locus);
4079
+ })
4080
+ .catch((error) => {
4081
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE, {
4082
+ correlation_id: this.correlationId,
4083
+ dial_out_url: this.dialOutUrl,
4084
+ locus_id: locusUrl.split('/').pop(),
4085
+ client_url: this.deviceUrl,
4086
+ reason: error.error?.message,
4087
+ stack: error.stack,
4088
+ });
4041
4089
 
4042
- return Promise.reject(error);
4043
- });
4090
+ return Promise.reject(error);
4091
+ })
4092
+ );
4044
4093
  }
4045
4094
 
4046
4095
  /**
@@ -4374,6 +4423,7 @@ export default class Meeting extends StatelessWebexPlugin {
4374
4423
  // Add ip address info if geo hint is present
4375
4424
  // @ts-ignore fix type
4376
4425
  options.data.intervalMetadata.peerReflexiveIP =
4426
+ // @ts-ignore
4377
4427
  this.webex.meetings.geoHintInfo?.clientAddress ||
4378
4428
  options.data.intervalMetadata.peerReflexiveIP ||
4379
4429
  MQA_STATS.DEFAULT_IP;
@@ -4855,10 +4905,11 @@ export default class Meeting extends StatelessWebexPlugin {
4855
4905
  // we actually get a OFFER from the server and a GLAR condition happens
4856
4906
  if (startShare) {
4857
4907
  // We are assuming that the clients are connected when doing an update
4908
+ // @ts-ignore
4858
4909
  return this.share();
4859
4910
  }
4860
4911
 
4861
- throw error;
4912
+ return Promise.resolve();
4862
4913
  })
4863
4914
  .then(() =>
4864
4915
  logRequest(
@@ -5498,7 +5549,7 @@ export default class Meeting extends StatelessWebexPlugin {
5498
5549
  * @memberof Meeting
5499
5550
  */
5500
5551
  public startRecording() {
5501
- return MeetingUtil.startRecording(this.meetingRequest, this.locusUrl, this.locusInfo);
5552
+ return this.recordingController.startRecording();
5502
5553
  }
5503
5554
 
5504
5555
  /**
@@ -5508,7 +5559,7 @@ export default class Meeting extends StatelessWebexPlugin {
5508
5559
  * @memberof Meeting
5509
5560
  */
5510
5561
  public stopRecording() {
5511
- return MeetingUtil.stopRecording(this.meetingRequest, this.locusUrl, this.locusInfo);
5562
+ return this.recordingController.stopRecording();
5512
5563
  }
5513
5564
 
5514
5565
  /**
@@ -5518,7 +5569,7 @@ export default class Meeting extends StatelessWebexPlugin {
5518
5569
  * @memberof Meeting
5519
5570
  */
5520
5571
  public pauseRecording() {
5521
- return MeetingUtil.pauseRecording(this.meetingRequest, this.locusUrl, this.locusInfo);
5572
+ return this.recordingController.pauseRecording();
5522
5573
  }
5523
5574
 
5524
5575
  /**
@@ -5528,7 +5579,7 @@ export default class Meeting extends StatelessWebexPlugin {
5528
5579
  * @memberof Meeting
5529
5580
  */
5530
5581
  public resumeRecording() {
5531
- return MeetingUtil.resumeRecording(this.meetingRequest, this.locusUrl, this.locusInfo);
5582
+ return this.recordingController.resumeRecording();
5532
5583
  }
5533
5584
 
5534
5585
  /**
@@ -496,37 +496,6 @@ export default class MeetingRequest extends StatelessWebexPlugin {
496
496
  });
497
497
  }
498
498
 
499
- /**
500
- * Make a network request to acknowledge a meeting
501
- * @param {Object} options
502
- * @param {String} options.locusUrl
503
- * @param {String} options.deviceUrl
504
- * @param {String} options.id
505
- * @returns {Promise}
506
- */
507
- recordMeeting(options: {
508
- locusUrl: string;
509
- deviceUrl: string;
510
- id: string;
511
- recording: any;
512
- paused: any;
513
- }) {
514
- const uri = `${options.locusUrl}/${CONTROLS}`;
515
- const body = {
516
- record: {
517
- recording: options.recording,
518
- paused: options.paused,
519
- },
520
- };
521
-
522
- // @ts-ignore
523
- return this.request({
524
- method: HTTP_VERBS.PATCH,
525
- uri,
526
- body,
527
- });
528
- }
529
-
530
499
  lockMeeting(options) {
531
500
  const uri = `${options.locusUrl}/${CONTROLS}`;
532
501
  const body = {
@@ -411,66 +411,6 @@ MeetingUtil.canUserUnlock = (displayHints) =>
411
411
  displayHints.includes(DISPLAY_HINTS.LOCK_CONTROL_UNLOCK) &&
412
412
  displayHints.includes(DISPLAY_HINTS.LOCK_STATUS_LOCKED);
413
413
 
414
- MeetingUtil.canUserRecord = (displayHints) =>
415
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START);
416
-
417
- MeetingUtil.canUserPause = (displayHints) =>
418
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE);
419
-
420
- MeetingUtil.canUserResume = (displayHints) =>
421
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME);
422
-
423
- MeetingUtil.canUserStop = (displayHints) =>
424
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP);
425
-
426
- MeetingUtil.startRecording = (request, locusUrl, locusInfo) => {
427
- const displayHints = MeetingUtil.getUserDisplayHintsFromLocusInfo(locusInfo);
428
-
429
- if (MeetingUtil.canUserRecord(displayHints)) {
430
- return request.recordMeeting({locusUrl, recording: true, paused: false});
431
- }
432
-
433
- return Promise.reject(
434
- new PermissionError('Start recording not allowed, due to moderator property.')
435
- );
436
- };
437
-
438
- MeetingUtil.pauseRecording = (request, locusUrl, locusInfo) => {
439
- const displayHints = MeetingUtil.getUserDisplayHintsFromLocusInfo(locusInfo);
440
-
441
- if (MeetingUtil.canUserPause(displayHints)) {
442
- return request.recordMeeting({locusUrl, recording: true, paused: true});
443
- }
444
-
445
- return Promise.reject(
446
- new PermissionError('Pause recording not allowed, due to moderator property.')
447
- );
448
- };
449
-
450
- MeetingUtil.resumeRecording = (request, locusUrl, locusInfo) => {
451
- const displayHints = MeetingUtil.getUserDisplayHintsFromLocusInfo(locusInfo);
452
-
453
- if (MeetingUtil.canUserResume(displayHints)) {
454
- return request.recordMeeting({locusUrl, recording: true, paused: false});
455
- }
456
-
457
- return Promise.reject(
458
- new PermissionError('Resume recording not allowed, due to moderator property.')
459
- );
460
- };
461
-
462
- MeetingUtil.stopRecording = (request, locusUrl, locusInfo) => {
463
- const displayHints = MeetingUtil.getUserDisplayHintsFromLocusInfo(locusInfo);
464
-
465
- if (MeetingUtil.canUserStop(displayHints)) {
466
- return request.recordMeeting({locusUrl, recording: false, paused: false});
467
- }
468
-
469
- return Promise.reject(
470
- new PermissionError('Stop recording not allowed, due to moderator property.')
471
- );
472
- };
473
-
474
414
  MeetingUtil.canUserRaiseHand = (displayHints) => displayHints.includes(DISPLAY_HINTS.RAISE_HAND);
475
415
 
476
416
  MeetingUtil.canUserLowerAllHands = (displayHints) =>
@@ -19,6 +19,7 @@ export class MeetingInfoV2PasswordError extends Error {
19
19
  meetingInfo: any;
20
20
  sdkMessage: any;
21
21
  wbxAppApiCode: any;
22
+ body: any;
22
23
 
23
24
  /**
24
25
  *
@@ -70,6 +71,7 @@ export class MeetingInfoV2CaptchaError extends Error {
70
71
  isPasswordRequired: any;
71
72
  sdkMessage: any;
72
73
  wbxAppApiCode: any;
74
+ body: any;
73
75
  /**
74
76
  *
75
77
  * @constructor
@@ -221,6 +221,7 @@ export default class Meetings extends WebexPlugin {
221
221
  // @ts-ignore
222
222
  this.meetingCollection.getByKey(
223
223
  CORRELATION_ID,
224
+ // @ts-ignore
224
225
  MeetingsUtil.checkForCorrelationId(this.webex.internal.device.url, data.locus)
225
226
  ) ||
226
227
  this.meetingCollection.getByKey(
@@ -440,11 +441,14 @@ export default class Meetings extends WebexPlugin {
440
441
  */
441
442
  // @ts-ignore
442
443
  this.meetingInfo = this.config.experimental.enableUnifiedMeetings
443
- ? new MeetingInfoV2(this.webex)
444
- : new MeetingInfo(this.webex);
444
+ ? // @ts-ignore
445
+ new MeetingInfoV2(this.webex)
446
+ : // @ts-ignore
447
+ new MeetingInfo(this.webex);
445
448
  // @ts-ignore
446
449
  this.personalMeetingRoom = new PersonalMeetingRoom(
447
450
  {meetingInfo: this.meetingInfo},
451
+ // @ts-ignore
448
452
  {parent: this.webex}
449
453
  );
450
454
 
@@ -554,6 +558,7 @@ export default class Meetings extends WebexPlugin {
554
558
  // @ts-ignore
555
559
  .then(() =>
556
560
  LoggerProxy.logger.info(
561
+ // @ts-ignore
557
562
  `Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
558
563
  )
559
564
  )
@@ -607,8 +612,8 @@ export default class Meetings extends WebexPlugin {
607
612
 
608
613
  this.stopListeningForEvents();
609
614
 
610
- // @ts-ignore
611
615
  return (
616
+ // @ts-ignore
612
617
  this.webex.internal.mercury
613
618
  .disconnect()
614
619
  // @ts-ignore
@@ -53,9 +53,9 @@ export default class MeetingRequest extends StatelessWebexPlugin {
53
53
  */
54
54
  determineRedirections(responseBody: any) {
55
55
  if (responseBody.remoteLocusClusterUrls && responseBody.remoteLocusClusterUrls.length) {
56
- // @ts-ignore
57
56
  return Promise.all(
58
57
  responseBody.remoteLocusClusterUrls.map((url) =>
58
+ // @ts-ignore
59
59
  this.request({
60
60
  method: HTTP_VERBS.GET,
61
61
  url,
@@ -72,7 +72,7 @@ MemberUtil.isAssociatedSame = (participant: any, id: string) =>
72
72
  * @param {String} status
73
73
  * @returns {Boolean}
74
74
  */
75
- MemberUtil.isNotAdmitted = (participant: any, isGuest: boolean, status: string) =>
75
+ MemberUtil.isNotAdmitted = (participant: any, isGuest: boolean, status: string): boolean =>
76
76
  participant &&
77
77
  participant.guest &&
78
78
  ((participant.devices &&
@@ -82,6 +82,7 @@ MemberUtil.isNotAdmitted = (participant: any, isGuest: boolean, status: string)
82
82
  // @ts-ignore
83
83
  isGuest &&
84
84
  status === _IN_LOBBY_) ||
85
+ // @ts-ignore
85
86
  !status === _IN_MEETING_);
86
87
 
87
88
  /**
@@ -140,6 +140,7 @@ export default class MembersRequest extends StatelessWebexPlugin {
140
140
  !options.locusUrl ||
141
141
  !options.memberId ||
142
142
  !options.url ||
143
+ // @ts-ignore
143
144
  (!options.tones && options.tones !== 0)
144
145
  ) {
145
146
  throw new ParameterError(
@@ -261,6 +261,7 @@ export default class Reachability {
261
261
 
262
262
  // @ts-ignore
263
263
  LoggerProxy.logger.log(
264
+ // @ts-ignore
264
265
  `Reachability:index#onIceGatheringStateChange --> Successfully pinged ${peerConnection.key}:`,
265
266
  elapsed
266
267
  );
@@ -284,8 +285,8 @@ export default class Reachability {
284
285
  if (e.candidate && String(e.candidate.type).toLowerCase() === SERVER_REFLEXIVE) {
285
286
  const elapsed = this.getElapsedTime(peerConnection);
286
287
 
287
- // @ts-ignore
288
288
  LoggerProxy.logger.log(
289
+ // @ts-ignore
289
290
  `Reachability:index#onIceCandidate --> Successfully pinged ${peerConnection.key}:`,
290
291
  elapsed
291
292
  );
@@ -5,7 +5,8 @@ export type EmoticonData = {
5
5
  };
6
6
 
7
7
  export type SkinTone = EmoticonData;
8
- export type Reaction = ReactionData & {
8
+ // @ts-ignore
9
+ export type Reaction = EmoticonData & {
9
10
  tone?: SkinTone;
10
11
  };
11
12
 
@@ -0,0 +1,8 @@
1
+ enum RecordingAction {
2
+ Start = 'Start',
3
+ Stop = 'Stop',
4
+ Pause = 'Pause',
5
+ Resume = 'Resume',
6
+ }
7
+
8
+ export default RecordingAction;