@webex/plugin-meetings 3.12.0-next.9 → 3.12.0-next.91
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/AGENTS.md +9 -0
- package/dist/aiEnableRequest/index.js +15 -2
- package/dist/aiEnableRequest/index.js.map +1 -1
- package/dist/breakouts/breakout.js +8 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/index.js +26 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/constants.js +35 -9
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +11 -1
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +67 -29
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/util.js +91 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/hashTree/constants.js +13 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +880 -382
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/utils.js +42 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/interceptors/dataChannelAuthToken.js +75 -15
- package/dist/interceptors/dataChannelAuthToken.js.map +1 -1
- package/dist/interceptors/locusRetry.js +23 -8
- package/dist/interceptors/locusRetry.js.map +1 -1
- package/dist/interpretation/index.js +10 -1
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/interpretation.types.js +7 -0
- package/dist/interpretation/interpretation.types.js.map +1 -0
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +4 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +303 -88
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +36 -5
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/types.js +19 -0
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/index.js +3 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +1 -0
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +5 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1233 -793
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +229 -82
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +10 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +5 -2
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +35 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -2
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +231 -118
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +6 -1
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/request.js +39 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +79 -5
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +30 -0
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +101 -43
- package/dist/members/index.js.map +1 -1
- package/dist/members/util.js +8 -1
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +5 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/codec/constants.js +63 -0
- package/dist/multistream/codec/constants.js.map +1 -0
- package/dist/multistream/mediaRequestManager.js +62 -15
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +9 -0
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/reachability/index.js +10 -13
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachability.types.js +2 -0
- package/dist/reachability/reachability.types.js.map +1 -1
- package/dist/reachability/util.js +45 -0
- package/dist/reachability/util.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/recording-controller/index.js +1 -3
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/types/config.d.ts +2 -2
- package/dist/types/constants.d.ts +12 -1
- package/dist/types/controls-options-manager/constants.d.ts +6 -1
- package/dist/types/controls-options-manager/index.d.ts +16 -0
- package/dist/types/hashTree/constants.d.ts +2 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +146 -17
- package/dist/types/hashTree/utils.d.ts +18 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/interceptors/locusRetry.d.ts +4 -4
- package/dist/types/interpretation/interpretation.types.d.ts +10 -0
- package/dist/types/locus-info/index.d.ts +50 -6
- package/dist/types/locus-info/infoUtils.d.ts +8 -0
- package/dist/types/locus-info/types.d.ts +21 -1
- package/dist/types/media/properties.d.ts +1 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +4 -0
- package/dist/types/meeting/index.d.ts +94 -7
- package/dist/types/meeting/locusMediaRequest.d.ts +12 -0
- package/dist/types/meeting/request.d.ts +1 -0
- package/dist/types/meeting/util.d.ts +9 -0
- package/dist/types/meetings/index.d.ts +30 -18
- package/dist/types/meetings/meetings.types.d.ts +15 -0
- package/dist/types/meetings/request.d.ts +14 -0
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/types.d.ts +1 -0
- package/dist/types/member/util.d.ts +9 -0
- package/dist/types/members/index.d.ts +15 -2
- package/dist/types/members/util.d.ts +1 -5
- package/dist/types/metrics/constants.d.ts +4 -0
- package/dist/types/multistream/codec/constants.d.ts +7 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +22 -5
- package/dist/types/reachability/index.d.ts +1 -1
- package/dist/types/reachability/reachability.types.d.ts +7 -0
- package/dist/types/reachability/util.d.ts +17 -0
- package/dist/types/reactions/reactions.type.d.ts +3 -0
- package/dist/webinar/index.js +305 -159
- package/dist/webinar/index.js.map +1 -1
- package/package.json +22 -22
- package/src/aiEnableRequest/index.ts +16 -0
- package/src/breakouts/breakout.ts +3 -1
- package/src/breakouts/index.ts +31 -0
- package/src/config.ts +2 -2
- package/src/constants.ts +20 -3
- package/src/controls-options-manager/constants.ts +14 -1
- package/src/controls-options-manager/index.ts +87 -28
- package/src/controls-options-manager/util.ts +81 -1
- package/src/hashTree/constants.ts +16 -0
- package/src/hashTree/hashTreeParser.ts +580 -196
- package/src/hashTree/utils.ts +36 -0
- package/src/index.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +88 -12
- package/src/interceptors/locusRetry.ts +25 -4
- package/src/interpretation/index.ts +27 -9
- package/src/interpretation/interpretation.types.ts +11 -0
- package/src/locus-info/controlsUtils.ts +3 -1
- package/src/locus-info/index.ts +304 -100
- package/src/locus-info/infoUtils.ts +41 -6
- package/src/locus-info/types.ts +25 -1
- package/src/media/index.ts +3 -0
- package/src/media/properties.ts +1 -0
- package/src/meeting/in-meeting-actions.ts +8 -0
- package/src/meeting/index.ts +494 -67
- package/src/meeting/locusMediaRequest.ts +106 -6
- package/src/meeting/muteState.ts +10 -1
- package/src/meeting/request.ts +11 -0
- package/src/meeting/util.ts +47 -5
- package/src/meeting-info/meeting-info-v2.ts +4 -2
- package/src/meetings/index.ts +133 -78
- package/src/meetings/meetings.types.ts +19 -0
- package/src/meetings/request.ts +43 -0
- package/src/meetings/util.ts +97 -1
- package/src/member/index.ts +10 -0
- package/src/member/types.ts +1 -0
- package/src/member/util.ts +29 -0
- package/src/members/index.ts +70 -7
- package/src/members/util.ts +12 -4
- package/src/metrics/constants.ts +4 -0
- package/src/multistream/codec/constants.ts +58 -0
- package/src/multistream/mediaRequestManager.ts +119 -28
- package/src/multistream/receiveSlot.ts +18 -0
- package/src/reachability/index.ts +19 -15
- package/src/reachability/reachability.types.ts +11 -0
- package/src/reachability/util.ts +36 -0
- package/src/reactions/reactions.type.ts +3 -0
- package/src/recording-controller/index.ts +1 -2
- package/src/webinar/index.ts +214 -36
- package/test/unit/spec/aiEnableRequest/index.ts +86 -0
- package/test/unit/spec/breakouts/breakout.ts +9 -3
- package/test/unit/spec/breakouts/index.ts +49 -0
- package/test/unit/spec/controls-options-manager/index.js +244 -29
- package/test/unit/spec/controls-options-manager/util.js +165 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1838 -180
- package/test/unit/spec/hashTree/utils.ts +125 -1
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +196 -0
- package/test/unit/spec/interceptors/locusRetry.ts +205 -4
- package/test/unit/spec/interpretation/index.ts +26 -4
- package/test/unit/spec/locus-info/controlsUtils.js +172 -57
- package/test/unit/spec/locus-info/index.js +499 -81
- package/test/unit/spec/locus-info/infoUtils.js +184 -1
- package/test/unit/spec/media/index.ts +31 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
- package/test/unit/spec/meeting/index.js +1615 -42
- package/test/unit/spec/meeting/locusMediaRequest.ts +302 -4
- package/test/unit/spec/meeting/muteState.js +81 -0
- package/test/unit/spec/meeting/request.js +12 -0
- package/test/unit/spec/meeting/utils.js +157 -1
- package/test/unit/spec/meeting-info/meetinginfov2.js +19 -10
- package/test/unit/spec/meetings/index.js +363 -36
- package/test/unit/spec/meetings/request.js +141 -0
- package/test/unit/spec/meetings/utils.js +189 -0
- package/test/unit/spec/member/index.js +7 -0
- package/test/unit/spec/member/util.js +89 -0
- package/test/unit/spec/members/index.js +216 -0
- package/test/unit/spec/members/request.js +37 -1
- package/test/unit/spec/members/utils.js +63 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +501 -37
- package/test/unit/spec/reachability/index.ts +59 -46
- package/test/unit/spec/reachability/util.ts +31 -0
- package/test/unit/spec/recording-controller/index.js +9 -8
- package/test/unit/spec/webinar/index.ts +329 -28
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/* eslint-disable valid-jsdoc */
|
|
2
2
|
import {defer} from 'lodash';
|
|
3
|
-
import {Defer
|
|
3
|
+
import {Defer} from '@webex/common';
|
|
4
4
|
import {EventEmitter} from 'events';
|
|
5
5
|
import {WebexPlugin} from '@webex/webex-core';
|
|
6
6
|
import {MEDIA, HTTP_VERBS, ROAP} from '../constants';
|
|
7
7
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
8
8
|
import {ClientMediaPreferences} from '../reachability/reachability.types';
|
|
9
|
+
import Metrics from '../metrics';
|
|
10
|
+
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
9
11
|
|
|
10
12
|
export type MediaRequestType = 'RoapMessage' | 'LocalMute';
|
|
11
13
|
export type RequestResult = any;
|
|
@@ -37,13 +39,13 @@ export type Request = RoapRequest | LocalMuteRequest;
|
|
|
37
39
|
class InternalRequestInfo {
|
|
38
40
|
public readonly request: Request;
|
|
39
41
|
private pendingPromises: Defer[];
|
|
40
|
-
private sendRequestFn: (request: Request) => Promise<RequestResult>;
|
|
42
|
+
private sendRequestFn: (request: Request, selfUrlRetryCount: number) => Promise<RequestResult>;
|
|
41
43
|
|
|
42
44
|
/** Constructor */
|
|
43
45
|
constructor(
|
|
44
46
|
request: Request,
|
|
45
47
|
pendingPromise: Defer,
|
|
46
|
-
sendRequestFn: (request: Request) => Promise<RequestResult>
|
|
48
|
+
sendRequestFn: (request: Request, selfUrlRetryCount: number) => Promise<RequestResult>
|
|
47
49
|
) {
|
|
48
50
|
this.request = request;
|
|
49
51
|
this.pendingPromises = [pendingPromise];
|
|
@@ -69,7 +71,7 @@ class InternalRequestInfo {
|
|
|
69
71
|
* is completed (no matter if it succeeded or failed).
|
|
70
72
|
*/
|
|
71
73
|
public execute(): Promise<void> {
|
|
72
|
-
return this.sendRequestFn(this.request)
|
|
74
|
+
return this.sendRequestFn(this.request, 0)
|
|
73
75
|
.then((result) => {
|
|
74
76
|
// resolve all the pending promises associated with this request
|
|
75
77
|
this.pendingPromises.forEach((d) => d.resolve(result));
|
|
@@ -91,8 +93,12 @@ export type Config = {
|
|
|
91
93
|
correlationId: string;
|
|
92
94
|
meetingId: string;
|
|
93
95
|
preferTranscoding: boolean;
|
|
96
|
+
getCurrentSelfUrl: () => string | undefined;
|
|
97
|
+
waitForSelfUrlChange: () => Promise<void>;
|
|
94
98
|
};
|
|
95
99
|
|
|
100
|
+
const MAX_SELF_URL_RETRY_COUNT = 2;
|
|
101
|
+
|
|
96
102
|
/**
|
|
97
103
|
* Returns true if the request is triggering confluence creation in the server
|
|
98
104
|
*/
|
|
@@ -194,7 +200,13 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
194
200
|
/**
|
|
195
201
|
* Prepares the uri and body for the media request to be sent to Locus
|
|
196
202
|
*/
|
|
197
|
-
private sendHttpRequest(request: Request) {
|
|
203
|
+
private async sendHttpRequest(request: Request, selfUrlRetryCount = 0) {
|
|
204
|
+
// Resolve selfUrl lazily at send time. Locus rotates it on session
|
|
205
|
+
// transitions (breakout end, move-to, lobby admit) and the value
|
|
206
|
+
// captured upstream in roap/index.ts may be stale by the time we
|
|
207
|
+
// leave the queue. Persist the resolved URL on the request so a
|
|
208
|
+
// retry can detect a further rotation.
|
|
209
|
+
request.selfUrl = this.getCurrentSelfUrl(request);
|
|
198
210
|
const uri = `${request.selfUrl}/${MEDIA}`;
|
|
199
211
|
|
|
200
212
|
const {audioMuted, videoMuted} = this.getLatestMuteState();
|
|
@@ -263,7 +275,21 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
263
275
|
|
|
264
276
|
return result;
|
|
265
277
|
})
|
|
266
|
-
.catch((e) => {
|
|
278
|
+
.catch(async (e) => {
|
|
279
|
+
if (
|
|
280
|
+
e?.statusCode === 409 &&
|
|
281
|
+
(await this.shouldRetryOnSelfUrlChange(request, selfUrlRetryCount))
|
|
282
|
+
) {
|
|
283
|
+
// In-flight race: selfUrl rotated after we left the queue but
|
|
284
|
+
// before Locus rejected the request. Re-send; getCurrentSelfUrl
|
|
285
|
+
// will pick up the new URL. The returned promise replaces the
|
|
286
|
+
// rejection, so the caller's pendingPromise resolves correctly.
|
|
287
|
+
// Advance the retry count here so the guard in
|
|
288
|
+
// shouldRetryOnSelfUrlChange eventually stops after
|
|
289
|
+
// MAX_SELF_URL_RETRY_COUNT attempts.
|
|
290
|
+
return this.sendHttpRequest(request, selfUrlRetryCount + 1);
|
|
291
|
+
}
|
|
292
|
+
|
|
267
293
|
if (
|
|
268
294
|
isRequestAffectingConfluenceState(request) &&
|
|
269
295
|
this.confluenceState === 'creation in progress'
|
|
@@ -301,6 +327,80 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
301
327
|
return promise;
|
|
302
328
|
}
|
|
303
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Returns the latest selfUrl for this meeting, falling back to the value
|
|
332
|
+
* captured when the request was enqueued.
|
|
333
|
+
*/
|
|
334
|
+
private getCurrentSelfUrl(request: Request): string {
|
|
335
|
+
const currentSelfUrl = this.config.getCurrentSelfUrl();
|
|
336
|
+
|
|
337
|
+
if (currentSelfUrl && currentSelfUrl !== request.selfUrl) {
|
|
338
|
+
LoggerProxy.logger.info(
|
|
339
|
+
`Meeting:LocusMediaRequest#getCurrentSelfUrl --> resolved updated selfUrl, using ${currentSelfUrl}`
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LOCUS_MEDIA_REQUEST_RETRY, {
|
|
343
|
+
correlation_id: this.config.correlationId,
|
|
344
|
+
reason: 'selfUrlUpdatedBeforeMediaRequest',
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
return currentSelfUrl;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return request.selfUrl;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Decides whether a 409 warrants a retry against the meeting's latest
|
|
355
|
+
* selfUrl.
|
|
356
|
+
*/
|
|
357
|
+
private async shouldRetryOnSelfUrlChange(
|
|
358
|
+
request: Request,
|
|
359
|
+
selfUrlRetryCount: number
|
|
360
|
+
): Promise<boolean> {
|
|
361
|
+
if (selfUrlRetryCount >= MAX_SELF_URL_RETRY_COUNT) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const roapMessageType =
|
|
366
|
+
request.type === 'RoapMessage' ? request.roapMessage?.messageType : undefined;
|
|
367
|
+
|
|
368
|
+
const currentSelfUrl = this.getCurrentSelfUrl(request);
|
|
369
|
+
|
|
370
|
+
if (!currentSelfUrl || currentSelfUrl === request.selfUrl) {
|
|
371
|
+
await this.config.waitForSelfUrlChange();
|
|
372
|
+
|
|
373
|
+
const latestSelfUrl = this.getCurrentSelfUrl(request);
|
|
374
|
+
|
|
375
|
+
if (!latestSelfUrl || latestSelfUrl === request.selfUrl) {
|
|
376
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LOCUS_MEDIA_REQUEST_RETRY, {
|
|
377
|
+
correlation_id: this.config.correlationId,
|
|
378
|
+
reason: 'selfUrlNotChangedAfterWait',
|
|
379
|
+
retryAttempt: selfUrlRetryCount,
|
|
380
|
+
roapMessageType,
|
|
381
|
+
});
|
|
382
|
+
LoggerProxy.logger.info(
|
|
383
|
+
'Meeting:LocusMediaRequest#sendHttpRequest --> 409 conflict, no new selfUrl even after waiting'
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.LOCUS_MEDIA_REQUEST_RETRY, {
|
|
390
|
+
correlation_id: this.config.correlationId,
|
|
391
|
+
reason: 'selfUrlChangedAfterWait',
|
|
392
|
+
retryAttempt: selfUrlRetryCount,
|
|
393
|
+
roapMessageType,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
LoggerProxy.logger.info(
|
|
398
|
+
`Meeting:LocusMediaRequest#sendHttpRequest --> 409 conflict, retrying ${request.type} with updated selfUrl`
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
|
|
304
404
|
/**
|
|
305
405
|
* Sends a media request to Locus
|
|
306
406
|
*/
|
package/src/meeting/muteState.ts
CHANGED
|
@@ -375,7 +375,16 @@ export class MuteState {
|
|
|
375
375
|
}
|
|
376
376
|
if (muted !== undefined) {
|
|
377
377
|
this.state.server.remoteMute = muted;
|
|
378
|
-
|
|
378
|
+
// BO->Main may replay a stale remoteMute=false from the locus cache.
|
|
379
|
+
// Only enforce the mute on muted=true (also locking client.localMute so a later stale
|
|
380
|
+
// false can't flip isMuted()), and never touch the stream on muted=false — the
|
|
381
|
+
// legitimate server-driven unmute path is LOCAL_UNMUTE_REQUIRED. Always sync client
|
|
382
|
+
// intent back so other participants' tiles still show the mute icon.
|
|
383
|
+
if (muted) {
|
|
384
|
+
this.state.client.localMute = true;
|
|
385
|
+
this.muteLocalStream(meeting, true, 'remotelyMuted');
|
|
386
|
+
}
|
|
387
|
+
this.applyClientStateToServer(meeting);
|
|
379
388
|
}
|
|
380
389
|
}
|
|
381
390
|
|
package/src/meeting/request.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
SEND_DTMF_ENDPOINT,
|
|
27
27
|
_SLIDES_,
|
|
28
28
|
ANNOTATION,
|
|
29
|
+
INTERPRETATION,
|
|
29
30
|
} from '../constants';
|
|
30
31
|
import {
|
|
31
32
|
SendReactionOptions,
|
|
@@ -135,6 +136,7 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
135
136
|
locale?: string;
|
|
136
137
|
deviceCapabilities?: Array<string>;
|
|
137
138
|
liveAnnotationSupported: boolean;
|
|
139
|
+
enableSimultaneousInterpretation: boolean;
|
|
138
140
|
alias?: string;
|
|
139
141
|
clientMediaPreferences: ClientMediaPreferences;
|
|
140
142
|
}) {
|
|
@@ -158,6 +160,7 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
158
160
|
locale,
|
|
159
161
|
deviceCapabilities = [],
|
|
160
162
|
liveAnnotationSupported,
|
|
163
|
+
enableSimultaneousInterpretation,
|
|
161
164
|
clientMediaPreferences,
|
|
162
165
|
alias,
|
|
163
166
|
} = options;
|
|
@@ -193,6 +196,14 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
193
196
|
if (liveAnnotationSupported) {
|
|
194
197
|
deviceCapabilities.push(ANNOTATION.ANNOTATION_ON_SHARE_SUPPORTED);
|
|
195
198
|
}
|
|
199
|
+
if (enableSimultaneousInterpretation) {
|
|
200
|
+
deviceCapabilities.push(
|
|
201
|
+
INTERPRETATION.CAPABILITIES.HOST_CONTROL_SI_SUPPORTED,
|
|
202
|
+
INTERPRETATION.CAPABILITIES.INTERPRETER_CONTROL_SI_SUPPORTED,
|
|
203
|
+
INTERPRETATION.CAPABILITIES.SI_HANDOVER_SUPPORTED,
|
|
204
|
+
INTERPRETATION.CAPABILITIES.SIGN_INTERPRETER_SUPPORTED
|
|
205
|
+
);
|
|
206
|
+
}
|
|
196
207
|
|
|
197
208
|
// append installationId to device config if it exists
|
|
198
209
|
// @ts-ignore
|
package/src/meeting/util.ts
CHANGED
|
@@ -317,6 +317,7 @@ const MeetingUtil = {
|
|
|
317
317
|
locale: options.locale,
|
|
318
318
|
deviceCapabilities: options.deviceCapabilities,
|
|
319
319
|
liveAnnotationSupported: options.liveAnnotationSupported,
|
|
320
|
+
enableSimultaneousInterpretation: options.enableSimultaneousInterpretation,
|
|
320
321
|
clientMediaPreferences,
|
|
321
322
|
alias: options.alias,
|
|
322
323
|
})
|
|
@@ -371,6 +372,7 @@ const MeetingUtil = {
|
|
|
371
372
|
meeting.breakouts.cleanUp();
|
|
372
373
|
meeting.webinar.cleanUp();
|
|
373
374
|
meeting.simultaneousInterpretation.cleanUp();
|
|
375
|
+
meeting.locusInfo.cleanUp();
|
|
374
376
|
meeting.locusMediaRequest = undefined;
|
|
375
377
|
|
|
376
378
|
meeting.webex?.internal?.newMetrics?.callDiagnosticMetrics?.clearEventLimitsForCorrelationId(
|
|
@@ -845,6 +847,19 @@ const MeetingUtil = {
|
|
|
845
847
|
requestBody.sequence = sequence;
|
|
846
848
|
},
|
|
847
849
|
|
|
850
|
+
/**
|
|
851
|
+
* Checks if Locus API response contains a Locus DTO
|
|
852
|
+
*
|
|
853
|
+
* @param {any} response http response from Locus API call
|
|
854
|
+
* @returns {boolean} true if response contains a Locus DTO
|
|
855
|
+
*/
|
|
856
|
+
isLocusDtoInAPIResponse(response: any) {
|
|
857
|
+
return (
|
|
858
|
+
response?.body?.locus || // for APIs called on our participant - locus is one of props in the response body
|
|
859
|
+
response?.body?.url // for APIs that act on locus itself (like mute all), the body is the locus
|
|
860
|
+
);
|
|
861
|
+
},
|
|
862
|
+
|
|
848
863
|
/**
|
|
849
864
|
* Updates the locus info for the meeting with the locus
|
|
850
865
|
* information returned from API requests made to Locus
|
|
@@ -853,12 +868,13 @@ const MeetingUtil = {
|
|
|
853
868
|
* @param {Object} response The response of the http request
|
|
854
869
|
* @returns {Object}
|
|
855
870
|
*/
|
|
856
|
-
updateLocusFromApiResponse: (meeting, response) => {
|
|
871
|
+
updateLocusFromApiResponse: (meeting: any, response: any) => {
|
|
857
872
|
if (!meeting) {
|
|
858
873
|
return response;
|
|
859
874
|
}
|
|
860
875
|
|
|
861
|
-
|
|
876
|
+
// locus API responses can come in different shapes:
|
|
877
|
+
if (MeetingUtil.isLocusDtoInAPIResponse(response)) {
|
|
862
878
|
meeting.locusInfo.handleLocusAPIResponse(meeting, response.body);
|
|
863
879
|
}
|
|
864
880
|
|
|
@@ -904,9 +920,20 @@ const MeetingUtil = {
|
|
|
904
920
|
|
|
905
921
|
const options = buildLocusDeltaRequestOptions(originalOptions);
|
|
906
922
|
|
|
907
|
-
return meeting
|
|
908
|
-
|
|
909
|
-
|
|
923
|
+
return meeting.request(options).then((response) => {
|
|
924
|
+
const requestUri = options?.uri;
|
|
925
|
+
const meetingLocusUrl = meeting.locusUrl;
|
|
926
|
+
|
|
927
|
+
if (!requestUri || !meetingLocusUrl || !requestUri.startsWith(meetingLocusUrl)) {
|
|
928
|
+
LoggerProxy.logger.info(
|
|
929
|
+
`Meeting:util#generateLocusDeltaRequest --> skipping updateLocusFromApiResponse, request uri "${requestUri}" does not match meeting locusUrl "${meetingLocusUrl}"`
|
|
930
|
+
);
|
|
931
|
+
|
|
932
|
+
return response;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return MeetingUtil.updateLocusFromApiResponse(meeting, response);
|
|
936
|
+
});
|
|
910
937
|
};
|
|
911
938
|
|
|
912
939
|
return locusDeltaRequest;
|
|
@@ -930,6 +957,21 @@ const MeetingUtil = {
|
|
|
930
957
|
attendeeRequestAiAssistantDeclinedAll: (displayHints = []) =>
|
|
931
958
|
displayHints.includes(DISPLAY_HINTS.ATTENDEE_REQUEST_AI_ASSISTANT_DECLINED_ALL),
|
|
932
959
|
|
|
960
|
+
isAnonymizeDisplayNamesEnabled: (displayHints) =>
|
|
961
|
+
displayHints.includes(DISPLAY_HINTS.ANONYMOUS_DISPLAY_NAMES_ENABLED),
|
|
962
|
+
|
|
963
|
+
canViewTheParticipantList: (displayHints, canNotViewTheParticipantList: boolean) => {
|
|
964
|
+
if (!displayHints.includes(DISPLAY_HINTS.VIEW_THE_PARTICIPANT_LIST)) {
|
|
965
|
+
return false;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
if (canNotViewTheParticipantList) {
|
|
969
|
+
return false;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
return displayHints.includes(DISPLAY_HINTS.CAN_VIEW_THE_PARTICIPANT_LIST);
|
|
973
|
+
},
|
|
974
|
+
|
|
933
975
|
selfSupportsFeature: (feature: SELF_POLICY, userPolicies: Record<SELF_POLICY, boolean>) => {
|
|
934
976
|
if (!userPolicies) {
|
|
935
977
|
return true;
|
|
@@ -19,7 +19,7 @@ const ADHOC_MEETING_DEFAULT_ERROR =
|
|
|
19
19
|
const MEETING_IS_IN_PROGRESS_MESSAGE = 'Meeting is in progress';
|
|
20
20
|
const STATIC_MEETING_LINK_ALREADY_EXISTS_MESSAGE = 'Static meeting link already exists';
|
|
21
21
|
const FETCH_STATIC_MEETING_LINK = 'Meeting link does not exists for conversation';
|
|
22
|
-
const CAPTCHA_ERROR_REQUIRES_PASSWORD_CODES = [423005, 423006];
|
|
22
|
+
const CAPTCHA_ERROR_REQUIRES_PASSWORD_CODES = [423005, 423006, 423008];
|
|
23
23
|
const CAPTCHA_ERROR_REQUIRES_REGISTRATION_ID_CODES = [423007];
|
|
24
24
|
|
|
25
25
|
const POLICY_ERROR_CODES = [403049, 403104, 403103, 403048, 403102, 403101];
|
|
@@ -35,7 +35,9 @@ const JOIN_FORBIDDEN_CODES = [403003];
|
|
|
35
35
|
* 403137 - Registration ID verified failure
|
|
36
36
|
*
|
|
37
37
|
*/
|
|
38
|
-
const JOIN_WEBINAR_ERROR_CODES = [
|
|
38
|
+
const JOIN_WEBINAR_ERROR_CODES = [
|
|
39
|
+
403021, 403022, 403024, 403137, 423007, 403026, 403037, 403137, 403106,
|
|
40
|
+
];
|
|
39
41
|
|
|
40
42
|
/**
|
|
41
43
|
* Error to indicate that wbxappapi requires a password
|