@webex/plugin-meetings 3.9.0-webinar5k.1 → 3.10.0-multi-llms.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/common/errors/webex-errors.js +21 -1
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/constants.js +25 -0
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +22 -5
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +116 -0
- package/dist/interceptors/locusRouteToken.js.map +1 -0
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +11 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +76 -322
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/parser.js +4 -1
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/media/index.js +5 -0
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +53 -5
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +14 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +468 -278
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +177 -14
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/type.js +7 -0
- package/dist/meeting/type.js.map +1 -0
- package/dist/meeting/util.js +100 -3
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +29 -21
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +20 -16
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +9 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +10 -0
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +10 -7
- package/dist/members/index.js.map +1 -1
- package/dist/members/util.js +7 -2
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +34 -5
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +42 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/reachability/index.js +3 -3
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/common/errors/webex-errors.d.ts +12 -0
- package/dist/types/constants.d.ts +23 -0
- package/dist/types/controls-options-manager/index.d.ts +9 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/interceptors/locusRouteToken.d.ts +38 -0
- package/dist/types/locus-info/index.d.ts +9 -54
- package/dist/types/media/properties.d.ts +21 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +14 -0
- package/dist/types/meeting/index.d.ts +64 -29
- package/dist/types/meeting/request.d.ts +42 -0
- package/dist/types/meeting/type.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +13 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
- package/dist/types/meetings/index.d.ts +3 -1
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/members/index.d.ts +12 -11
- package/dist/types/members/util.d.ts +8 -4
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/remoteMedia.d.ts +20 -1
- package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +26 -28
- package/src/common/errors/webex-errors.ts +19 -0
- package/src/constants.ts +26 -2
- package/src/controls-options-manager/index.ts +26 -5
- package/src/index.ts +4 -1
- package/src/interceptors/index.ts +2 -1
- package/src/interceptors/locusRouteToken.ts +80 -0
- package/src/locus-info/controlsUtils.ts +18 -0
- package/src/locus-info/index.ts +69 -357
- package/src/locus-info/parser.ts +5 -1
- package/src/media/index.ts +6 -0
- package/src/media/properties.ts +43 -0
- package/src/meeting/in-meeting-actions.ts +29 -0
- package/src/meeting/index.ts +299 -88
- package/src/meeting/request.ts +141 -0
- package/src/meeting/type.ts +9 -0
- package/src/meeting/util.ts +107 -3
- package/src/meeting-info/meeting-info-v2.ts +24 -5
- package/src/meetings/index.ts +15 -22
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +14 -0
- package/src/members/index.ts +20 -10
- package/src/members/util.ts +20 -3
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +7 -7
- package/src/multistream/remoteMedia.ts +34 -4
- package/src/multistream/remoteMediaGroup.ts +37 -2
- package/src/reachability/index.ts +3 -3
- package/test/unit/spec/common/browser-detection.js +0 -24
- package/test/unit/spec/controls-options-manager/index.js +47 -0
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interceptors/locusRouteToken.ts +87 -0
- package/test/unit/spec/locus-info/index.js +80 -361
- package/test/unit/spec/locus-info/parser.js +3 -2
- package/test/unit/spec/media/index.ts +140 -9
- package/test/unit/spec/media/properties.ts +137 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +14 -0
- package/test/unit/spec/meeting/index.js +679 -82
- package/test/unit/spec/meeting/muteState.js +32 -6
- package/test/unit/spec/meeting/request.js +21 -0
- package/test/unit/spec/meeting/utils.js +170 -17
- package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
- package/test/unit/spec/meetings/index.js +12 -7
- package/test/unit/spec/member/util.js +24 -0
- package/test/unit/spec/members/collection.js +120 -0
- package/test/unit/spec/members/index.js +107 -2
- package/test/unit/spec/members/request.js +55 -0
- package/test/unit/spec/members/utils.js +116 -14
- package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
- package/test/unit/spec/multistream/remoteMedia.ts +66 -2
- package/test/unit/spec/reachability/index.ts +158 -3
- package/test/unit/spec/roap/turnDiscovery.ts +3 -3
- package/dist/hashTree/constants.js +0 -23
- package/dist/hashTree/constants.js.map +0 -1
- package/dist/hashTree/hashTree.js +0 -516
- package/dist/hashTree/hashTree.js.map +0 -1
- package/dist/hashTree/hashTreeParser.js +0 -521
- package/dist/hashTree/hashTreeParser.js.map +0 -1
- package/dist/types/hashTree/constants.d.ts +0 -8
- package/dist/types/hashTree/hashTree.d.ts +0 -128
- package/dist/types/hashTree/hashTreeParser.d.ts +0 -152
- package/src/hashTree/constants.ts +0 -12
- package/src/hashTree/hashTree.ts +0 -460
- package/src/hashTree/hashTreeParser.ts +0 -556
- package/test/unit/spec/hashTree/hashTree.ts +0 -394
- package/test/unit/spec/hashTree/hashTreeParser.ts +0 -156
package/src/meeting/index.ts
CHANGED
|
@@ -28,6 +28,9 @@ import {
|
|
|
28
28
|
StatsAnalyzerEventNames,
|
|
29
29
|
NetworkQualityEventNames,
|
|
30
30
|
NetworkQualityMonitor,
|
|
31
|
+
StatsMonitor,
|
|
32
|
+
StatsMonitorEventNames,
|
|
33
|
+
InboundAudioIssueSubTypes,
|
|
31
34
|
} from '@webex/internal-media-core';
|
|
32
35
|
|
|
33
36
|
import {
|
|
@@ -55,6 +58,7 @@ import {
|
|
|
55
58
|
NoMediaEstablishedYetError,
|
|
56
59
|
UserNotJoinedError,
|
|
57
60
|
AddMediaFailed,
|
|
61
|
+
SdpResponseTimeoutError,
|
|
58
62
|
} from '../common/errors/webex-errors';
|
|
59
63
|
|
|
60
64
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
@@ -66,7 +70,7 @@ import Media, {type BundlePolicy} from '../media';
|
|
|
66
70
|
import MediaProperties from '../media/properties';
|
|
67
71
|
import MeetingStateMachine from './state';
|
|
68
72
|
import {createMuteState} from './muteState';
|
|
69
|
-
import LocusInfo
|
|
73
|
+
import LocusInfo from '../locus-info';
|
|
70
74
|
import Metrics from '../metrics';
|
|
71
75
|
import ReconnectionManager from '../reconnection-manager';
|
|
72
76
|
import ReconnectionNotStartedError from '../common/errors/reconnection-not-started';
|
|
@@ -166,7 +170,7 @@ import MultistreamNotSupportedError from '../common/errors/multistream-not-suppo
|
|
|
166
170
|
import JoinForbiddenError from '../common/errors/join-forbidden-error';
|
|
167
171
|
import {ReachabilityMetrics} from '../reachability/reachability.types';
|
|
168
172
|
import {SetStageOptions, SetStageVideoLayout, UnsetStageVideoLayout} from './request.type';
|
|
169
|
-
import {
|
|
173
|
+
import {Invitee} from './type';
|
|
170
174
|
|
|
171
175
|
// default callback so we don't call an undefined function, but in practice it should never be used
|
|
172
176
|
const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
|
|
@@ -251,6 +255,7 @@ export type CallStateForMetrics = {
|
|
|
251
255
|
loginType?: string;
|
|
252
256
|
userNameInput?: string;
|
|
253
257
|
emailInput?: string;
|
|
258
|
+
pstnCorrelationId?: string;
|
|
254
259
|
};
|
|
255
260
|
|
|
256
261
|
export const MEDIA_UPDATE_TYPE = {
|
|
@@ -268,6 +273,7 @@ export enum ScreenShareFloorStatus {
|
|
|
268
273
|
type FetchMeetingInfoParams = {
|
|
269
274
|
password?: string;
|
|
270
275
|
registrationId?: string;
|
|
276
|
+
classificationId?: string;
|
|
271
277
|
captchaCode?: string;
|
|
272
278
|
extraParams?: Record<string, any>;
|
|
273
279
|
sendCAevents?: boolean;
|
|
@@ -632,6 +638,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
632
638
|
shareStatus: string;
|
|
633
639
|
screenShareFloorState: ScreenShareFloorStatus;
|
|
634
640
|
statsAnalyzer: StatsAnalyzer;
|
|
641
|
+
statsMonitor: StatsMonitor;
|
|
635
642
|
transcription: Transcription;
|
|
636
643
|
updateMediaConnections: (mediaConnections: any[]) => void;
|
|
637
644
|
userDisplayHints: any;
|
|
@@ -744,10 +751,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
744
751
|
/**
|
|
745
752
|
* @param {Object} attrs
|
|
746
753
|
* @param {Object} options
|
|
754
|
+
* @param {Function} callback - if provided, it will be called with the newly created meeting object as soon as the meeting.id is set
|
|
747
755
|
* @constructor
|
|
748
756
|
* @memberof Meeting
|
|
749
757
|
*/
|
|
750
|
-
constructor(attrs: any, options: object) {
|
|
758
|
+
constructor(attrs: any, options: object, callback: (meeting: Meeting) => void) {
|
|
751
759
|
super({}, options);
|
|
752
760
|
/**
|
|
753
761
|
* @instance
|
|
@@ -773,6 +781,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
773
781
|
* @memberof Meeting
|
|
774
782
|
*/
|
|
775
783
|
this.id = uuid.v4();
|
|
784
|
+
|
|
785
|
+
if (callback) {
|
|
786
|
+
callback(this);
|
|
787
|
+
}
|
|
788
|
+
|
|
776
789
|
/**
|
|
777
790
|
* Call state used for metrics
|
|
778
791
|
* @instance
|
|
@@ -1279,6 +1292,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1279
1292
|
* @memberof Meeting
|
|
1280
1293
|
*/
|
|
1281
1294
|
this.networkQualityMonitor = null;
|
|
1295
|
+
/**
|
|
1296
|
+
* @instance
|
|
1297
|
+
* @type {StatsMonitor}
|
|
1298
|
+
* @private
|
|
1299
|
+
* @memberof Meeting
|
|
1300
|
+
*/
|
|
1301
|
+
this.statsMonitor = null;
|
|
1282
1302
|
/**
|
|
1283
1303
|
* Indicates network status of the webrtc media connection
|
|
1284
1304
|
* @instance
|
|
@@ -1677,6 +1697,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1677
1697
|
this.callStateForMetrics.correlationId = correlationId;
|
|
1678
1698
|
}
|
|
1679
1699
|
|
|
1700
|
+
/**
|
|
1701
|
+
* Getter - Returns callStateForMetrics.pstnCorrelationId
|
|
1702
|
+
* @returns {string | undefined}
|
|
1703
|
+
*/
|
|
1704
|
+
get pstnCorrelationId(): string | undefined {
|
|
1705
|
+
return this.callStateForMetrics.pstnCorrelationId;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
/**
|
|
1709
|
+
* Setter - sets callStateForMetrics.pstnCorrelationId
|
|
1710
|
+
* @param {string | undefined} correlationId
|
|
1711
|
+
*/
|
|
1712
|
+
set pstnCorrelationId(correlationId: string | undefined) {
|
|
1713
|
+
this.callStateForMetrics.pstnCorrelationId = correlationId;
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1680
1716
|
/**
|
|
1681
1717
|
* Getter - Returns callStateForMetrics.userNameInput
|
|
1682
1718
|
* @returns {string}
|
|
@@ -1879,6 +1915,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1879
1915
|
extraParams = {},
|
|
1880
1916
|
sendCAevents = false,
|
|
1881
1917
|
registrationId = null,
|
|
1918
|
+
classificationId = null,
|
|
1882
1919
|
}): Promise<void> {
|
|
1883
1920
|
try {
|
|
1884
1921
|
const captchaInfo = captchaCode
|
|
@@ -1895,7 +1932,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1895
1932
|
this.locusId,
|
|
1896
1933
|
extraParams,
|
|
1897
1934
|
{meetingId: this.id, sendCAevents},
|
|
1898
|
-
registrationId
|
|
1935
|
+
registrationId,
|
|
1936
|
+
null,
|
|
1937
|
+
classificationId
|
|
1899
1938
|
);
|
|
1900
1939
|
|
|
1901
1940
|
this.parseMeetingInfo(info?.body, this.destination, info?.errors);
|
|
@@ -2939,6 +2978,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2939
2978
|
);
|
|
2940
2979
|
});
|
|
2941
2980
|
|
|
2981
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_AUTO_END_MEETING_WARNING_CHANGED, ({state}) => {
|
|
2982
|
+
Trigger.trigger(
|
|
2983
|
+
this,
|
|
2984
|
+
{
|
|
2985
|
+
file: 'meeting/index',
|
|
2986
|
+
function: 'setupLocusControlsListener',
|
|
2987
|
+
},
|
|
2988
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_AUTO_END_MEETING_WARNING_UPDATED,
|
|
2989
|
+
{state}
|
|
2990
|
+
);
|
|
2991
|
+
});
|
|
2992
|
+
|
|
2942
2993
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_ANNOTATION_CHANGED, ({state}) => {
|
|
2943
2994
|
Trigger.trigger(
|
|
2944
2995
|
this,
|
|
@@ -3059,12 +3110,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3059
3110
|
// There is no concept of local/remote share for whiteboard
|
|
3060
3111
|
// It does not matter who requested to share the whiteboard, everyone gets the same view
|
|
3061
3112
|
else if (whiteboardShare.disposition === FLOOR_ACTION.GRANTED) {
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3113
|
+
if (this.locusInfo?.info?.isWebinar && this.webinar?.selfIsAttendee) {
|
|
3114
|
+
// WHITEBOARD - sharing whiteboard
|
|
3115
|
+
// Webinar attendee should receive whiteboard as remote share
|
|
3116
|
+
newShareStatus = SHARE_STATUS.REMOTE_SHARE_ACTIVE;
|
|
3117
|
+
} else if (this.guest) {
|
|
3118
|
+
// If user is a guest to a meeting, they should receive whiteboard as remote share
|
|
3119
|
+
newShareStatus = SHARE_STATUS.REMOTE_SHARE_ACTIVE;
|
|
3120
|
+
} else {
|
|
3121
|
+
newShareStatus = SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE;
|
|
3122
|
+
}
|
|
3068
3123
|
}
|
|
3069
3124
|
// or if content share is either released or null and whiteboard share is either released or null, no one is sharing
|
|
3070
3125
|
else if (
|
|
@@ -3122,6 +3177,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3122
3177
|
},
|
|
3123
3178
|
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_WHITEBOARD
|
|
3124
3179
|
);
|
|
3180
|
+
// @ts-ignore
|
|
3181
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp({
|
|
3182
|
+
key: 'internal.client.share.stopped',
|
|
3183
|
+
});
|
|
3184
|
+
// @ts-ignore
|
|
3185
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
3186
|
+
name: 'client.share.stopped',
|
|
3187
|
+
payload: {
|
|
3188
|
+
mediaType: 'whiteboard',
|
|
3189
|
+
shareDuration:
|
|
3190
|
+
// @ts-ignore
|
|
3191
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration(),
|
|
3192
|
+
},
|
|
3193
|
+
options: {
|
|
3194
|
+
meetingId: this.id,
|
|
3195
|
+
},
|
|
3196
|
+
});
|
|
3125
3197
|
break;
|
|
3126
3198
|
|
|
3127
3199
|
case SHARE_STATUS.NO_SHARE:
|
|
@@ -3140,6 +3212,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3140
3212
|
this.shareCAEventSentStatus.receiveStart = false;
|
|
3141
3213
|
this.shareCAEventSentStatus.receiveStop = false;
|
|
3142
3214
|
|
|
3215
|
+
let finalBeneficiaryId = contentShare.beneficiaryId;
|
|
3216
|
+
// In case of attendee in webinar, the whiteboard is shared by other participants
|
|
3217
|
+
if (this.locusInfo?.info?.isWebinar && this.webinar?.selfIsAttendee) {
|
|
3218
|
+
if (!finalBeneficiaryId && whiteboardShare.beneficiaryId) {
|
|
3219
|
+
finalBeneficiaryId = whiteboardShare.beneficiaryId;
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3143
3223
|
Trigger.trigger(
|
|
3144
3224
|
this,
|
|
3145
3225
|
{
|
|
@@ -3148,7 +3228,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3148
3228
|
},
|
|
3149
3229
|
EVENT_TRIGGERS.MEETING_STARTED_SHARING_REMOTE,
|
|
3150
3230
|
{
|
|
3151
|
-
memberId:
|
|
3231
|
+
memberId: finalBeneficiaryId,
|
|
3152
3232
|
url: contentShare.url,
|
|
3153
3233
|
shareInstanceId: this.remoteShareInstanceId,
|
|
3154
3234
|
annotationInfo: contentShare.annotation,
|
|
@@ -3290,27 +3370,31 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3290
3370
|
* @memberof Meeting
|
|
3291
3371
|
*/
|
|
3292
3372
|
private setUpLocusUrlListener() {
|
|
3293
|
-
this.locusInfo.on(
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3373
|
+
this.locusInfo.on(
|
|
3374
|
+
EVENTS.LOCUS_INFO_UPDATE_URL,
|
|
3375
|
+
(payload: {url: string; isMainLocus?: boolean}) => {
|
|
3376
|
+
const {url, isMainLocus} = payload;
|
|
3377
|
+
this.members.locusUrlUpdate(url);
|
|
3378
|
+
this.breakouts.locusUrlUpdate(url);
|
|
3379
|
+
this.simultaneousInterpretation.locusUrlUpdate(url);
|
|
3380
|
+
this.annotation.locusUrlUpdate(url);
|
|
3381
|
+
this.locusUrl = url;
|
|
3382
|
+
this.locusId = this.locusUrl?.split('/').pop();
|
|
3383
|
+
this.recordingController.setLocusUrl(this.locusUrl);
|
|
3384
|
+
this.controlsOptionsManager.setLocusUrl(this.locusUrl, !!isMainLocus);
|
|
3385
|
+
this.webinar.locusUrlUpdate(url);
|
|
3303
3386
|
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3387
|
+
Trigger.trigger(
|
|
3388
|
+
this,
|
|
3389
|
+
{
|
|
3390
|
+
file: 'meeting/index',
|
|
3391
|
+
function: 'setUpLocusSelfListener',
|
|
3392
|
+
},
|
|
3393
|
+
EVENT_TRIGGERS.MEETING_LOCUS_URL_UPDATE,
|
|
3394
|
+
{locusUrl: url}
|
|
3395
|
+
);
|
|
3396
|
+
}
|
|
3397
|
+
);
|
|
3314
3398
|
}
|
|
3315
3399
|
|
|
3316
3400
|
/**
|
|
@@ -3830,49 +3914,43 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3830
3914
|
|
|
3831
3915
|
/**
|
|
3832
3916
|
* Invite a guest to the call that isn't normally part of this call
|
|
3833
|
-
* @param {
|
|
3917
|
+
* @param {Invitee} invitee
|
|
3834
3918
|
* @param {String} invitee.emailAddress
|
|
3835
3919
|
* @param {String} invitee.email
|
|
3836
3920
|
* @param {String} invitee.phoneNumber
|
|
3837
3921
|
* @param {Boolean} [alertIfActive]
|
|
3922
|
+
* @param {Boolean} [invitee.skipEmailValidation]
|
|
3923
|
+
* @param {Boolean} [invitee.isInternalNumber]
|
|
3838
3924
|
* @returns {Promise} see #members.addMember
|
|
3839
3925
|
* @public
|
|
3840
3926
|
* @memberof Meeting
|
|
3841
3927
|
*/
|
|
3842
|
-
public invite(
|
|
3843
|
-
invitee: {
|
|
3844
|
-
emailAddress: string;
|
|
3845
|
-
email: string;
|
|
3846
|
-
phoneNumber: string;
|
|
3847
|
-
roles: Array<string>;
|
|
3848
|
-
},
|
|
3849
|
-
alertIfActive = true
|
|
3850
|
-
) {
|
|
3928
|
+
public invite(invitee: Invitee, alertIfActive = true) {
|
|
3851
3929
|
return this.members.addMember(invitee, alertIfActive);
|
|
3852
3930
|
}
|
|
3853
3931
|
|
|
3854
3932
|
/**
|
|
3855
3933
|
* Cancel an outgoing phone call invitation made during a meeting
|
|
3856
|
-
* @param {
|
|
3934
|
+
* @param {Invitee} invitee
|
|
3857
3935
|
* @param {String} invitee.phoneNumber
|
|
3858
3936
|
* @returns {Promise} see #members.cancelPhoneInvite
|
|
3859
3937
|
* @public
|
|
3860
3938
|
* @memberof Meeting
|
|
3861
3939
|
*/
|
|
3862
|
-
public cancelPhoneInvite(invitee:
|
|
3940
|
+
public cancelPhoneInvite(invitee: Invitee) {
|
|
3863
3941
|
return this.members.cancelPhoneInvite(invitee);
|
|
3864
3942
|
}
|
|
3865
3943
|
|
|
3866
3944
|
/**
|
|
3867
3945
|
* Cancel an SIP/phone call invitation made during a meeting
|
|
3868
|
-
* @param {
|
|
3946
|
+
* @param {Invitee} invitee
|
|
3869
3947
|
* @param {String} invitee.memberId
|
|
3870
3948
|
* @param {Boolean} [invitee.isInternalNumber] - When cancel phone invitation, if the number is internal
|
|
3871
3949
|
* @returns {Promise} see #members.cancelInviteByMemberId
|
|
3872
3950
|
* @public
|
|
3873
3951
|
* @memberof Meeting
|
|
3874
3952
|
*/
|
|
3875
|
-
public cancelInviteByMemberId(invitee:
|
|
3953
|
+
public cancelInviteByMemberId(invitee: Invitee) {
|
|
3876
3954
|
return this.members.cancelInviteByMemberId(invitee);
|
|
3877
3955
|
}
|
|
3878
3956
|
|
|
@@ -4159,6 +4237,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4159
4237
|
this.userDisplayHints,
|
|
4160
4238
|
this.selfUserPolicies
|
|
4161
4239
|
),
|
|
4240
|
+
showAutoEndMeetingWarning: MeetingUtil.showAutoEndMeetingWarning(this.userDisplayHints),
|
|
4162
4241
|
canRaiseHand: MeetingUtil.canUserRaiseHand(this.userDisplayHints),
|
|
4163
4242
|
canLowerAllHands: MeetingUtil.canUserLowerAllHands(this.userDisplayHints),
|
|
4164
4243
|
canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(this.userDisplayHints),
|
|
@@ -4171,8 +4250,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4171
4250
|
isClosedCaptionActive: MeetingUtil.isClosedCaptionActive(this.userDisplayHints),
|
|
4172
4251
|
canStartManualCaption: MeetingUtil.canStartManualCaption(this.userDisplayHints),
|
|
4173
4252
|
canStopManualCaption: MeetingUtil.canStopManualCaption(this.userDisplayHints),
|
|
4253
|
+
isLocalRecordingStarted: MeetingUtil.isLocalRecordingStarted(this.userDisplayHints),
|
|
4254
|
+
isLocalRecordingStopped: MeetingUtil.isLocalRecordingStopped(this.userDisplayHints),
|
|
4255
|
+
isLocalRecordingPaused: MeetingUtil.isLocalRecordingPaused(this.userDisplayHints),
|
|
4256
|
+
isLocalStreamingStarted: MeetingUtil.isLocalStreamingStarted(this.userDisplayHints),
|
|
4257
|
+
isLocalStreamingStopped: MeetingUtil.isLocalStreamingStopped(this.userDisplayHints),
|
|
4174
4258
|
isManualCaptionActive: MeetingUtil.isManualCaptionActive(this.userDisplayHints),
|
|
4175
4259
|
isSaveTranscriptsEnabled: MeetingUtil.isSaveTranscriptsEnabled(this.userDisplayHints),
|
|
4260
|
+
isSpokenLanguageAutoDetectionEnabled: MeetingUtil.isSpokenLanguageAutoDetectionEnabled(
|
|
4261
|
+
this.userDisplayHints
|
|
4262
|
+
),
|
|
4176
4263
|
isWebexAssistantActive: MeetingUtil.isWebexAssistantActive(this.userDisplayHints),
|
|
4177
4264
|
canViewCaptionPanel: MeetingUtil.canViewCaptionPanel(this.userDisplayHints),
|
|
4178
4265
|
isRealTimeTranslationEnabled: MeetingUtil.isRealTimeTranslationEnabled(
|
|
@@ -4479,13 +4566,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4479
4566
|
setLocus(
|
|
4480
4567
|
locus:
|
|
4481
4568
|
| {
|
|
4482
|
-
locus: LocusDTO;
|
|
4483
4569
|
mediaConnections: Array<any>;
|
|
4484
4570
|
locusUrl: string;
|
|
4485
4571
|
locusId: string;
|
|
4486
4572
|
mediaId: string;
|
|
4487
4573
|
host: object;
|
|
4488
|
-
dataSets: DataSet[];
|
|
4489
4574
|
}
|
|
4490
4575
|
| any
|
|
4491
4576
|
) {
|
|
@@ -4499,7 +4584,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4499
4584
|
this.selfId = locus.selfId;
|
|
4500
4585
|
this.mediaId = locus.mediaId;
|
|
4501
4586
|
this.hostId = mtgLocus.host ? mtgLocus.host.id : this.hostId;
|
|
4502
|
-
this.locusInfo.initialSetup(mtgLocus
|
|
4587
|
+
this.locusInfo.initialSetup(mtgLocus);
|
|
4503
4588
|
}
|
|
4504
4589
|
|
|
4505
4590
|
/**
|
|
@@ -5612,21 +5697,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5612
5697
|
}
|
|
5613
5698
|
}
|
|
5614
5699
|
|
|
5615
|
-
/** Handles Locus LLM events
|
|
5616
|
-
*
|
|
5617
|
-
* @param {LocusLLMEvent} event - The Locus LLM event to process
|
|
5618
|
-
* @returns {void}
|
|
5619
|
-
*/
|
|
5620
|
-
private processLocusLLMEvent = (event: LocusLLMEvent): void => {
|
|
5621
|
-
if (event.data.eventType === 'locus.state_message') {
|
|
5622
|
-
this.locusInfo.parse(this, event.data);
|
|
5623
|
-
} else {
|
|
5624
|
-
LoggerProxy.logger.warn(
|
|
5625
|
-
`Meeting:index#processLocusLLMEvent --> Unknown event type: ${event.data.eventType}`
|
|
5626
|
-
);
|
|
5627
|
-
}
|
|
5628
|
-
};
|
|
5629
|
-
|
|
5630
5700
|
/**
|
|
5631
5701
|
* Callback called when a relay event is received from meeting LLM Connection
|
|
5632
5702
|
* @param {RelayEvent} e Event object coming from LLM Connection
|
|
@@ -5945,15 +6015,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5945
6015
|
this.meetingFiniteStateMachine.fail(error);
|
|
5946
6016
|
LoggerProxy.logger.error('Meeting:index#join --> Failed', error);
|
|
5947
6017
|
|
|
5948
|
-
// @ts-ignore
|
|
5949
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
|
5950
|
-
name: 'client.locus.join.response',
|
|
5951
|
-
payload: {
|
|
5952
|
-
identifiers: {meetingLookupUrl: this.meetingInfo?.meetingLookupUrl},
|
|
5953
|
-
},
|
|
5954
|
-
options: {meetingId: this.id, rawError: error},
|
|
5955
|
-
});
|
|
5956
|
-
|
|
5957
6018
|
// TODO: change this to error codes and pre defined dictionary
|
|
5958
6019
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_FAILURE, {
|
|
5959
6020
|
correlation_id: this.correlationId,
|
|
@@ -6047,8 +6108,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6047
6108
|
);
|
|
6048
6109
|
// @ts-ignore - Fix type
|
|
6049
6110
|
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6050
|
-
// @ts-ignore - Fix type
|
|
6051
|
-
this.webex.internal.llm.off('event:locus.state_message', this.processLocusLLMEvent);
|
|
6052
6111
|
}
|
|
6053
6112
|
|
|
6054
6113
|
if (!isJoined) {
|
|
@@ -6063,10 +6122,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6063
6122
|
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6064
6123
|
// @ts-ignore - Fix type
|
|
6065
6124
|
this.webex.internal.llm.on('event:relay.event', this.processRelayEvent);
|
|
6066
|
-
// @ts-ignore - Fix type
|
|
6067
|
-
this.webex.internal.llm.off('event:locus.state_message', this.processLocusLLMEvent);
|
|
6068
|
-
// @ts-ignore - Fix type
|
|
6069
|
-
this.webex.internal.llm.on('event:locus.state_message', this.processLocusLLMEvent);
|
|
6070
6125
|
LoggerProxy.logger.info(
|
|
6071
6126
|
'Meeting:index#updateLLMConnection --> enabled to receive relay events!'
|
|
6072
6127
|
);
|
|
@@ -6109,8 +6164,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6109
6164
|
*/
|
|
6110
6165
|
private dialInPstn() {
|
|
6111
6166
|
if (this.isPhoneProvisioned(this.dialInDeviceStatus)) return Promise.resolve(); // prevent multiple dial in devices from being provisioned
|
|
6167
|
+
this.pstnCorrelationId = uuid.v4();
|
|
6112
6168
|
|
|
6113
|
-
const {
|
|
6169
|
+
const {pstnCorrelationId, locusUrl} = this;
|
|
6114
6170
|
|
|
6115
6171
|
if (!this.dialInUrl) this.dialInUrl = `dialin:///${uuid.v4()}`;
|
|
6116
6172
|
|
|
@@ -6118,7 +6174,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6118
6174
|
this.meetingRequest
|
|
6119
6175
|
// @ts-ignore
|
|
6120
6176
|
.dialIn({
|
|
6121
|
-
correlationId,
|
|
6177
|
+
correlationId: pstnCorrelationId,
|
|
6122
6178
|
dialInUrl: this.dialInUrl,
|
|
6123
6179
|
locusUrl,
|
|
6124
6180
|
clientUrl: this.deviceUrl,
|
|
@@ -6127,12 +6183,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6127
6183
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE, {
|
|
6128
6184
|
correlation_id: this.correlationId,
|
|
6129
6185
|
dial_in_url: this.dialInUrl,
|
|
6186
|
+
dial_in_correlation_id: pstnCorrelationId,
|
|
6130
6187
|
locus_id: locusUrl.split('/').pop(),
|
|
6131
6188
|
client_url: this.deviceUrl,
|
|
6132
6189
|
reason: error.error?.message,
|
|
6133
6190
|
stack: error.stack,
|
|
6134
6191
|
});
|
|
6135
6192
|
|
|
6193
|
+
if (this.pstnCorrelationId === pstnCorrelationId) {
|
|
6194
|
+
this.pstnCorrelationId = undefined;
|
|
6195
|
+
}
|
|
6196
|
+
|
|
6136
6197
|
return Promise.reject(error);
|
|
6137
6198
|
})
|
|
6138
6199
|
);
|
|
@@ -6147,8 +6208,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6147
6208
|
*/
|
|
6148
6209
|
private dialOutPstn(phoneNumber: string) {
|
|
6149
6210
|
if (this.isPhoneProvisioned(this.dialOutDeviceStatus)) return Promise.resolve(); // prevent multiple dial out devices from being provisioned
|
|
6211
|
+
this.pstnCorrelationId = uuid.v4();
|
|
6150
6212
|
|
|
6151
|
-
const {
|
|
6213
|
+
const {locusUrl, pstnCorrelationId} = this;
|
|
6152
6214
|
|
|
6153
6215
|
if (!this.dialOutUrl) this.dialOutUrl = `dialout:///${uuid.v4()}`;
|
|
6154
6216
|
|
|
@@ -6156,7 +6218,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6156
6218
|
this.meetingRequest
|
|
6157
6219
|
// @ts-ignore
|
|
6158
6220
|
.dialOut({
|
|
6159
|
-
correlationId,
|
|
6221
|
+
correlationId: pstnCorrelationId,
|
|
6160
6222
|
dialOutUrl: this.dialOutUrl,
|
|
6161
6223
|
phoneNumber,
|
|
6162
6224
|
locusUrl,
|
|
@@ -6166,12 +6228,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6166
6228
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE, {
|
|
6167
6229
|
correlation_id: this.correlationId,
|
|
6168
6230
|
dial_out_url: this.dialOutUrl,
|
|
6231
|
+
dial_out_correlation_id: pstnCorrelationId,
|
|
6169
6232
|
locus_id: locusUrl.split('/').pop(),
|
|
6170
6233
|
client_url: this.deviceUrl,
|
|
6171
6234
|
reason: error.error?.message,
|
|
6172
6235
|
stack: error.stack,
|
|
6173
6236
|
});
|
|
6174
6237
|
|
|
6238
|
+
if (this.pstnCorrelationId === pstnCorrelationId) {
|
|
6239
|
+
this.pstnCorrelationId = undefined;
|
|
6240
|
+
}
|
|
6241
|
+
|
|
6175
6242
|
return Promise.reject(error);
|
|
6176
6243
|
})
|
|
6177
6244
|
);
|
|
@@ -6185,6 +6252,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6185
6252
|
* @returns {Promise}
|
|
6186
6253
|
*/
|
|
6187
6254
|
public disconnectPhoneAudio() {
|
|
6255
|
+
const correlationToClear = this.pstnCorrelationId;
|
|
6256
|
+
|
|
6188
6257
|
return Promise.all([
|
|
6189
6258
|
this.isPhoneProvisioned(this.dialInDeviceStatus)
|
|
6190
6259
|
? MeetingUtil.disconnectPhoneAudio(this, this.dialInUrl)
|
|
@@ -6192,7 +6261,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6192
6261
|
this.isPhoneProvisioned(this.dialOutDeviceStatus)
|
|
6193
6262
|
? MeetingUtil.disconnectPhoneAudio(this, this.dialOutUrl)
|
|
6194
6263
|
: Promise.resolve(),
|
|
6195
|
-
])
|
|
6264
|
+
]).then(() => {
|
|
6265
|
+
if (this.pstnCorrelationId === correlationToClear) {
|
|
6266
|
+
this.pstnCorrelationId = undefined;
|
|
6267
|
+
}
|
|
6268
|
+
});
|
|
6196
6269
|
}
|
|
6197
6270
|
|
|
6198
6271
|
/**
|
|
@@ -6769,6 +6842,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6769
6842
|
// @ts-ignore
|
|
6770
6843
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
6771
6844
|
name: 'client.ice.start',
|
|
6845
|
+
payload: {
|
|
6846
|
+
// @ts-ignore
|
|
6847
|
+
labels: MeetingUtil.getCaEventLabelsForIpVersion(this.webex),
|
|
6848
|
+
},
|
|
6772
6849
|
options: {
|
|
6773
6850
|
meetingId: this.id,
|
|
6774
6851
|
},
|
|
@@ -6938,10 +7015,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6938
7015
|
}
|
|
6939
7016
|
}
|
|
6940
7017
|
|
|
6941
|
-
// Count members that are in the meeting.
|
|
7018
|
+
// Count members that are in the meeting or in the lobby.
|
|
6942
7019
|
const {members} = this.getMembers().membersCollection;
|
|
6943
7020
|
event.data.intervalMetadata.meetingUserCount = Object.values(members).filter(
|
|
6944
|
-
(member: Member) => member.isInMeeting
|
|
7021
|
+
(member: Member) => member.isInMeeting || member.isInLobby
|
|
6945
7022
|
).length;
|
|
6946
7023
|
|
|
6947
7024
|
// @ts-ignore
|
|
@@ -7300,10 +7377,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7300
7377
|
if (this.config.stats.enableStatsAnalyzer) {
|
|
7301
7378
|
// @ts-ignore - config coming from registerPlugin
|
|
7302
7379
|
this.networkQualityMonitor = new NetworkQualityMonitor(this.config.stats);
|
|
7380
|
+
this.statsMonitor = new StatsMonitor();
|
|
7303
7381
|
this.statsAnalyzer = new StatsAnalyzer({
|
|
7304
7382
|
// @ts-ignore - config coming from registerPlugin
|
|
7305
7383
|
config: this.config.stats,
|
|
7306
7384
|
networkQualityMonitor: this.networkQualityMonitor,
|
|
7385
|
+
statsMonitor: this.statsMonitor,
|
|
7307
7386
|
isMultistream: this.isMultistream,
|
|
7308
7387
|
});
|
|
7309
7388
|
this.shareCAEventSentStatus = {
|
|
@@ -7317,6 +7396,33 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7317
7396
|
NetworkQualityEventNames.NETWORK_QUALITY,
|
|
7318
7397
|
this.sendNetworkQualityEvent.bind(this)
|
|
7319
7398
|
);
|
|
7399
|
+
|
|
7400
|
+
this.statsMonitor.on(StatsMonitorEventNames.INBOUND_AUDIO_ISSUE, (data) => {
|
|
7401
|
+
// Before forwarding any inbound audio issues to the app, make sure that we have at least one other
|
|
7402
|
+
// participant in the meeting with unmuted audio.
|
|
7403
|
+
// We don't check this.mediaProperties.mediaDirection here, because that's already handled in statsAnalyzer,
|
|
7404
|
+
// so we won't get this event if we are not setup to receive any audio
|
|
7405
|
+
const atLeastOneUnmutedOtherMember = Object.values(
|
|
7406
|
+
this.members.membersCollection.getAll()
|
|
7407
|
+
).find((member) => {
|
|
7408
|
+
return !member.isSelf && !member.isPairedWithSelf && !member.isAudioMuted;
|
|
7409
|
+
});
|
|
7410
|
+
|
|
7411
|
+
if (atLeastOneUnmutedOtherMember) {
|
|
7412
|
+
this.mediaProperties.sendMediaIssueMetric(
|
|
7413
|
+
'inbound_audio',
|
|
7414
|
+
data.issueSubType,
|
|
7415
|
+
this.correlationId
|
|
7416
|
+
);
|
|
7417
|
+
|
|
7418
|
+
Trigger.trigger(
|
|
7419
|
+
this,
|
|
7420
|
+
{file: 'meeting/index', function: 'createStatsAnalyzer'},
|
|
7421
|
+
EVENT_TRIGGERS.MEDIA_INBOUND_AUDIO_ISSUE_DETECTED,
|
|
7422
|
+
data
|
|
7423
|
+
);
|
|
7424
|
+
}
|
|
7425
|
+
});
|
|
7320
7426
|
}
|
|
7321
7427
|
}
|
|
7322
7428
|
|
|
@@ -7347,7 +7453,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7347
7453
|
} seconds`
|
|
7348
7454
|
);
|
|
7349
7455
|
|
|
7350
|
-
const error = new
|
|
7456
|
+
const error = new SdpResponseTimeoutError();
|
|
7351
7457
|
|
|
7352
7458
|
// @ts-ignore
|
|
7353
7459
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
@@ -7615,6 +7721,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7615
7721
|
}
|
|
7616
7722
|
|
|
7617
7723
|
this.statsAnalyzer = null;
|
|
7724
|
+
this.networkQualityMonitor?.removeAllListeners();
|
|
7725
|
+
this.networkQualityMonitor = null;
|
|
7726
|
+
this.statsMonitor?.removeAllListeners();
|
|
7727
|
+
this.statsMonitor = null;
|
|
7618
7728
|
|
|
7619
7729
|
// when media fails, we want to upload a webrtc dump to see whats going on
|
|
7620
7730
|
// this function is async, but returns once the stats have been gathered
|
|
@@ -7638,6 +7748,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7638
7748
|
await this.statsAnalyzer.stopAnalyzer();
|
|
7639
7749
|
}
|
|
7640
7750
|
this.statsAnalyzer = null;
|
|
7751
|
+
this.networkQualityMonitor?.removeAllListeners();
|
|
7752
|
+
this.networkQualityMonitor = null;
|
|
7753
|
+
this.statsMonitor?.removeAllListeners();
|
|
7754
|
+
this.statsMonitor = null;
|
|
7641
7755
|
|
|
7642
7756
|
this.isMultistream = false;
|
|
7643
7757
|
|
|
@@ -7809,6 +7923,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7809
7923
|
|
|
7810
7924
|
this.allowMediaInLobby = options?.allowMediaInLobby;
|
|
7811
7925
|
|
|
7926
|
+
// @ts-ignore
|
|
7927
|
+
const ipver = MeetingUtil.getIpVersion(this.webex); // used just for metrics
|
|
7928
|
+
|
|
7812
7929
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
|
7813
7930
|
// @ts-ignore - isUserUnadmitted coming from SelfUtil
|
|
7814
7931
|
if (this.isUserUnadmitted && !this.wirelessShare && !this.allowMediaInLobby) {
|
|
@@ -7907,6 +8024,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7907
8024
|
locus_id: this.locusUrl.split('/').pop(),
|
|
7908
8025
|
connectionType,
|
|
7909
8026
|
ipVersion,
|
|
8027
|
+
ipver,
|
|
7910
8028
|
selectedCandidatePairChanges,
|
|
7911
8029
|
numTransports,
|
|
7912
8030
|
isMultistream: this.isMultistream,
|
|
@@ -7975,6 +8093,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7975
8093
|
...reachabilityMetrics,
|
|
7976
8094
|
...iceCandidateErrors,
|
|
7977
8095
|
iceCandidatesCount: this.iceCandidatesCount,
|
|
8096
|
+
ipver,
|
|
7978
8097
|
});
|
|
7979
8098
|
|
|
7980
8099
|
await this.cleanUpOnAddMediaFailure();
|
|
@@ -8414,6 +8533,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8414
8533
|
}
|
|
8415
8534
|
|
|
8416
8535
|
if (whiteboard) {
|
|
8536
|
+
// @ts-ignore
|
|
8537
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp({
|
|
8538
|
+
key: 'internal.client.share.initiated',
|
|
8539
|
+
});
|
|
8417
8540
|
// @ts-ignore
|
|
8418
8541
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
8419
8542
|
name: 'client.share.initiated',
|
|
@@ -8473,11 +8596,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8473
8596
|
const whiteboard = this.locusInfo.mediaShares.find((element) => element.name === 'whiteboard');
|
|
8474
8597
|
|
|
8475
8598
|
if (whiteboard) {
|
|
8599
|
+
// @ts-ignore
|
|
8600
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp({
|
|
8601
|
+
key: 'internal.client.share.stopped',
|
|
8602
|
+
});
|
|
8476
8603
|
// @ts-ignore
|
|
8477
8604
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
8478
8605
|
name: 'client.share.stopped',
|
|
8479
8606
|
payload: {
|
|
8480
8607
|
mediaType: 'whiteboard',
|
|
8608
|
+
// @ts-ignore
|
|
8609
|
+
shareDuration: this.webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration(),
|
|
8481
8610
|
},
|
|
8482
8611
|
options: {
|
|
8483
8612
|
meetingId: this.id,
|
|
@@ -8635,12 +8764,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8635
8764
|
}
|
|
8636
8765
|
this.screenShareFloorState = ScreenShareFloorStatus.RELEASED;
|
|
8637
8766
|
if (content) {
|
|
8767
|
+
// @ts-ignore
|
|
8768
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp({
|
|
8769
|
+
key: 'internal.client.share.stopped',
|
|
8770
|
+
});
|
|
8638
8771
|
// @ts-ignore
|
|
8639
8772
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
8640
8773
|
name: 'client.share.stopped',
|
|
8641
8774
|
payload: {
|
|
8642
8775
|
mediaType: 'share',
|
|
8643
8776
|
shareInstanceId: this.localShareInstanceId,
|
|
8777
|
+
// @ts-ignore
|
|
8778
|
+
shareDuration: this.webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration(),
|
|
8644
8779
|
},
|
|
8645
8780
|
options: {meetingId: this.id},
|
|
8646
8781
|
});
|
|
@@ -9238,8 +9373,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9238
9373
|
|
|
9239
9374
|
// @ts-ignore - fix types
|
|
9240
9375
|
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
9241
|
-
// @ts-ignore - Fix type
|
|
9242
|
-
this.webex.internal.llm.off('event:locus.state_message', this.processLocusLLMEvent);
|
|
9243
9376
|
};
|
|
9244
9377
|
|
|
9245
9378
|
/**
|
|
@@ -9337,6 +9470,36 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9337
9470
|
return Promise.reject(new Error('Error sending reaction, service url not found.'));
|
|
9338
9471
|
}
|
|
9339
9472
|
|
|
9473
|
+
/**
|
|
9474
|
+
* Extend the current meeting duration.
|
|
9475
|
+
*
|
|
9476
|
+
* @param {number} extensionMinutes - how many minutes to extend
|
|
9477
|
+
* @returns {Promise}
|
|
9478
|
+
* @public
|
|
9479
|
+
* @memberof Meeting
|
|
9480
|
+
*/
|
|
9481
|
+
public extendMeeting({
|
|
9482
|
+
meetingPolicyUrl,
|
|
9483
|
+
meetingInstanceId,
|
|
9484
|
+
participantId,
|
|
9485
|
+
extensionMinutes = 30,
|
|
9486
|
+
}) {
|
|
9487
|
+
if (!meetingInstanceId || !participantId) {
|
|
9488
|
+
return Promise.reject(new Error('Missing meetingInstanceId or participantId'));
|
|
9489
|
+
}
|
|
9490
|
+
|
|
9491
|
+
if (!meetingPolicyUrl) {
|
|
9492
|
+
return Promise.reject(new Error('Missing meetingPolicyUrl'));
|
|
9493
|
+
}
|
|
9494
|
+
|
|
9495
|
+
return this.meetingRequest.extendMeeting({
|
|
9496
|
+
meetingInstanceId,
|
|
9497
|
+
participantId,
|
|
9498
|
+
extensionMinutes,
|
|
9499
|
+
meetingPolicyUrl,
|
|
9500
|
+
});
|
|
9501
|
+
}
|
|
9502
|
+
|
|
9340
9503
|
/**
|
|
9341
9504
|
* Method to enable or disable reactions inside the meeting.
|
|
9342
9505
|
*
|
|
@@ -9619,6 +9782,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9619
9782
|
this.shareCAEventSentStatus.transmitStart = false;
|
|
9620
9783
|
this.shareCAEventSentStatus.transmitStop = false;
|
|
9621
9784
|
|
|
9785
|
+
// @ts-ignore
|
|
9786
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp({
|
|
9787
|
+
key: 'internal.client.share.initiated',
|
|
9788
|
+
});
|
|
9789
|
+
|
|
9622
9790
|
// @ts-ignore
|
|
9623
9791
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
9624
9792
|
name: 'client.share.initiated',
|
|
@@ -9861,4 +10029,47 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9861
10029
|
|
|
9862
10030
|
return this.meetingRequest.synchronizeStage(this.locusUrl, videoLayout);
|
|
9863
10031
|
}
|
|
10032
|
+
|
|
10033
|
+
/**
|
|
10034
|
+
* Notifies the host with the given meeting UUID and display names.
|
|
10035
|
+
*
|
|
10036
|
+
* @param {string} meetingUuid - The UUID of the meeting.
|
|
10037
|
+
* @param {string[]} displayName - An array of display names to notify the host with.
|
|
10038
|
+
* @returns {Promise<any>} The result of the notifyHost request.
|
|
10039
|
+
*/
|
|
10040
|
+
notifyHost(meetingUuid: string, displayName: string[]) {
|
|
10041
|
+
return this.meetingRequest.notifyHost(
|
|
10042
|
+
this.meetingInfo.siteFullUrl,
|
|
10043
|
+
this.locusId,
|
|
10044
|
+
meetingUuid,
|
|
10045
|
+
displayName
|
|
10046
|
+
);
|
|
10047
|
+
}
|
|
10048
|
+
|
|
10049
|
+
/**
|
|
10050
|
+
* Call out a SIP participant to a meeting
|
|
10051
|
+
* @param {string} address - The SIP address or phone number
|
|
10052
|
+
* @param {string} displayName - The display name for the participant
|
|
10053
|
+
* @param {string} [correlationId] - Optional correlation ID
|
|
10054
|
+
* @returns {Promise} Promise that resolves when the call-out is initiated
|
|
10055
|
+
*/
|
|
10056
|
+
sipCallOut(address: string, displayName: string) {
|
|
10057
|
+
return this.meetingRequest.sipCallOut(
|
|
10058
|
+
this.meetingInfo.meetingId,
|
|
10059
|
+
this.meetingInfo.meetingId,
|
|
10060
|
+
address,
|
|
10061
|
+
displayName
|
|
10062
|
+
);
|
|
10063
|
+
}
|
|
10064
|
+
|
|
10065
|
+
/**
|
|
10066
|
+
* Cancel an ongoing SIP call-out
|
|
10067
|
+
* @param {string} participantId - The participant ID to cancel
|
|
10068
|
+
* @returns {Promise} Promise that resolves when the call-out is cancelled
|
|
10069
|
+
* @public
|
|
10070
|
+
* @memberof Meetings
|
|
10071
|
+
*/
|
|
10072
|
+
cancelSipCallOut(participantId: string) {
|
|
10073
|
+
return this.meetingRequest.cancelSipCallOut(participantId);
|
|
10074
|
+
}
|
|
9864
10075
|
}
|