@webex/plugin-meetings 3.0.0-beta.94 → 3.0.0-beta.96

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 (35) hide show
  1. package/dist/breakouts/breakout.js +4 -3
  2. package/dist/breakouts/breakout.js.map +1 -1
  3. package/dist/breakouts/index.js +83 -52
  4. package/dist/breakouts/index.js.map +1 -1
  5. package/dist/constants.js +5 -1
  6. package/dist/constants.js.map +1 -1
  7. package/dist/controls-options-manager/index.js +19 -14
  8. package/dist/controls-options-manager/index.js.map +1 -1
  9. package/dist/meeting/in-meeting-actions.js +27 -3
  10. package/dist/meeting/in-meeting-actions.js.map +1 -1
  11. package/dist/meeting/index.js +138 -29
  12. package/dist/meeting/index.js.map +1 -1
  13. package/dist/meeting/util.js +0 -9
  14. package/dist/meeting/util.js.map +1 -1
  15. package/dist/metrics/index.js +5 -2
  16. package/dist/metrics/index.js.map +1 -1
  17. package/dist/types/constants.d.ts +3 -0
  18. package/dist/types/controls-options-manager/index.d.ts +1 -1
  19. package/dist/types/meeting/in-meeting-actions.d.ts +26 -2
  20. package/dist/types/meeting/index.d.ts +17 -6
  21. package/package.json +19 -19
  22. package/src/breakouts/breakout.ts +1 -0
  23. package/src/breakouts/index.ts +33 -5
  24. package/src/constants.ts +3 -0
  25. package/src/controls-options-manager/index.ts +13 -10
  26. package/src/meeting/in-meeting-actions.ts +52 -4
  27. package/src/meeting/index.ts +144 -29
  28. package/src/meeting/util.ts +0 -11
  29. package/src/metrics/index.ts +5 -2
  30. package/test/unit/spec/breakouts/index.ts +83 -103
  31. package/test/unit/spec/controls-options-manager/index.js +8 -1
  32. package/test/unit/spec/meeting/in-meeting-actions.ts +26 -2
  33. package/test/unit/spec/meeting/index.js +91 -5
  34. package/test/unit/spec/meeting/utils.js +0 -21
  35. package/test/unit/spec/meetings/index.js +55 -0
@@ -105,12 +105,17 @@ const Breakouts = WebexPlugin.extend({
105
105
  leading: true,
106
106
  trailing: false,
107
107
  });
108
- this.listenTo(this.breakouts, 'add', () => {
108
+ this.listenTo(this.breakouts, 'add', (breakout) => {
109
109
  this.debouncedQueryRosters();
110
+ this.triggerReturnToMainEvent(breakout);
111
+ });
112
+ this.listenTo(this.breakouts, 'change:requestedLastModifiedTime', (breakout) => {
113
+ this.triggerReturnToMainEvent(breakout);
110
114
  });
111
115
  this.listenToCurrentSessionTypeChange();
112
116
  this.listenToBroadcastMessages();
113
117
  this.listenToBreakoutRosters();
118
+ this.listenToBreakoutHelp();
114
119
  // @ts-ignore
115
120
  this.breakoutRequest = new BreakoutRequest({webex: this.webex});
116
121
  },
@@ -234,6 +239,19 @@ const Breakouts = WebexPlugin.extend({
234
239
  });
235
240
  },
236
241
 
