@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.
- package/dist/breakouts/breakout.js +4 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/index.js +83 -52
- package/dist/breakouts/index.js.map +1 -1
- package/dist/constants.js +5 -1
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +19 -14
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +27 -3
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +138 -29
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +0 -9
- package/dist/meeting/util.js.map +1 -1
- package/dist/metrics/index.js +5 -2
- package/dist/metrics/index.js.map +1 -1
- package/dist/types/constants.d.ts +3 -0
- package/dist/types/controls-options-manager/index.d.ts +1 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +26 -2
- package/dist/types/meeting/index.d.ts +17 -6
- package/package.json +19 -19
- package/src/breakouts/breakout.ts +1 -0
- package/src/breakouts/index.ts +33 -5
- package/src/constants.ts +3 -0
- package/src/controls-options-manager/index.ts +13 -10
- package/src/meeting/in-meeting-actions.ts +52 -4
- package/src/meeting/index.ts +144 -29
- package/src/meeting/util.ts +0 -11
- package/src/metrics/index.ts +5 -2
- package/test/unit/spec/breakouts/index.ts +83 -103
- package/test/unit/spec/controls-options-manager/index.js +8 -1
- package/test/unit/spec/meeting/in-meeting-actions.ts +26 -2
- package/test/unit/spec/meeting/index.js +91 -5
- package/test/unit/spec/meeting/utils.js +0 -21
- package/test/unit/spec/meetings/index.js +55 -0
package/src/breakouts/index.ts
CHANGED
|
@@ -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
|
-
|
|
144
|
-
const
|
|
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
|
/**
|
package/src/meeting/index.ts
CHANGED
|
@@ -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
|
-
|
|
514
|
+
endCallInitJoinReq: any;
|
|
512
515
|
endJoinReqResp: any;
|
|
513
516
|
endLocalSDPGenRemoteSDPRecvDelay: any;
|
|
514
517
|
joinedWith: any;
|
|
515
518
|
locusId: any;
|
|
516
|
-
|
|
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
|
-
|
|
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
|
|
1714
|
+
const callInitJoinReq = this.getCallInitJoinReq();
|
|
1700
1715
|
|
|
1701
|
-
if (
|
|
1716
|
+
if (callInitJoinReq) {
|
|
1702
1717
|
options.joinTimes = {
|
|
1703
1718
|
...options.joinTimes,
|
|
1704
|
-
|
|
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
|
|
1732
|
+
const totalJmt = this.getTotalJmt();
|
|
1718
1733
|
|
|
1719
|
-
if (
|
|
1734
|
+
if (totalJmt) {
|
|
1720
1735
|
options.joinTimes = {
|
|
1721
1736
|
...options.joinTimes,
|
|
1722
|
-
|
|
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
|
-
|
|
7036
|
-
this.
|
|
7037
|
-
this.
|
|
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
|
-
|
|
7045
|
-
this.
|
|
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
|
-
|
|
7053
|
-
const start = this.
|
|
7054
|
-
const end = this.
|
|
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.
|
|
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
|
/**
|
package/src/meeting/util.ts
CHANGED
|
@@ -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;
|
package/src/metrics/index.ts
CHANGED
|
@@ -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.
|
|
34
|
+
meeting.setStartCallInitJoinReq();
|
|
35
35
|
break;
|
|
36
36
|
case eventType.LOCUS_JOIN_REQUEST:
|
|
37
|
-
meeting.
|
|
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}`,
|