@webex/plugin-meetings 3.8.1-web-workers-keepalive.1 → 3.9.0-next.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/constants.js +24 -2
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +39 -85
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/brbState.js +14 -12
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +6 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +274 -140
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +19 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/type.js +7 -0
- package/dist/meeting/type.js.map +1 -0
- package/dist/meeting/util.js +68 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +35 -33
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js.map +1 -1
- package/dist/members/index.js +11 -9
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +3 -3
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +18 -6
- package/dist/members/util.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/multistream/sendSlotManager.js +32 -2
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/types/constants.d.ts +22 -0
- package/dist/types/locus-info/index.d.ts +0 -9
- package/dist/types/meeting/brbState.d.ts +0 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +40 -19
- package/dist/types/meeting/request.d.ts +9 -1
- package/dist/types/meeting/request.type.d.ts +74 -0
- package/dist/types/meeting/type.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +3 -0
- package/dist/types/members/index.d.ts +10 -7
- package/dist/types/members/request.d.ts +1 -1
- package/dist/types/members/util.d.ts +7 -3
- package/dist/types/multistream/remoteMedia.d.ts +20 -1
- package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
- package/dist/types/multistream/sendSlotManager.d.ts +16 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -23
- package/src/constants.ts +23 -2
- package/src/locus-info/index.ts +48 -86
- package/src/meeting/brbState.ts +9 -7
- package/src/meeting/in-meeting-actions.ts +13 -0
- package/src/meeting/index.ts +165 -38
- package/src/meeting/request.ts +16 -0
- package/src/meeting/request.type.ts +64 -0
- package/src/meeting/type.ts +9 -0
- package/src/meeting/util.ts +73 -2
- package/src/meetings/index.ts +3 -2
- package/src/member/index.ts +1 -0
- package/src/members/index.ts +13 -10
- package/src/members/request.ts +2 -2
- package/src/members/util.ts +16 -4
- package/src/multistream/mediaRequestManager.ts +7 -7
- package/src/multistream/remoteMedia.ts +34 -4
- package/src/multistream/remoteMediaGroup.ts +37 -2
- package/src/multistream/sendSlotManager.ts +34 -2
- package/test/unit/spec/locus-info/index.js +199 -83
- package/test/unit/spec/meeting/brbState.ts +9 -9
- package/test/unit/spec/meeting/in-meeting-actions.ts +6 -0
- package/test/unit/spec/meeting/index.js +729 -80
- package/test/unit/spec/meeting/request.js +71 -0
- package/test/unit/spec/meeting/utils.js +122 -1
- package/test/unit/spec/meetings/index.js +2 -0
- package/test/unit/spec/members/index.js +68 -9
- package/test/unit/spec/members/request.js +2 -2
- package/test/unit/spec/members/utils.js +27 -7
- package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
- package/test/unit/spec/multistream/remoteMedia.ts +66 -2
- package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
- package/test/unit/spec/reachability/index.ts +3 -1
@@ -71,6 +71,9 @@ declare const MeetingUtil: {
|
|
71
71
|
canStopTranscribing: (displayHints: any) => any;
|
72
72
|
isClosedCaptionActive: (displayHints: any) => any;
|
73
73
|
canStartManualCaption: (displayHints: any) => any;
|
74
|
+
isLocalRecordingStarted: (displayHints: any) => any;
|
75
|
+
isLocalRecordingStopped: (displayHints: any) => any;
|
76
|
+
isLocalRecordingPaused: (displayHints: any) => any;
|
74
77
|
canStopManualCaption: (displayHints: any) => any;
|
75
78
|
isManualCaptionActive: (displayHints: any) => any;
|
76
79
|
isWebexAssistantActive: (displayHints: any) => any;
|
@@ -4,6 +4,7 @@ import MembersCollection from './collection';
|
|
4
4
|
import { ReceiveSlotManager } from '../multistream/receiveSlotManager';
|
5
5
|
import { MediaRequestManager } from '../multistream/mediaRequestManager';
|
6
6
|
import { ServerRoleShape } from './types';
|
7
|
+
import { Invitee } from '../meeting/type';
|
7
8
|
/**
|
8
9
|
* @class Members
|
9
10
|
*/
|
@@ -212,26 +213,28 @@ export default class Members extends StatelessWebexPlugin {
|
|
212
213
|
private update;
|
213
214
|
/**
|
214
215
|
* Adds a guest Member to the associated meeting
|
215
|
-
* @param {
|
216
|
+
* @param {Invitee} invitee
|
216
217
|
* @param {Boolean} [alertIfActive]
|
217
218
|
* @returns {Promise}
|
218
219
|
* @memberof Members
|
219
220
|
*/
|
220
|
-
addMember(invitee:
|
221
|
+
addMember(invitee: Invitee, alertIfActive?: boolean): any;
|
221
222
|
/**
|
222
223
|
* Cancels an outgoing PSTN call to the associated meeting
|
223
|
-
* @param {
|
224
|
+
* @param {Invitee} invitee
|
224
225
|
* @returns {Promise}
|
225
226
|
* @memberof Members
|
226
227
|
*/
|
227
|
-
cancelPhoneInvite(invitee:
|
228
|
+
cancelPhoneInvite(invitee: Invitee): any;
|
228
229
|
/**
|
229
|
-
* Cancels an SIP call to the associated meeting
|
230
|
-
* @param {
|
230
|
+
* Cancels an SIP/phone call to the associated meeting
|
231
|
+
* @param {Invitee} invitee
|
232
|
+
* @param {String} invitee.memberId - The memberId of the invitee
|
233
|
+
* @param {Boolean} [invitee.isInternalNumber] - When cancel phone invitation, if the number is internal
|
231
234
|
* @returns {Promise}
|
232
235
|
* @memberof Members
|
233
236
|
*/
|
234
|
-
|
237
|
+
cancelInviteByMemberId(invitee: Invitee): any;
|
235
238
|
/**
|
236
239
|
* Admits waiting members (invited guests to meeting)
|
237
240
|
* @param {Array} memberIds
|
@@ -136,5 +136,5 @@ export default class MembersRequest extends StatelessWebexPlugin {
|
|
136
136
|
* @throws {Error} if the options are not valid and complete, must have invitee with memberId AND locusUrl
|
137
137
|
* @memberof MembersRequest
|
138
138
|
*/
|
139
|
-
|
139
|
+
cancelInviteByMemberId(options: any): Promise<any>;
|
140
140
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { RoleAssignmentOptions, RoleAssignmentRequest, ServerRoleShape } from './types';
|
2
|
+
import { Invitee } from '../meeting/type';
|
2
3
|
declare const MembersUtil: {
|
3
4
|
/**
|
4
5
|
* @param {Object} invitee with emailAddress, email or phoneNumber
|
@@ -26,6 +27,7 @@ declare const MembersUtil: {
|
|
26
27
|
*/
|
27
28
|
getAddMemberBody: (options: any) => {
|
28
29
|
invitees: {
|
30
|
+
isInternalNumber?: any;
|
29
31
|
roles?: any;
|
30
32
|
address: any;
|
31
33
|
}[];
|
@@ -55,13 +57,14 @@ declare const MembersUtil: {
|
|
55
57
|
uri: any;
|
56
58
|
body: {
|
57
59
|
invitees: {
|
60
|
+
isInternalNumber?: any;
|
58
61
|
roles?: any;
|
59
62
|
address: any;
|
60
63
|
}[];
|
61
64
|
alertIfActive: any;
|
62
65
|
};
|
63
66
|
};
|
64
|
-
isInvalidInvitee: (invitee:
|
67
|
+
isInvalidInvitee: (invitee: Invitee) => boolean;
|
65
68
|
getRemoveMemberRequestParams: (options: any) => {
|
66
69
|
method: string;
|
67
70
|
uri: string;
|
@@ -228,16 +231,17 @@ declare const MembersUtil: {
|
|
228
231
|
}[];
|
229
232
|
};
|
230
233
|
};
|
231
|
-
|
234
|
+
cancelInviteByMemberIdOptions: (invitee: any, locusUrl: any) => {
|
232
235
|
invitee: any;
|
233
236
|
locusUrl: any;
|
234
237
|
};
|
235
|
-
|
238
|
+
generateCancelInviteByMemberIdRequestParams: (options: any) => {
|
236
239
|
method: string;
|
237
240
|
uri: any;
|
238
241
|
body: {
|
239
242
|
actionType: string;
|
240
243
|
invitees: {
|
244
|
+
isInternalNumber?: any;
|
241
245
|
address: any;
|
242
246
|
}[];
|
243
247
|
};
|
@@ -7,9 +7,17 @@ export declare const RemoteMediaEvents: {
|
|
7
7
|
Stopped: string;
|
8
8
|
};
|
9
9
|
export type RemoteVideoResolution = 'thumbnail' | 'very small' | 'small' | 'medium' | 'large' | 'best';
|
10
|
+
export declare const MAX_FS_VALUES: {
|
11
|
+
'90p': number;
|
12
|
+
'180p': number;
|
13
|
+
'360p': number;
|
14
|
+
'540p': number;
|
15
|
+
'720p': number;
|
16
|
+
'1080p': number;
|
17
|
+
};
|
10
18
|
/**
|
11
19
|
* Converts pane size into h264 maxFs
|
12
|
-
* @param {
|
20
|
+
* @param {RemoteVideoResolution} paneSize
|
13
21
|
* @returns {number}
|
14
22
|
*/
|
15
23
|
export declare function getMaxFs(paneSize: RemoteVideoResolution): number;
|
@@ -29,6 +37,12 @@ export declare class RemoteMedia extends EventsScope {
|
|
29
37
|
private readonly options;
|
30
38
|
private mediaRequestId?;
|
31
39
|
readonly id: RemoteMediaId;
|
40
|
+
/**
|
41
|
+
* The max frame size of the media request, used for logging and media requests.
|
42
|
+
* Set by setSizeHint() based on video element dimensions.
|
43
|
+
* When > 0, this value takes precedence over options.resolution in sendMediaRequest().
|
44
|
+
*/
|
45
|
+
private maxFrameSize;
|
32
46
|
/**
|
33
47
|
* Constructs RemoteMedia instance
|
34
48
|
*
|
@@ -45,6 +59,11 @@ export declare class RemoteMedia extends EventsScope {
|
|
45
59
|
* @note width/height of 0 will be ignored
|
46
60
|
*/
|
47
61
|
setSizeHint(width: any, height: any): void;
|
62
|
+
/**
|
63
|
+
* Get the current effective maxFs value that would be used in media requests
|
64
|
+
* @returns {number | undefined} The maxFs value, or undefined if no constraints
|
65
|
+
*/
|
66
|
+
getEffectiveMaxFs(): number | undefined;
|
48
67
|
/**
|
49
68
|
* registers event listeners on the receive slot and forwards all the events
|
50
69
|
*/
|
@@ -45,5 +45,16 @@ export declare class RemoteMediaGroup {
|
|
45
45
|
* @returns true if remote media is found
|
46
46
|
*/
|
47
47
|
includes(remoteMedia: RemoteMedia, filter?: 'all' | 'pinned' | 'unpinned'): boolean;
|
48
|
+
/**
|
49
|
+
* Calculate the effective maxFs for the active speaker media request based on unpinned RemoteMedia instances
|
50
|
+
* @returns {number | undefined} The calculated maxFs value, or undefined if no constraints
|
51
|
+
* @private
|
52
|
+
*/
|
53
|
+
private getEffectiveMaxFsForActiveSpeaker;
|
54
|
+
/**
|
55
|
+
* Get the current effective maxFs that would be used for the active speaker media request
|
56
|
+
* @returns {number | undefined} The effective maxFs value
|
57
|
+
*/
|
58
|
+
getEffectiveMaxFs(): number | undefined;
|
48
59
|
}
|
49
60
|
export {};
|
@@ -1,7 +1,17 @@
|
|
1
1
|
import { SendSlot, MediaType, LocalStream, MultistreamRoapMediaConnection, NamedMediaGroup, StreamState } from '@webex/internal-media-core';
|
2
|
+
/**
|
3
|
+
* This class is used to manage the sendSlots for the given media types.
|
4
|
+
*/
|
2
5
|
export default class SendSlotManager {
|
3
6
|
private readonly slots;
|
4
7
|
private readonly LoggerProxy;
|
8
|
+
private readonly sourceStateOverrides;
|
9
|
+
/**
|
10
|
+
* Constructor for SendSlotManager
|
11
|
+
*
|
12
|
+
* @param {any} LoggerProxy is used to log the messages
|
13
|
+
* @constructor
|
14
|
+
*/
|
5
15
|
constructor(LoggerProxy: any);
|
6
16
|
/**
|
7
17
|
* This method is used to create a sendSlot for the given mediaType and returns the created sendSlot
|
@@ -32,6 +42,12 @@ export default class SendSlotManager {
|
|
32
42
|
* @returns {void}
|
33
43
|
*/
|
34
44
|
setSourceStateOverride(mediaType: MediaType, state: StreamState | null): void;
|
45
|
+
/**
|
46
|
+
* Gets the source state override for the given media type.
|
47
|
+
* @param {MediaType} mediaType - The type of media to get the source state override for.
|
48
|
+
* @returns {StreamState | null} - The current source state override or null if not set.
|
49
|
+
*/
|
50
|
+
private getSourceStateOverride;
|
35
51
|
/**
|
36
52
|
* This method publishes the given stream to the sendSlot for the given mediaType
|
37
53
|
* @param {MediaType} mediaType MediaType of the sendSlot to which a stream needs to be published (AUDIO_MAIN/VIDEO_MAIN/AUDIO_SLIDES/VIDEO_SLIDES)
|
package/dist/webinar/index.js
CHANGED
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@webex/plugin-meetings",
|
3
3
|
"description": "",
|
4
|
-
"license": "Cisco
|
4
|
+
"license": "Cisco's General Terms (https://www.cisco.com/site/us/en/about/legal/contract-experience/index.html)",
|
5
5
|
"contributors": [
|
6
6
|
"Adam Weeks <adweeks@cisco.com> (https://adamweeks.com/)",
|
7
7
|
"Arun Ganeshan <arungane@cisco.com>",
|
@@ -43,13 +43,12 @@
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
46
|
-
"@webex/plugin-
|
47
|
-
"@webex/
|
48
|
-
"@webex/test-helper-
|
49
|
-
"@webex/test-helper-
|
50
|
-
"@webex/test-helper-
|
51
|
-
"@webex/test-helper-
|
52
|
-
"@webex/test-helper-test-users": "3.8.1-web-workers-keepalive.1",
|
46
|
+
"@webex/plugin-rooms": "3.8.1-next.15",
|
47
|
+
"@webex/test-helper-chai": "3.8.1-next.11",
|
48
|
+
"@webex/test-helper-mocha": "3.8.1-next.11",
|
49
|
+
"@webex/test-helper-mock-webex": "3.8.1-next.11",
|
50
|
+
"@webex/test-helper-retry": "3.8.1-next.11",
|
51
|
+
"@webex/test-helper-test-users": "3.8.1-next.11",
|
53
52
|
"chai": "^4.3.4",
|
54
53
|
"chai-as-promised": "^7.1.1",
|
55
54
|
"eslint": "^8.24.0",
|
@@ -61,23 +60,23 @@
|
|
61
60
|
"typescript": "^4.7.4"
|
62
61
|
},
|
63
62
|
"dependencies": {
|
64
|
-
"@webex/common": "3.8.1-
|
63
|
+
"@webex/common": "3.8.1-next.11",
|
65
64
|
"@webex/event-dictionary-ts": "^1.0.1819",
|
66
|
-
"@webex/internal-media-core": "2.18.
|
67
|
-
"@webex/internal-plugin-conversation": "3.8.1-
|
68
|
-
"@webex/internal-plugin-device": "3.8.1-
|
69
|
-
"@webex/internal-plugin-llm": "3.8.1-
|
70
|
-
"@webex/internal-plugin-mercury": "3.8.1-
|
71
|
-
"@webex/internal-plugin-metrics": "3.8.1-
|
72
|
-
"@webex/internal-plugin-support": "3.8.1-
|
73
|
-
"@webex/internal-plugin-user": "3.8.1-
|
74
|
-
"@webex/internal-plugin-voicea": "3.8.1-
|
75
|
-
"@webex/media-helpers": "3.8.1-
|
76
|
-
"@webex/plugin-people": "3.8.1-
|
77
|
-
"@webex/plugin-rooms": "3.8.1-
|
65
|
+
"@webex/internal-media-core": "2.18.5",
|
66
|
+
"@webex/internal-plugin-conversation": "3.8.1-next.18",
|
67
|
+
"@webex/internal-plugin-device": "3.8.1-next.15",
|
68
|
+
"@webex/internal-plugin-llm": "3.8.1-next.16",
|
69
|
+
"@webex/internal-plugin-mercury": "3.8.1-next.15",
|
70
|
+
"@webex/internal-plugin-metrics": "3.8.1-next.15",
|
71
|
+
"@webex/internal-plugin-support": "3.8.1-next.18",
|
72
|
+
"@webex/internal-plugin-user": "3.8.1-next.15",
|
73
|
+
"@webex/internal-plugin-voicea": "3.8.1-next.42",
|
74
|
+
"@webex/media-helpers": "3.8.1-next.16",
|
75
|
+
"@webex/plugin-people": "3.8.1-next.15",
|
76
|
+
"@webex/plugin-rooms": "3.8.1-next.15",
|
78
77
|
"@webex/ts-sdp": "^1.8.1",
|
79
78
|
"@webex/web-capabilities": "^1.6.0",
|
80
|
-
"@webex/webex-core": "3.8.1-
|
79
|
+
"@webex/webex-core": "3.8.1-next.15",
|
81
80
|
"ampersand-collection": "^2.0.2",
|
82
81
|
"bowser": "^2.11.0",
|
83
82
|
"btoa": "^1.2.1",
|
@@ -93,5 +92,5 @@
|
|
93
92
|
"//": [
|
94
93
|
"TODO: upgrade jwt-decode when moving to node 18"
|
95
94
|
],
|
96
|
-
"version": "3.
|
95
|
+
"version": "3.9.0-next.1"
|
97
96
|
}
|
package/src/constants.ts
CHANGED
@@ -217,6 +217,7 @@ export const DIALER_REGEX = {
|
|
217
217
|
PHONE_NUMBER:
|
218
218
|
/^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/,
|
219
219
|
E164_FORMAT: /^\+[1-9]\d{1,14}$/,
|
220
|
+
INTERNAL_NUMBER: /^\d{1,14}$/,
|
220
221
|
};
|
221
222
|
|
222
223
|
// eslint-disable-next-line max-len
|
@@ -262,7 +263,6 @@ export const RECORDING_STATE = {
|
|
262
263
|
PAUSED: 'paused',
|
263
264
|
RESUMED: 'resumed',
|
264
265
|
};
|
265
|
-
|
266
266
|
export const SHARE_STATUS = {
|
267
267
|
NO_SHARE: 'no_share',
|
268
268
|
REMOTE_SHARE_ACTIVE: 'remote_share_active',
|
@@ -948,6 +948,9 @@ export const DISPLAY_HINTS = {
|
|
948
948
|
PREMISE_RECORDING_CONTROL_PAUSE: 'PREMISE_RECORDING_CONTROL_PAUSE',
|
949
949
|
PREMISE_RECORDING_CONTROL_STOP: 'PREMISE_RECORDING_CONTROL_STOP',
|
950
950
|
PREMISE_RECORDING_CONTROL_RESUME: 'PREMISE_RECORDING_CONTROL_RESUME',
|
951
|
+
LOCAL_RECORDING_STATUS_STARTED: 'LOCAL_RECORDING_STATUS_STARTED',
|
952
|
+
LOCAL_RECORDING_STATUS_STOPPED: 'LOCAL_RECORDING_STATUS_STOPPED',
|
953
|
+
LOCAL_RECORDING_STATUS_PAUSED: 'LOCAL_RECORDING_STATUS_PAUSED',
|
951
954
|
LOCK_CONTROL_UNLOCK: 'LOCK_CONTROL_UNLOCK',
|
952
955
|
LOCK_CONTROL_LOCK: 'LOCK_CONTROL_LOCK',
|
953
956
|
LOCK_STATUS_LOCKED: 'LOCK_STATUS_LOCKED',
|
@@ -987,7 +990,6 @@ export const DISPLAY_HINTS = {
|
|
987
990
|
CAN_RENAME_SELF_AND_OBSERVED: 'CAN_RENAME_SELF_AND_OBSERVED',
|
988
991
|
CAN_RENAME_OTHERS: 'CAN_RENAME_OTHERS',
|
989
992
|
MOVE_TO_LOBBY: 'MOVE_TO_LOBBY',
|
990
|
-
|
991
993
|
// breakout session
|
992
994
|
BREAKOUT_MANAGEMENT: 'BREAKOUT_MANAGEMENT',
|
993
995
|
BROADCAST_MESSAGE_TO_BREAKOUT: 'BROADCAST_MESSAGE_TO_BREAKOUT',
|
@@ -1188,6 +1190,7 @@ export const QUALITY_LEVELS = {
|
|
1188
1190
|
HIGH: 'HIGH',
|
1189
1191
|
'360p': '360p',
|
1190
1192
|
'480p': '480p',
|
1193
|
+
'540p': '540p',
|
1191
1194
|
'720p': '720p',
|
1192
1195
|
'1080p': '1080p',
|
1193
1196
|
};
|
@@ -1217,6 +1220,18 @@ export const AVAILABLE_RESOLUTIONS = {
|
|
1217
1220
|
},
|
1218
1221
|
},
|
1219
1222
|
},
|
1223
|
+
'540p': {
|
1224
|
+
video: {
|
1225
|
+
width: {
|
1226
|
+
max: 960,
|
1227
|
+
ideal: 960,
|
1228
|
+
},
|
1229
|
+
height: {
|
1230
|
+
max: 540,
|
1231
|
+
ideal: 540,
|
1232
|
+
},
|
1233
|
+
},
|
1234
|
+
},
|
1220
1235
|
'720p': {
|
1221
1236
|
video: {
|
1222
1237
|
width: {
|
@@ -1357,3 +1372,9 @@ export const INITIAL_REGISTRATION_STATUS = {
|
|
1357
1372
|
mercuryConnect: false,
|
1358
1373
|
checkH264Support: false,
|
1359
1374
|
};
|
1375
|
+
|
1376
|
+
export const STAGE_MANAGER_TYPE = {
|
1377
|
+
LOGO: 0b001,
|
1378
|
+
BACKGROUND: 0b010,
|
1379
|
+
NAME_LABEL: 0b100,
|
1380
|
+
};
|
package/src/locus-info/index.ts
CHANGED
@@ -48,7 +48,6 @@ export default class LocusInfo extends EventsScope {
|
|
48
48
|
aclUrl: any;
|
49
49
|
baseSequence: any;
|
50
50
|
created: any;
|
51
|
-
deltaParticipants: any;
|
52
51
|
identities: any;
|
53
52
|
membership: any;
|
54
53
|
participants: any;
|
@@ -99,6 +98,7 @@ export default class LocusInfo extends EventsScope {
|
|
99
98
|
private doLocusSync(meeting: any) {
|
100
99
|
let isDelta;
|
101
100
|
let url;
|
101
|
+
let meetingDestroyed = false;
|
102
102
|
|
103
103
|
if (this.locusParser.workingCopy.syncUrl) {
|
104
104
|
url = this.locusParser.workingCopy.syncUrl;
|
@@ -134,32 +134,56 @@ export default class LocusInfo extends EventsScope {
|
|
134
134
|
|
135
135
|
isDelta = false;
|
136
136
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
137
|
+
// Locus sometimes returns 403, for example if meeting has ended, no point trying the fallback to full sync in that case
|
138
|
+
if (e.statusCode !== 403) {
|
139
|
+
return meeting.meetingRequest.getLocusDTO({url: meeting.locusUrl}).catch((err) => {
|
140
|
+
LoggerProxy.logger.info(
|
141
|
+
'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
|
142
|
+
);
|
143
|
+
this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
|
144
|
+
meetingDestroyed = true;
|
145
|
+
throw err;
|
146
|
+
});
|
147
|
+
}
|
148
|
+
LoggerProxy.logger.info(
|
149
|
+
'Locus-info:index#doLocusSync --> got 403 from Locus, skipping fallback to full sync, destroying the meeting'
|
150
|
+
);
|
151
|
+
} else {
|
152
|
+
LoggerProxy.logger.info(
|
153
|
+
'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
|
154
|
+
);
|
144
155
|
}
|
145
|
-
LoggerProxy.logger.info(
|
146
|
-
'Locus-info:index#doLocusSync --> fallback full sync failed, destroying the meeting'
|
147
|
-
);
|
148
156
|
this.webex.meetings.destroy(meeting, MEETING_REMOVED_REASON.LOCUS_DTO_SYNC_FAILED);
|
157
|
+
meetingDestroyed = true;
|
149
158
|
throw e;
|
150
159
|
})
|
151
160
|
.then((res) => {
|
152
|
-
if (
|
153
|
-
if (
|
154
|
-
meeting.locusInfo.handleLocusDelta(res.body, meeting);
|
155
|
-
} else {
|
161
|
+
if (isEmpty(res.body)) {
|
162
|
+
if (isDelta) {
|
156
163
|
LoggerProxy.logger.info(
|
157
164
|
'Locus-info:index#doLocusSync --> received empty body from syncUrl, so we already have latest Locus DTO'
|
158
165
|
);
|
166
|
+
} else {
|
167
|
+
LoggerProxy.logger.info(
|
168
|
+
'Locus-info:index#doLocusSync --> received empty body from full DTO sync request'
|
169
|
+
);
|
159
170
|
}
|
160
|
-
|
161
|
-
|
171
|
+
|
172
|
+
return;
|
173
|
+
}
|
174
|
+
|
175
|
+
if (isDelta) {
|
176
|
+
if (res.body.baseSequence) {
|
177
|
+
meeting.locusInfo.handleLocusDelta(res.body, meeting);
|
178
|
+
|
179
|
+
return;
|
180
|
+
}
|
181
|
+
// in some cases Locus might return us full DTO even when we asked for a delta
|
182
|
+
LoggerProxy.logger.info(
|
183
|
+
'Locus-info:index#doLocusSync --> got full DTO when we asked for delta'
|
184
|
+
);
|
162
185
|
}
|
186
|
+
meeting.locusInfo.onFullLocus(res.body);
|
163
187
|
})
|
164
188
|
.catch((e) => {
|
165
189
|
LoggerProxy.logger.info(
|
@@ -176,9 +200,11 @@ export default class LocusInfo extends EventsScope {
|
|
176
200
|
});
|
177
201
|
})
|
178
202
|
.finally(() => {
|
179
|
-
|
180
|
-
|
181
|
-
|
203
|
+
if (!meetingDestroyed) {
|
204
|
+
// Notify parser to resume processing delta events.
|
205
|
+
// Any deltas in the queue that have now been superseded by this sync will simply be ignored
|
206
|
+
this.locusParser.resume();
|
207
|
+
}
|
182
208
|
});
|
183
209
|
}
|
184
210
|
|
@@ -257,17 +283,6 @@ export default class LocusInfo extends EventsScope {
|
|
257
283
|
* @property {Object} person - Contains person data.
|
258
284
|
*/
|
259
285
|
|
260
|
-
/**
|
261
|
-
* Stored participant changes between the last event and the current event.
|
262
|
-
* All previously stored events are overwritten between events.
|
263
|
-
*
|
264
|
-
* @instance
|
265
|
-
* @type {Array<DeltaParticipant>}
|
266
|
-
* @private
|
267
|
-
* @member LocusInfo
|
268
|
-
*/
|
269
|
-
this.deltaParticipants = [];
|
270
|
-
|
271
286
|
this.updateLocusCache(locus);
|
272
287
|
// above section only updates the locusInfo object
|
273
288
|
// The below section makes sure it updates the locusInfo as well as updates the meeting object
|
@@ -373,7 +388,6 @@ export default class LocusInfo extends EventsScope {
|
|
373
388
|
return;
|
374
389
|
}
|
375
390
|
|
376
|
-
this.updateParticipantDeltas(locus.participants);
|
377
391
|
this.scheduledMeeting = locus.meeting || null;
|
378
392
|
this.participants = locus.participants;
|
379
393
|
const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
|
@@ -462,12 +476,12 @@ export default class LocusInfo extends EventsScope {
|
|
462
476
|
this.updateCreated(locus.created);
|
463
477
|
this.updateFullState(locus.fullState);
|
464
478
|
this.updateHostInfo(locus.host);
|
479
|
+
this.updateLocusUrl(locus.url);
|
465
480
|
this.updateMeetingInfo(locus.info, locus.self);
|
466
481
|
this.updateMediaShares(locus.mediaShares);
|
467
482
|
this.updateParticipantsUrl(locus.participantsUrl);
|
468
483
|
this.updateReplace(locus.replace);
|
469
484
|
this.updateSelf(locus.self);
|
470
|
-
this.updateLocusUrl(locus.url);
|
471
485
|
this.updateAclUrl(locus.aclUrl);
|
472
486
|
this.updateBasequence(locus.baseSequence);
|
473
487
|
this.updateSequence(locus.sequence);
|
@@ -728,55 +742,6 @@ export default class LocusInfo extends EventsScope {
|
|
728
742
|
}
|
729
743
|
}
|
730
744
|
|
731
|
-
/**
|
732
|
-
* Update the deltaParticipants property of this object based on a list of
|
733
|
-
* provided participants.
|
734
|
-
*
|
735
|
-
* @param {Array} [participants] - The participants to update against.
|
736
|
-
* @returns {void}
|
737
|
-
*/
|
738
|
-
updateParticipantDeltas(participants: Array<any> = []) {
|
739
|
-
// Used to find a participant within a participants collection.
|
740
|
-
const findParticipant = (participant, collection) =>
|
741
|
-
collection.find((item) => item.person.id === participant.person.id);
|
742
|
-
|
743
|
-
// Generates an object that indicates which state properties have changed.
|
744
|
-
const generateDelta = (prevState: any = {}, newState: any = {}) => {
|
745
|
-
// Setup deltas.
|
746
|
-
const deltas = {
|
747
|
-
audioStatus: prevState.audioStatus !== newState.audioStatus,
|
748
|
-
videoSlidesStatus: prevState.videoSlidesStatus !== newState.videoSlidesStatus,
|
749
|
-
videoStatus: prevState.videoStatus !== newState.videoStatus,
|
750
|
-
};
|
751
|
-
|
752
|
-
// Clean the object
|
753
|
-
Object.keys(deltas).forEach((key) => {
|
754
|
-
if (deltas[key] !== true) {
|
755
|
-
delete deltas[key];
|
756
|
-
}
|
757
|
-
});
|
758
|
-
|
759
|
-
return deltas;
|
760
|
-
};
|
761
|
-
|
762
|
-
this.deltaParticipants = participants.reduce((collection, participant) => {
|
763
|
-
const existingParticipant = findParticipant(participant, this.participants || []) || {};
|
764
|
-
|
765
|
-
const delta = generateDelta(existingParticipant.status, participant.status);
|
766
|
-
|
767
|
-
const changed = Object.keys(delta).length > 0;
|
768
|
-
|
769
|
-
if (changed) {
|
770
|
-
collection.push({
|
771
|
-
person: participant.person,
|
772
|
-
delta,
|
773
|
-
});
|
774
|
-
}
|
775
|
-
|
776
|
-
return collection;
|
777
|
-
}, []);
|
778
|
-
}
|
779
|
-
|
780
745
|
/**
|
781
746
|
* update meeting's members
|
782
747
|
* @param {Object} participants new participants object
|
@@ -1289,10 +1254,7 @@ export default class LocusInfo extends EventsScope {
|
|
1289
1254
|
*/
|
1290
1255
|
updateMeetingInfo(info: object, self?: object) {
|
1291
1256
|
const roles = self ? SelfUtils.getRoles(self) : this.parsedLocus.self?.roles || [];
|
1292
|
-
if (
|
1293
|
-
(info && !isEqual(this.info, info)) ||
|
1294
|
-
(roles.length && !isEqual(this.roles, roles) && info)
|
1295
|
-
) {
|
1257
|
+
if ((info && !isEqual(this.info, info)) || (!isEqual(this.roles, roles) && info)) {
|
1296
1258
|
const isJoined = SelfUtils.isJoined(self || this.parsedLocus.self);
|
1297
1259
|
const parsedInfo = InfoUtils.getInfos(this.parsedLocus.info, info, roles, isJoined);
|
1298
1260
|
|
package/src/meeting/brbState.ts
CHANGED
@@ -58,7 +58,13 @@ export class BrbState {
|
|
58
58
|
public enable(enabled: boolean, sendSlotManager: SendSlotManager) {
|
59
59
|
this.state.client.enabled = enabled;
|
60
60
|
|
61
|
-
|
61
|
+
// Don't set the source state override if enabling brb fails
|
62
|
+
return this.applyClientStateToServer(sendSlotManager).then(() => {
|
63
|
+
sendSlotManager.setSourceStateOverride(
|
64
|
+
MediaType.VideoMain,
|
65
|
+
this.state.client.enabled ? 'away' : null
|
66
|
+
);
|
67
|
+
});
|
62
68
|
}
|
63
69
|
|
64
70
|
/**
|
@@ -92,7 +98,7 @@ export class BrbState {
|
|
92
98
|
|
93
99
|
this.state.syncToServerInProgress = true;
|
94
100
|
|
95
|
-
return this.sendLocalBrbStateToServer(
|
101
|
+
return this.sendLocalBrbStateToServer()
|
96
102
|
.then(() => {
|
97
103
|
this.state.syncToServerInProgress = false;
|
98
104
|
|
@@ -120,10 +126,9 @@ export class BrbState {
|
|
120
126
|
/**
|
121
127
|
* Send the local brb state to the server
|
122
128
|
*
|
123
|
-
* @param {SendSlotManager} sendSlotManager
|
124
129
|
* @returns {Promise}
|
125
130
|
*/
|
126
|
-
private async sendLocalBrbStateToServer(
|
131
|
+
private async sendLocalBrbStateToServer() {
|
127
132
|
const {enabled} = this.state.client;
|
128
133
|
|
129
134
|
if (!this.meeting.isMultistream) {
|
@@ -153,9 +158,6 @@ export class BrbState {
|
|
153
158
|
deviceUrl: this.meeting.deviceUrl,
|
154
159
|
selfId: this.meeting.selfId,
|
155
160
|
})
|
156
|
-
.then(() => {
|
157
|
-
sendSlotManager.setSourceStateOverride(MediaType.VideoMain, enabled ? 'away' : null);
|
158
|
-
})
|
159
161
|
.catch((error) => {
|
160
162
|
LoggerProxy.logger.error('Meeting:brbState#sendLocalBrbStateToServer: Error ', error);
|
161
163
|
|
@@ -38,6 +38,10 @@ interface IInMeetingActions {
|
|
38
38
|
isClosedCaptionActive?: boolean;
|
39
39
|
canStartManualCaption?: boolean;
|
40
40
|
canStopManualCaption?: boolean;
|
41
|
+
isLocalRecordingStarted?: boolean;
|
42
|
+
isLocalRecordingStopped?: boolean;
|
43
|
+
isLocalRecordingPaused?: boolean;
|
44
|
+
|
41
45
|
isManualCaptionActive?: boolean;
|
42
46
|
isSaveTranscriptsEnabled?: boolean;
|
43
47
|
isWebexAssistantActive?: boolean;
|
@@ -173,6 +177,12 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
173
177
|
|
174
178
|
canStopManualCaption = null;
|
175
179
|
|
180
|
+
isLocalRecordingStopped = null;
|
181
|
+
|
182
|
+
isLocalRecordingStarted = null;
|
183
|
+
|
184
|
+
isLocalRecordingPaused = null;
|
185
|
+
|
176
186
|
isManualCaptionActive = null;
|
177
187
|
|
178
188
|
isSaveTranscriptsEnabled = null;
|
@@ -347,6 +357,9 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
347
357
|
canStopTranscribing: this.canStopTranscribing,
|
348
358
|
isClosedCaptionActive: this.isClosedCaptionActive,
|
349
359
|
canStartManualCaption: this.canStartManualCaption,
|
360
|
+
isLocalRecordingStarted: this.isLocalRecordingStarted,
|
361
|
+
isLocalRecordingStopped: this.isLocalRecordingStopped,
|
362
|
+
isLocalRecordingPaused: this.isLocalRecordingPaused,
|
350
363
|
canStopManualCaption: this.canStopManualCaption,
|
351
364
|
isManualCaptionActive: this.isManualCaptionActive,
|
352
365
|
isSaveTranscriptsEnabled: this.isSaveTranscriptsEnabled,
|