242
+ /**
243
+ * Sets up a listener for ask help notify from mecury
244
+ * @returns {void}
245
+ */
246
+ listenToBreakoutHelp() {
247
+ this.listenTo(this.webex.internal.mercury, 'event:breakout.help', (event) => {
248
+ const {
249
+ data: {participant, sessionId},
250
+ } = event;
251
+ this.trigger(BREAKOUTS.EVENTS.ASK_FOR_HELP, {participant, sessionId});
252
+ });
253
+ },
254
+
237
255
  /**
238
256
  * Updates the information about the current breakout
239
257
  * @param {Object} params
@@ -301,6 +319,10 @@ const Breakouts = WebexPlugin.extend({
301
319
  }
302
320
 
303
321
  breakouts[sessionId][state] = true;
322
+
323
+ if (state === BREAKOUTS.SESSION_STATES.REQUESTED) {
324
+ breakouts[sessionId].requestedLastModifiedTime = breakout.modifiedAt;
325
+ }
304
326
  });
305
327
  });
306
328
  }
@@ -311,10 +333,6 @@ const Breakouts = WebexPlugin.extend({
311
333
  });
312
334
 
313
335
  this.breakouts.set(Object.values(breakouts));
314
-
315
- if (this.allowBackToMain && this.getMainSession().requested) {
316
- this.trigger(BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN);
317
- }
318
336
  },
319
337
  /**
320
338
  * get main session
@@ -786,6 +804,16 @@ const Breakouts = WebexPlugin.extend({
786
804
  body,
787
805
  });
788
806
  },
807
+ /**
808
+ * trigger ASK_RETURN_TO_MAIN event when main session requested
809
+ * @param {Object} breakout
810
+ * @returns {void}
811
+ */
812
+ triggerReturnToMainEvent(breakout) {
813
+ if (breakout.isMain && breakout.requested) {
814
+ this.trigger(BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN);
815
+ }
816
+ },
789
817
  });
790
818
 
791
819
  export default Breakouts;
package/src/constants.ts CHANGED
@@ -315,6 +315,7 @@ export const EVENT_TRIGGERS = {
315
315
  MEETING_BREAKOUTS_MESSAGE: 'meeting:breakouts:message',
316
316
  MEETING_BREAKOUTS_ASK_RETURN_TO_MAIN: 'meeting:breakouts:askReturnToMain',
317
317
  MEETING_BREAKOUTS_LEAVE: 'meeting:breakouts:leave',
318
+ MEETING_BREAKOUTS_ASK_FOR_HELP: 'meeting:breakouts:askForHelp',
318
319
  MEMBERS_UPDATE: 'members:update',
319
320
  MEMBERS_CLEAR: 'members:clear',
320
321
  MEMBERS_CONTENT_UPDATE: 'members:content:update',
@@ -368,6 +369,7 @@ export const MEETING_REMOVED_REASON = {
368
369
  FULLSTATE_REMOVED: 'FULLSTATE_REMOVED', // meeting got dropped ? not sure
369
370
  MEETING_INACTIVE_TERMINATING: 'MEETING_INACTIVE_TERMINATING', // Meeting got ended or everyone left the meeting
370
371
  CLIENT_LEAVE_REQUEST: 'CLIENT_LEAVE_REQUEST', // You triggered leave meeting
372
+ CLIENT_LEAVE_REQUEST_TAB_CLOSED: 'CLIENT_LEAVE_REQUEST_TAB_CLOSED', // You triggered leave meeting, such as closing the browser tab directly
371
373
  USER_ENDED_SHARE_STREAMS: 'USER_ENDED_SHARE_STREAMS', // user triggered stop share
372
374
  NO_MEETINGS_TO_SYNC: 'NO_MEETINGS_TO_SYNC', // After the syncMeeting no meeting exists
373
375
  MEETING_CONNECTION_FAILED: 'MEETING_CONNECTION_FAILED', // meeting failed to connect due to ice failures or firewall issue
@@ -549,6 +551,7 @@ export const BREAKOUTS = {
549
551
  MEMBERS_UPDATE: 'MEMBERS_UPDATE',
550
552
  ASK_RETURN_TO_MAIN: 'ASK_RETURN_TO_MAIN',
551
553
  LEAVE_BREAKOUT: 'LEAVE_BREAKOUT',
554
+ ASK_FOR_HELP: 'ASK_FOR_HELP',
552
555
  },
553
556
  SESSION_TYPES: {
554
557
  MAIN: 'MAIN',
@@ -140,8 +140,8 @@ export default class ControlsOptionsManager {
140
140
  * @param {Array<ControlConfig>} controls - Spread Array of ControlConfigs
141
141
  * @returns {Promise<Array<any>>}- Promise resolving if the request was successful.
142
142
  */
143
- protected update(...controls: Array<ControlConfig>) {
144
- const payload = controls.reduce((output, control) => {
143
+ public update(...controls: Array<ControlConfig>) {
144
+ const payloads = controls.map((control) => {
145
145
  if (!Object.keys(Control).includes(control.scope)) {
146
146
  throw new Error(
147
147
  `updating meeting control scope "${control.scope}" is not a supported scope`
@@ -155,17 +155,20 @@ export default class ControlsOptionsManager {
155
155
  }
156
156
 
157
157
  return {
158
- ...output,
159
158
  [control.scope]: control.properties,
160
159
  };
161
- }, {});
162
-
163
- // @ts-ignore
164
- return this.request.request({
165
- uri: `${this.locusUrl}/${CONTROLS}`,
166
- body: payload,
167
- method: HTTP_VERBS.PATCH,
168
160
  });
161
+
162
+ return payloads.reduce((previous, payload) => {
163
+ return previous.then(() =>
164
+ // @ts-ignore
165
+ this.request.request({
166
+ uri: `${this.locusUrl}/${CONTROLS}`,
167
+ body: payload,
168
+ method: HTTP_VERBS.PATCH,
169
+ })
170
+ );
171
+ }, Promise.resolve());
169
172
  }
170
173
 
171
174
  /**
@@ -40,7 +40,6 @@ interface IInMeetingActions {
40
40
  isRealTimeTranslationEnabled?: boolean;
41
41
  canSelectSpokenLanguages?: boolean;
42
42
  waitingForOthersToJoin?: boolean;
43
- canEnableReactions?: boolean;
44
43
  canSendReactions?: boolean;
45
44
  canManageBreakout?: boolean;
46
45
  canAdmitLobbyToBreakout?: boolean;
@@ -48,6 +47,19 @@ interface IInMeetingActions {
48
47
  canUserAskForHelp?: boolean;
49
48
  canUserRenameSelfAndObserved?: boolean;
50
49
  canUserRenameOthers?: boolean;
50
+ canMuteAll?: boolean;
51
+ canUnmuteAll?: boolean;
52
+ canEnableHardMute?: boolean;
53
+ canDisableHardMute?: boolean;
54
+ canEnableMuteOnEntry?: boolean;
55
+ canDisableMuteOnEntry?: boolean;
56
+ canEnableReactions?: boolean;
57
+ canDisableReactions?: boolean;
58
+ canEnableReactionDisplayNames?: boolean;
59
+ canDisableReactionDisplayNames?: boolean;
60
+ canUpdateShareControl?: boolean;
61
+ canEnableViewTheParticipantsList?: boolean;
62
+ canDisableViewTheParticipantsList?: boolean;
51
63
  }
52
64
 
53
65
  /**
@@ -118,8 +130,6 @@ export default class InMeetingActions implements IInMeetingActions {
118
130
 
119
131
  waitingForOthersToJoin = null;
120
132
 
121
- canEnableReactions = null;
122
-
123
133
  canSendReactions = null;
124
134
 
125
135
  canManageBreakout = null;
@@ -134,6 +144,32 @@ export default class InMeetingActions implements IInMeetingActions {
134
144
 
135
145
  canUserRenameOthers = null;
136
146
 
147
+ canMuteAll = null;
148
+
149
+ canUnmuteAll = null;
150
+
151
+ canEnableHardMute = null;
152
+
153
+ canDisableHardMute = null;
154
+
155
+ canEnableMuteOnEntry = null;
156
+
157
+ canDisableMuteOnEntry = null;
158
+
159
+ canEnableReactions = null;
160
+
161
+ canDisableReactions = null;
162
+
163
+ canEnableReactionDisplayNames = null;
164
+
165
+ canDisableReactionDisplayNames = null;
166
+
167
+ canUpdateShareControl = null;
168
+
169
+ canEnableViewTheParticipantsList = null;
170
+
171
+ canDisableViewTheParticipantsList = null;
172
+
137
173
  /**
138
174
  * Returns all meeting action options
139
175
  * @returns {Object}
@@ -170,7 +206,6 @@ export default class InMeetingActions implements IInMeetingActions {
170
206
  isRealTimeTranslationEnabled: this.isRealTimeTranslationEnabled,
171
207
  canSelectSpokenLanguages: this.canSelectSpokenLanguages,
172
208
  waitingForOthersToJoin: this.waitingForOthersToJoin,
173
- canEnableReactions: this.canEnableReactions,
174
209
  canSendReactions: this.canSendReactions,
175
210
  canManageBreakout: this.canManageBreakout,
176
211
  canAdmitLobbyToBreakout: this.canAdmitLobbyToBreakout,
@@ -178,6 +213,19 @@ export default class InMeetingActions implements IInMeetingActions {
178
213
  canUserAskForHelp: this.canUserAskForHelp,
179
214
  canUserRenameSelfAndObserved: this.canUserRenameSelfAndObserved,
180
215
  canUserRenameOthers: this.canUserRenameOthers,
216
+ canMuteAll: this.canMuteAll,
217
+ canUnmuteAll: this.canUnmuteAll,
218
+ canEnableHardMute: this.canEnableHardMute,
219
+ canDisableHardMute: this.canDisableHardMute,
220
+ canEnableMuteOnEntry: this.canEnableMuteOnEntry,
221
+ canDisableMuteOnEntry: this.canDisableMuteOnEntry,
222
+ canEnableReactions: this.canEnableReactions,
223
+ canDisableReactions: this.canDisableReactions,
224
+ canEnableReactionDisplayNames: this.canEnableReactionDisplayNames,
225
+ canDisableReactionDisplayNames: this.canDisableReactionDisplayNames,
226
+ canUpdateShareControl: this.canUpdateShareControl,
227
+ canEnableViewTheParticipantsList: this.canEnableViewTheParticipantsList,
228
+ canDisableViewTheParticipantsList: this.canDisableViewTheParticipantsList,
181
229
  });
182
230
 
183
231
  /**
@@ -2,6 +2,7 @@ import uuid from 'uuid';
2
2
  import {cloneDeep, isEqual, pick, isString, defer} from 'lodash';
3
3
  // @ts-ignore - Fix this
4
4
  import {StatelessWebexPlugin} from '@webex/webex-core';
5
+ import {base64} from '@webex/common';
5
6
  import {
6
7
  ConnectionState,
7
8
  Errors,
@@ -62,6 +63,7 @@ import {
62
63
  _JOIN_,
63
64
  AUDIO,
64
65
  CONTENT,
66
+ DISPLAY_HINTS,
65
67
  ENDED,
66
68
  EVENT_TRIGGERS,
67
69
  EVENT_TYPES,
@@ -90,6 +92,7 @@ import {
90
92
  VIDEO_RESOLUTIONS,
91
93
  VIDEO,
92
94
  HTTP_VERBS,
95
+ SELF_ROLES,
93
96
  } from '../constants';
94
97
  import BEHAVIORAL_METRICS from '../metrics/constants';
95
98
  import ParameterError from '../common/errors/parameter';
@@ -508,12 +511,12 @@ export default class Meeting extends StatelessWebexPlugin {
508
511
  statsAnalyzer: StatsAnalyzer;
509
512
  transcription: Transcription;
510
513
  updateMediaConnections: (mediaConnections: any[]) => void;
511
- endCallInitiateJoinReq: any;
514
+ endCallInitJoinReq: any;
512
515
  endJoinReqResp: any;
513
516
  endLocalSDPGenRemoteSDPRecvDelay: any;
514
517
  joinedWith: any;
515
518
  locusId: any;
516
- startCallInitiateJoinReq: any;
519
+ startCallInitJoinReq: any;
517
520
  startJoinReqResp: any;
518
521
  startLocalSDPGenRemoteSDPRecvDelay: any;
519
522
  wirelessShare: any;
@@ -528,8 +531,8 @@ export default class Meeting extends StatelessWebexPlugin {
528
531
  state: any;
529
532
  localAudioTrackMuteStateHandler: (event: TrackMuteEvent) => void;
530
533
  localVideoTrackMuteStateHandler: (event: TrackMuteEvent) => void;
531
- webexMeetingId: string;
532
-
534
+ roles: any[];
535
+ environment: string;
533
536
  namespace = MEETINGS;
534
537
 
535
538
  /**
@@ -1481,6 +1484,18 @@ export default class Meeting extends StatelessWebexPlugin {
1481
1484
  EVENT_TRIGGERS.MEETING_BREAKOUTS_LEAVE
1482
1485
  );
1483
1486
  });
1487
+
1488
+ this.breakouts.on(BREAKOUTS.EVENTS.ASK_FOR_HELP, (helpEvent) => {
1489
+ Trigger.trigger(
1490
+ this,
1491
+ {
1492
+ file: 'meeting/index',
1493
+ function: 'setUpBreakoutsListener',
1494
+ },
1495
+ EVENT_TRIGGERS.MEETING_BREAKOUTS_ASK_FOR_HELP,
1496
+ helpEvent
1497
+ );
1498
+ });
1484
1499
  }
1485
1500
 
1486
1501
  /**
@@ -1696,12 +1711,12 @@ export default class Meeting extends StatelessWebexPlugin {
1696
1711
  };
1697
1712
  }
1698
1713
 
1699
- const callInitiateJoinReq = this.getCallInitiateJoinReq();
1714
+ const callInitJoinReq = this.getCallInitJoinReq();
1700
1715
 
1701
- if (callInitiateJoinReq) {
1716
+ if (callInitJoinReq) {
1702
1717
  options.joinTimes = {
1703
1718
  ...options.joinTimes,
1704
- callInitiateJoinReq,
1719
+ callInitJoinReq,
1705
1720
  };
1706
1721
  }
1707
1722
 
@@ -1714,15 +1729,31 @@ export default class Meeting extends StatelessWebexPlugin {
1714
1729
  };
1715
1730
  }
1716
1731
 
1717
- const getTotalJmt = this.getTotalJmt();
1732
+ const totalJmt = this.getTotalJmt();
1718
1733
 
1719
- if (getTotalJmt) {
1734
+ if (totalJmt) {
1720
1735
  options.joinTimes = {
1721
1736
  ...options.joinTimes,
1722
- getTotalJmt,
1737
+ totalJmt,
1723
1738
  };
1724
1739
  }
1725
1740
 
1741
+ const curUserType = this.getCurUserType();
1742
+
1743
+ if (curUserType) {
1744
+ options.userType = curUserType;
1745
+ }
1746
+
1747
+ const curLoginType = this.getCurLoginType();
1748
+
1749
+ if (curLoginType) {
1750
+ options.loginType = curLoginType;
1751
+ }
1752
+
1753
+ if (this.environment) {
1754
+ options.environment = this.environment;
1755
+ }
1756
+
1726
1757
  if (options.type === MQA_STATS.CA_TYPE) {
1727
1758
  payload = Metrics.initMediaPayload(options.event, identifiers, options);
1728
1759
  } else {
@@ -2430,10 +2461,6 @@ export default class Meeting extends StatelessWebexPlugin {
2430
2461
  payload.info.userDisplayHints
2431
2462
  ),
2432
2463
  waitingForOthersToJoin: MeetingUtil.waitingForOthersToJoin(payload.info.userDisplayHints),
2433
- canEnableReactions: MeetingUtil.canEnableReactions(
2434
- this.inMeetingActions.canEnableReactions,
2435
- payload.info.userDisplayHints
2436
- ),
2437
2464
  canSendReactions: MeetingUtil.canSendReactions(
2438
2465
  this.inMeetingActions.canSendReactions,
2439
2466
  payload.info.userDisplayHints
@@ -2450,6 +2477,58 @@ export default class Meeting extends StatelessWebexPlugin {
2450
2477
  payload.info.userDisplayHints
2451
2478
  ),
2452
2479
  canUserRenameOthers: MeetingUtil.canUserRenameOthers(payload.info.userDisplayHints),
2480
+ canMuteAll: ControlsOptionsUtil.hasHints({
2481
+ requiredHints: [DISPLAY_HINTS.MUTE_ALL],
2482
+ displayHints: payload.info.userDisplayHints,
2483
+ }),
2484
+ canUnmuteAll: ControlsOptionsUtil.hasHints({
2485
+ requiredHints: [DISPLAY_HINTS.UNMUTE_ALL],
2486
+ displayHints: payload.info.userDisplayHints,
2487
+ }),
2488
+ canEnableHardMute: ControlsOptionsUtil.hasHints({
2489
+ requiredHints: [DISPLAY_HINTS.ENABLE_HARD_MUTE],
2490
+ displayHints: payload.info.userDisplayHints,
2491
+ }),
2492
+ canDisableHardMute: ControlsOptionsUtil.hasHints({
2493
+ requiredHints: [DISPLAY_HINTS.DISABLE_HARD_MUTE],
2494
+ displayHints: payload.info.userDisplayHints,
2495
+ }),
2496
+ canEnableMuteOnEntry: ControlsOptionsUtil.hasHints({
2497
+ requiredHints: [DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY],
2498
+ displayHints: payload.info.userDisplayHints,
2499
+ }),
2500
+ canDisableMuteOnEntry: ControlsOptionsUtil.hasHints({
2501
+ requiredHints: [DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY],
2502
+ displayHints: payload.info.userDisplayHints,
2503
+ }),
2504
+ canEnableReactions: ControlsOptionsUtil.hasHints({
2505
+ requiredHints: [DISPLAY_HINTS.ENABLE_REACTIONS],
2506
+ displayHints: payload.info.userDisplayHints,
2507
+ }),
2508
+ canDisableReactions: ControlsOptionsUtil.hasHints({
2509
+ requiredHints: [DISPLAY_HINTS.DISABLE_REACTIONS],
2510
+ displayHints: payload.info.userDisplayHints,
2511
+ }),
2512
+ canEnableReactionDisplayNames: ControlsOptionsUtil.hasHints({
2513
+ requiredHints: [DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME],
2514
+ displayHints: payload.info.userDisplayHints,
2515
+ }),
2516
+ canDisableReactionDisplayNames: ControlsOptionsUtil.hasHints({
2517
+ requiredHints: [DISPLAY_HINTS.DISABLE_SHOW_DISPLAY_NAME],
2518
+ displayHints: payload.info.userDisplayHints,
2519
+ }),
2520
+ canUpdateShareControl: ControlsOptionsUtil.hasHints({
2521
+ requiredHints: [DISPLAY_HINTS.SHARE_CONTROL],
2522
+ displayHints: payload.info.userDisplayHints,
2523
+ }),
2524
+ canEnableViewTheParticipantsList: ControlsOptionsUtil.hasHints({
2525
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST],
2526
+ displayHints: payload.info.userDisplayHints,
2527
+ }),
2528
+ canDisableViewTheParticipantsList: ControlsOptionsUtil.hasHints({
2529
+ requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST],
2530
+ displayHints: payload.info.userDisplayHints,
2531
+ }),
2453
2532
  });
2454
2533
 
2455
2534
  this.recordingController.setDisplayHints(payload.info.userDisplayHints);
@@ -3047,6 +3126,8 @@ export default class Meeting extends StatelessWebexPlugin {
3047
3126
  webexMeetingInfo?.hostId ||
3048
3127
  this.owner;
3049
3128
  this.permissionToken = webexMeetingInfo?.permissionToken;
3129
+ // Need to populate environment when sending CA event
3130
+ this.environment = locusMeetingObject?.info.channel || webexMeetingInfo?.channel;
3050
3131
  }
3051
3132
  }
3052
3133
 
@@ -6086,13 +6167,12 @@ export default class Meeting extends StatelessWebexPlugin {
6086
6167
  * @memberof Meeting
6087
6168
  */
6088
6169
  public leave(options: {resourceId?: string; reason?: any} = {} as any) {
6170
+ const leaveReason = options.reason || MEETING_REMOVED_REASON.CLIENT_LEAVE_REQUEST;
6089
6171
  Metrics.postEvent({
6090
6172
  event: eventType.LEAVE,
6091
6173
  meeting: this,
6092
- data: {trigger: trigger.USER_INTERACTION, canProceed: false},
6174
+ data: {trigger: trigger.USER_INTERACTION, canProceed: false, reason: leaveReason},
6093
6175
  });
6094
- const leaveReason = options.reason || MEETING_REMOVED_REASON.CLIENT_LEAVE_REQUEST;
6095
-
6096
6176
  LoggerProxy.logger.log('Meeting:index#leave --> Leaving a meeting');
6097
6177
 
6098
6178
  return MeetingUtil.leaveMeeting(this, options)
@@ -7020,7 +7100,7 @@ export default class Meeting extends StatelessWebexPlugin {
7020
7100
  const end = this.endLocalSDPGenRemoteSDPRecvDelay;
7021
7101
 
7022
7102
  if (start && end) {
7023
- const calculatedDelay = end - start;
7103
+ const calculatedDelay = Math.round(end - start);
7024
7104
 
7025
7105
  return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
7026
7106
  }
@@ -7032,26 +7112,26 @@ export default class Meeting extends StatelessWebexPlugin {
7032
7112
  *
7033
7113
  * @returns {undefined}
7034
7114
  */
7035
- setStartCallInitiateJoinReq() {
7036
- this.startCallInitiateJoinReq = performance.now();
7037
- this.endCallInitiateJoinReq = undefined;
7115
+ setStartCallInitJoinReq() {
7116
+ this.startCallInitJoinReq = performance.now();
7117
+ this.endCallInitJoinReq = undefined;
7038
7118
  }
7039
7119
 
7040
7120
  /**
7041
7121
  *
7042
7122
  * @returns {undefined}
7043
7123
  */
7044
- setEndCallInitiateJoinReq() {
7045
- this.endCallInitiateJoinReq = performance.now();
7124
+ setEndCallInitJoinReq() {
7125
+ this.endCallInitJoinReq = performance.now();
7046
7126
  }
7047
7127
 
7048
7128
  /**
7049
7129
  *
7050
7130
  * @returns {string} duration between call initiate and sending join request to locus
7051
7131
  */
7052
- getCallInitiateJoinReq() {
7053
- const start = this.startCallInitiateJoinReq;
7054
- const end = this.endCallInitiateJoinReq;
7132
+ getCallInitJoinReq() {
7133
+ const start = this.startCallInitJoinReq;
7134
+ const end = this.endCallInitJoinReq;
7055
7135
 
7056
7136
  if (start && end) {
7057
7137
  const calculatedDelay = end - start;
@@ -7088,7 +7168,7 @@ export default class Meeting extends StatelessWebexPlugin {
7088
7168
  const end = this.endJoinReqResp;
7089
7169
 
7090
7170
  if (start && end) {
7091
- const calculatedDelay = end - start;
7171
+ const calculatedDelay = Math.round(end - start);
7092
7172
 
7093
7173
  return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
7094
7174
  }
@@ -7101,10 +7181,45 @@ export default class Meeting extends StatelessWebexPlugin {
7101
7181
  * @returns {string} duration between call initiate and successful locus join (even if it is in lobby)
7102
7182
  */
7103
7183
  getTotalJmt() {
7104
- const start = this.startCallInitiateJoinReq;
7184
+ const start = this.startCallInitJoinReq;
7105
7185
  const end = this.endJoinReqResp;
7106
7186
 
7107
- return start && end ? end - start : undefined;
7187
+ return start && end ? Math.round(end - start) : undefined;
7188
+ }
7189
+
7190
+ /**
7191
+ *
7192
+ * @returns {string} one of 'attendee','host','cohost', returns the user type of the current user
7193
+ */
7194
+ getCurUserType() {
7195
+ const {roles} = this;
7196
+ if (roles) {
7197
+ if (roles.includes(SELF_ROLES.MODERATOR)) {
7198
+ return 'host';
7199
+ }
7200
+ if (roles.includes(SELF_ROLES.COHOST)) {
7201
+ return 'cohost';
7202
+ }
7203
+ if (roles.includes(SELF_ROLES.ATTENDEE)) {
7204
+ return 'attendee';
7205
+ }
7206
+ }
7207
+
7208
+ return null;
7209
+ }
7210
+
7211
+ /**
7212
+ *
7213
+ * @returns {string} one of 'login-ci','unverified-guest', returns the login type of the current user
7214
+ */
7215
+ getCurLoginType() {
7216
+ // @ts-ignore
7217
+ if (this.webex.canAuthorize) {
7218
+ // @ts-ignore
7219
+ return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';
7220
+ }
7221
+
7222
+ return null;
7108
7223
  }
7109
7224
 
7110
7225
  /**
@@ -497,17 +497,6 @@ MeetingUtil.canSelectSpokenLanguages = (displayHints) =>
497
497
  MeetingUtil.waitingForOthersToJoin = (displayHints) =>
498
498
  displayHints.includes(DISPLAY_HINTS.WAITING_FOR_OTHERS);
499
499
 
500
- MeetingUtil.canEnableReactions = (originalValue, displayHints) => {
501
- if (displayHints.includes(DISPLAY_HINTS.ENABLE_REACTIONS)) {
502
- return true;
503
- }
504
- if (displayHints.includes(DISPLAY_HINTS.DISABLE_REACTIONS)) {
505
- return false;
506
- }
507
-
508
- return originalValue;
509
- };
510
-
511
500
  MeetingUtil.canSendReactions = (originalValue, displayHints) => {
512
501
  if (displayHints.includes(DISPLAY_HINTS.REACTIONS_ACTIVE)) {
513
502
  return true;
@@ -31,10 +31,10 @@ const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);
31
31
  const triggerTimers = ({event, meeting, data}) => {
32
32
  switch (event) {
33
33
  case eventType.CALL_INITIATED:
34
- meeting.setStartCallInitiateJoinReq();
34
+ meeting.setStartCallInitJoinReq();
35
35
  break;
36
36
  case eventType.LOCUS_JOIN_REQUEST:
37
- meeting.setEndCallInitiateJoinReq();
37
+ meeting.setEndCallInitJoinReq();
38
38
  meeting.setStartJoinReqResp();
39
39
  break;
40
40
  case eventType.LOCUS_JOIN_RESPONSE:
@@ -189,6 +189,9 @@ class Metrics {
189
189
  name: 'endpoint',
190
190
  networkType: 'unknown',
191
191
  userAgent: this.userAgentToString(),
192
+ userType: options.userType,
193
+ loginType: options.loginType,
194
+ channel: options.channel,
192
195
  clientInfo: {
193
196
  clientType: options.clientType,
194
197
  clientVersion: `${CLIENT_NAME}/${this.webex.version}`,