@webex/plugin-meetings 3.7.0-next.4 → 3.7.0-next.6
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 +10 -1
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/in-meeting-actions.js +11 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +18 -0
- package/dist/meeting/index.js.map +1 -1
- package/dist/members/util.js +4 -2
- package/dist/members/util.js.map +1 -1
- package/dist/recording-controller/enums.js +8 -4
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.js +18 -9
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +13 -9
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/types/constants.d.ts +8 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +10 -0
- package/dist/types/meeting/index.d.ts +1 -0
- package/dist/types/members/util.d.ts +2 -0
- package/dist/types/recording-controller/enums.d.ts +5 -2
- package/dist/types/recording-controller/index.d.ts +1 -0
- package/dist/types/recording-controller/util.d.ts +2 -1
- package/dist/webinar/index.js +39 -7
- package/dist/webinar/index.js.map +1 -1
- package/package.json +21 -21
- package/src/constants.ts +10 -0
- package/src/meeting/in-meeting-actions.ts +21 -0
- package/src/meeting/index.ts +22 -0
- package/src/members/util.ts +1 -0
- package/src/recording-controller/enums.ts +5 -2
- package/src/recording-controller/index.ts +17 -4
- package/src/recording-controller/util.ts +20 -5
- package/src/webinar/index.ts +40 -8
- package/test/unit/spec/meeting/in-meeting-actions.ts +13 -1
- package/test/unit/spec/meeting/index.js +3 -0
- package/test/unit/spec/members/utils.js +95 -0
- package/test/unit/spec/recording-controller/index.js +61 -5
- package/test/unit/spec/recording-controller/util.js +39 -3
- package/test/unit/spec/webinar/index.ts +47 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_webexCore","require","_lodash","_constants","_collection","_interopRequireDefault","Webinar","WebexPlugin","extend","namespace","MEETINGS","collections","webinar","WebinarCollection","props","locusUrl","webcastInstanceUrl","canManageWebcast","selfIsPanelist","selfIsAttendee","locusUrlUpdate","set","updateWebcastUrl","payload","get","updateCanManageWebcast","updateRoleChanged","isPromoted","includes","SELF_ROLES","ATTENDEE","PANELIST","isDemoted","MODERATOR","version","_default","exports","default"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\nimport {WebexPlugin} from '@webex/webex-core';\nimport {get} from 'lodash';\nimport {MEETINGS, SELF_ROLES} from '../constants';\n\nimport WebinarCollection from './collection';\n\n/**\n * @class Webinar\n */\nconst Webinar = WebexPlugin.extend({\n namespace: MEETINGS,\n collections: {\n webinar: WebinarCollection,\n },\n\n props: {\n locusUrl: 'string', // appears current webinar's locus url\n webcastInstanceUrl: 'string', // current webinar's webcast instance url\n canManageWebcast: 'boolean', // appears the ability to manage webcast\n selfIsPanelist: 'boolean', // self is panelist\n selfIsAttendee: 'boolean', // self is attendee\n },\n\n /**\n * Update the current locus url of the webinar\n * @param {string} locusUrl\n * @returns {void}\n */\n locusUrlUpdate(locusUrl) {\n this.set('locusUrl', locusUrl);\n },\n\n /**\n * Update the current webcast instance url of the meeting\n * @param {object} payload\n * @returns {void}\n */\n updateWebcastUrl(payload) {\n this.set('webcastInstanceUrl', get(payload, 'resources.webcastInstance.url'));\n },\n\n /**\n * Update whether self has capability to manage start/stop webcast (only host can manage it)\n * @param {boolean} canManageWebcast\n * @returns {void}\n */\n updateCanManageWebcast(canManageWebcast) {\n this.set('canManageWebcast', canManageWebcast);\n },\n\n /**\n * Updates user roles and manages associated state transitions\n * @param {object} payload\n * @param {string[]} payload.oldRoles - Previous roles of the user\n * @param {string[]} payload.newRoles - New roles of the user\n * @returns {{isPromoted: boolean, isDemoted: boolean}} Role transition states\n */\n updateRoleChanged(payload) {\n const
|
|
1
|
+
{"version":3,"names":["_webexCore","require","_lodash","_constants","_collection","_interopRequireDefault","_loggerProxy","Webinar","WebexPlugin","extend","namespace","MEETINGS","collections","webinar","WebinarCollection","props","locusUrl","webcastInstanceUrl","canManageWebcast","selfIsPanelist","selfIsAttendee","practiceSessionEnabled","locusUrlUpdate","set","updateWebcastUrl","payload","get","updateCanManageWebcast","updateRoleChanged","oldRoles","newRoles","isPromoted","includes","SELF_ROLES","ATTENDEE","PANELIST","isDemoted","MODERATOR","setPracticeSessionState","enabled","request","method","HTTP_VERBS","PATCH","uri","concat","body","practiceSession","catch","error","LoggerProxy","logger","updatePracticeSessionStatus","version","_default","exports","default"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\nimport {WebexPlugin} from '@webex/webex-core';\nimport {get} from 'lodash';\nimport {HTTP_VERBS, MEETINGS, SELF_ROLES} from '../constants';\n\nimport WebinarCollection from './collection';\nimport LoggerProxy from '../common/logs/logger-proxy';\n\n/**\n * @class Webinar\n */\nconst Webinar = WebexPlugin.extend({\n namespace: MEETINGS,\n collections: {\n webinar: WebinarCollection,\n },\n\n props: {\n locusUrl: 'string', // appears current webinar's locus url\n webcastInstanceUrl: 'string', // current webinar's webcast instance url\n canManageWebcast: 'boolean', // appears the ability to manage webcast\n selfIsPanelist: 'boolean', // self is panelist\n selfIsAttendee: 'boolean', // self is attendee\n practiceSessionEnabled: 'boolean', // practice session enabled\n },\n\n /**\n * Update the current locus url of the webinar\n * @param {string} locusUrl\n * @returns {void}\n */\n locusUrlUpdate(locusUrl) {\n this.set('locusUrl', locusUrl);\n },\n\n /**\n * Update the current webcast instance url of the meeting\n * @param {object} payload\n * @returns {void}\n */\n updateWebcastUrl(payload) {\n this.set('webcastInstanceUrl', get(payload, 'resources.webcastInstance.url'));\n },\n\n /**\n * Update whether self has capability to manage start/stop webcast (only host can manage it)\n * @param {boolean} canManageWebcast\n * @returns {void}\n */\n updateCanManageWebcast(canManageWebcast) {\n this.set('canManageWebcast', canManageWebcast);\n },\n\n /**\n * Updates user roles and manages associated state transitions\n * @param {object} payload\n * @param {string[]} payload.oldRoles - Previous roles of the user\n * @param {string[]} payload.newRoles - New roles of the user\n * @returns {{isPromoted: boolean, isDemoted: boolean}} Role transition states\n */\n updateRoleChanged(payload) {\n const oldRoles = get(payload, 'oldRoles', []);\n const newRoles = get(payload, 'newRoles', []);\n\n const isPromoted =\n oldRoles.includes(SELF_ROLES.ATTENDEE) && newRoles.includes(SELF_ROLES.PANELIST);\n const isDemoted =\n oldRoles.includes(SELF_ROLES.PANELIST) && newRoles.includes(SELF_ROLES.ATTENDEE);\n this.set('selfIsPanelist', newRoles.includes(SELF_ROLES.PANELIST));\n this.set('selfIsAttendee', newRoles.includes(SELF_ROLES.ATTENDEE));\n this.updateCanManageWebcast(newRoles.includes(SELF_ROLES.MODERATOR));\n\n return {isPromoted, isDemoted};\n },\n\n /**\n * start or stop practice session for webinar\n * @param {boolean} enabled\n * @returns {Promise}\n */\n setPracticeSessionState(enabled) {\n return this.request({\n method: HTTP_VERBS.PATCH,\n uri: `${this.locusUrl}/controls`,\n body: {\n practiceSession: {\n enabled,\n },\n },\n }).catch((error) => {\n LoggerProxy.logger.error('Meeting:webinar#setPracticeSessionState failed', error);\n throw error;\n });\n },\n\n /**\n * update practice session status\n * @param {object} payload\n * @returns {void}\n */\n updatePracticeSessionStatus(payload) {\n this.set('practiceSessionEnabled', payload.enabled);\n },\n});\n\nexport default Webinar;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -43,13 +43,13 @@
|
|
|
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-meetings": "3.7.0-next.
|
|
47
|
-
"@webex/plugin-rooms": "3.7.0-next.
|
|
48
|
-
"@webex/test-helper-chai": "3.7.0-next.
|
|
49
|
-
"@webex/test-helper-mocha": "3.7.0-next.
|
|
50
|
-
"@webex/test-helper-mock-webex": "3.7.0-next.
|
|
51
|
-
"@webex/test-helper-retry": "3.7.0-next.
|
|
52
|
-
"@webex/test-helper-test-users": "3.7.0-next.
|
|
46
|
+
"@webex/plugin-meetings": "3.7.0-next.6",
|
|
47
|
+
"@webex/plugin-rooms": "3.7.0-next.2",
|
|
48
|
+
"@webex/test-helper-chai": "3.7.0-next.2",
|
|
49
|
+
"@webex/test-helper-mocha": "3.7.0-next.2",
|
|
50
|
+
"@webex/test-helper-mock-webex": "3.7.0-next.2",
|
|
51
|
+
"@webex/test-helper-retry": "3.7.0-next.2",
|
|
52
|
+
"@webex/test-helper-test-users": "3.7.0-next.2",
|
|
53
53
|
"chai": "^4.3.4",
|
|
54
54
|
"chai-as-promised": "^7.1.1",
|
|
55
55
|
"eslint": "^8.24.0",
|
|
@@ -61,21 +61,21 @@
|
|
|
61
61
|
"typescript": "^4.7.4"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@webex/common": "3.7.0-next.
|
|
64
|
+
"@webex/common": "3.7.0-next.2",
|
|
65
65
|
"@webex/internal-media-core": "2.12.2",
|
|
66
|
-
"@webex/internal-plugin-conversation": "3.7.0-next.
|
|
67
|
-
"@webex/internal-plugin-device": "3.7.0-next.
|
|
68
|
-
"@webex/internal-plugin-llm": "3.7.0-next.
|
|
69
|
-
"@webex/internal-plugin-mercury": "3.7.0-next.
|
|
70
|
-
"@webex/internal-plugin-metrics": "3.7.0-next.
|
|
71
|
-
"@webex/internal-plugin-support": "3.7.0-next.
|
|
72
|
-
"@webex/internal-plugin-user": "3.7.0-next.
|
|
73
|
-
"@webex/internal-plugin-voicea": "3.7.0-next.
|
|
74
|
-
"@webex/media-helpers": "3.7.0-next.
|
|
75
|
-
"@webex/plugin-people": "3.7.0-next.
|
|
76
|
-
"@webex/plugin-rooms": "3.7.0-next.
|
|
66
|
+
"@webex/internal-plugin-conversation": "3.7.0-next.2",
|
|
67
|
+
"@webex/internal-plugin-device": "3.7.0-next.2",
|
|
68
|
+
"@webex/internal-plugin-llm": "3.7.0-next.2",
|
|
69
|
+
"@webex/internal-plugin-mercury": "3.7.0-next.2",
|
|
70
|
+
"@webex/internal-plugin-metrics": "3.7.0-next.2",
|
|
71
|
+
"@webex/internal-plugin-support": "3.7.0-next.2",
|
|
72
|
+
"@webex/internal-plugin-user": "3.7.0-next.2",
|
|
73
|
+
"@webex/internal-plugin-voicea": "3.7.0-next.6",
|
|
74
|
+
"@webex/media-helpers": "3.7.0-next.2",
|
|
75
|
+
"@webex/plugin-people": "3.7.0-next.2",
|
|
76
|
+
"@webex/plugin-rooms": "3.7.0-next.2",
|
|
77
77
|
"@webex/web-capabilities": "^1.4.0",
|
|
78
|
-
"@webex/webex-core": "3.7.0-next.
|
|
78
|
+
"@webex/webex-core": "3.7.0-next.2",
|
|
79
79
|
"ampersand-collection": "^2.0.2",
|
|
80
80
|
"bowser": "^2.11.0",
|
|
81
81
|
"btoa": "^1.2.1",
|
|
@@ -91,5 +91,5 @@
|
|
|
91
91
|
"//": [
|
|
92
92
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
93
93
|
],
|
|
94
|
-
"version": "3.7.0-next.
|
|
94
|
+
"version": "3.7.0-next.6"
|
|
95
95
|
}
|
package/src/constants.ts
CHANGED
|
@@ -904,6 +904,10 @@ export const DISPLAY_HINTS = {
|
|
|
904
904
|
RECORDING_CONTROL_PAUSE: 'RECORDING_CONTROL_PAUSE',
|
|
905
905
|
RECORDING_CONTROL_STOP: 'RECORDING_CONTROL_STOP',
|
|
906
906
|
RECORDING_CONTROL_RESUME: 'RECORDING_CONTROL_RESUME',
|
|
907
|
+
PREMISE_RECORDING_CONTROL_START: 'PREMISE_RECORDING_CONTROL_START',
|
|
908
|
+
PREMISE_RECORDING_CONTROL_PAUSE: 'PREMISE_RECORDING_CONTROL_PAUSE',
|
|
909
|
+
PREMISE_RECORDING_CONTROL_STOP: 'PREMISE_RECORDING_CONTROL_STOP',
|
|
910
|
+
PREMISE_RECORDING_CONTROL_RESUME: 'PREMISE_RECORDING_CONTROL_RESUME',
|
|
907
911
|
LOCK_CONTROL_UNLOCK: 'LOCK_CONTROL_UNLOCK',
|
|
908
912
|
LOCK_CONTROL_LOCK: 'LOCK_CONTROL_LOCK',
|
|
909
913
|
LOCK_STATUS_LOCKED: 'LOCK_STATUS_LOCKED',
|
|
@@ -988,6 +992,12 @@ export const DISPLAY_HINTS = {
|
|
|
988
992
|
STAGE_VIEW_INACTIVE: 'STAGE_VIEW_INACTIVE',
|
|
989
993
|
ENABLE_STAGE_VIEW: 'ENABLE_STAGE_VIEW',
|
|
990
994
|
DISABLE_STAGE_VIEW: 'DISABLE_STAGE_VIEW',
|
|
995
|
+
|
|
996
|
+
// Practice Session
|
|
997
|
+
PRACTICE_SESSION_ON: 'PRACTICE_SESSION_ON',
|
|
998
|
+
PRACTICE_SESSION_OFF: 'PRACTICE_SESSION_OFF',
|
|
999
|
+
SHOW_PRACTICE_SESSION_START: 'SHOW_PRACTICE_SESSION_START',
|
|
1000
|
+
SHOW_PRACTICE_SESSION_STOP: 'SHOW_PRACTICE_SESSION_STOP',
|
|
991
1001
|
};
|
|
992
1002
|
|
|
993
1003
|
export const INTERSTITIAL_DISPLAY_HINTS = [DISPLAY_HINTS.VOIP_IS_ENABLED];
|
|
@@ -26,6 +26,7 @@ interface IInMeetingActions {
|
|
|
26
26
|
canStartRecording?: boolean;
|
|
27
27
|
canPauseRecording?: boolean;
|
|
28
28
|
canResumeRecording?: boolean;
|
|
29
|
+
isPremiseRecordingEnabled?: boolean;
|
|
29
30
|
canStopRecording?: boolean;
|
|
30
31
|
canRaiseHand?: boolean;
|
|
31
32
|
canLowerAllHands?: boolean;
|
|
@@ -93,6 +94,10 @@ interface IInMeetingActions {
|
|
|
93
94
|
canShowStageView?: boolean;
|
|
94
95
|
canEnableStageView?: boolean;
|
|
95
96
|
canDisableStageView?: boolean;
|
|
97
|
+
isPracticeSessionOn?: boolean;
|
|
98
|
+
isPracticeSessionOff?: boolean;
|
|
99
|
+
canStartPracticeSession?: boolean;
|
|
100
|
+
canStopPracticeSession?: boolean;
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
/**
|
|
@@ -117,6 +122,8 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
117
122
|
|
|
118
123
|
canResumeRecording = null;
|
|
119
124
|
|
|
125
|
+
isPremiseRecordingEnabled = null;
|
|
126
|
+
|
|
120
127
|
canStopRecording = null;
|
|
121
128
|
|
|
122
129
|
canSetMuteOnEntry = null;
|
|
@@ -266,6 +273,15 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
266
273
|
canEnableStageView = null;
|
|
267
274
|
|
|
268
275
|
canDisableStageView = null;
|
|
276
|
+
|
|
277
|
+
isPracticeSessionOn = null;
|
|
278
|
+
|
|
279
|
+
isPracticeSessionOff = null;
|
|
280
|
+
|
|
281
|
+
canStartPracticeSession = null;
|
|
282
|
+
|
|
283
|
+
canStopPracticeSession = null;
|
|
284
|
+
|
|
269
285
|
/**
|
|
270
286
|
* Returns all meeting action options
|
|
271
287
|
* @returns {Object}
|
|
@@ -288,6 +304,7 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
288
304
|
canPauseRecording: this.canPauseRecording,
|
|
289
305
|
canResumeRecording: this.canResumeRecording,
|
|
290
306
|
canStopRecording: this.canStopRecording,
|
|
307
|
+
isPremiseRecordingEnabled: this.isPremiseRecordingEnabled,
|
|
291
308
|
canRaiseHand: this.canRaiseHand,
|
|
292
309
|
canLowerAllHands: this.canLowerAllHands,
|
|
293
310
|
canLowerSomeoneElsesHand: this.canLowerSomeoneElsesHand,
|
|
@@ -354,6 +371,10 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
354
371
|
canShowStageView: this.canShowStageView,
|
|
355
372
|
canEnableStageView: this.canEnableStageView,
|
|
356
373
|
canDisableStageView: this.canDisableStageView,
|
|
374
|
+
isPracticeSessionOn: this.isPracticeSessionOn,
|
|
375
|
+
isPracticeSessionOff: this.isPracticeSessionOff,
|
|
376
|
+
canStartPracticeSession: this.canStartPracticeSession,
|
|
377
|
+
canStopPracticeSession: this.canStopPracticeSession,
|
|
357
378
|
});
|
|
358
379
|
|
|
359
380
|
/**
|
package/src/meeting/index.ts
CHANGED
|
@@ -2660,6 +2660,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2660
2660
|
});
|
|
2661
2661
|
|
|
2662
2662
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_PRACTICE_SESSION_STATUS_UPDATED, ({state}) => {
|
|
2663
|
+
this.webinar.updatePracticeSessionStatus(state);
|
|
2663
2664
|
Trigger.trigger(
|
|
2664
2665
|
this,
|
|
2665
2666
|
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
|
@@ -3516,6 +3517,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3516
3517
|
emailAddress: string;
|
|
3517
3518
|
email: string;
|
|
3518
3519
|
phoneNumber: string;
|
|
3520
|
+
roles: Array<string>;
|
|
3519
3521
|
},
|
|
3520
3522
|
alertIfActive = true
|
|
3521
3523
|
) {
|
|
@@ -3772,6 +3774,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3772
3774
|
this.userDisplayHints,
|
|
3773
3775
|
this.selfUserPolicies
|
|
3774
3776
|
),
|
|
3777
|
+
isPremiseRecordingEnabled: RecordingUtil.isPremiseRecordingEnabled(
|
|
3778
|
+
this.userDisplayHints,
|
|
3779
|
+
this.selfUserPolicies
|
|
3780
|
+
),
|
|
3775
3781
|
canRaiseHand: MeetingUtil.canUserRaiseHand(this.userDisplayHints),
|
|
3776
3782
|
canLowerAllHands: MeetingUtil.canUserLowerAllHands(this.userDisplayHints),
|
|
3777
3783
|
canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(this.userDisplayHints),
|
|
@@ -3915,6 +3921,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3915
3921
|
requiredHints: [DISPLAY_HINTS.DISABLE_STAGE_VIEW],
|
|
3916
3922
|
displayHints: this.userDisplayHints,
|
|
3917
3923
|
}),
|
|
3924
|
+
isPracticeSessionOn: ControlsOptionsUtil.hasHints({
|
|
3925
|
+
requiredHints: [DISPLAY_HINTS.PRACTICE_SESSION_ON],
|
|
3926
|
+
displayHints: this.userDisplayHints,
|
|
3927
|
+
}),
|
|
3928
|
+
isPracticeSessionOff: ControlsOptionsUtil.hasHints({
|
|
3929
|
+
requiredHints: [DISPLAY_HINTS.PRACTICE_SESSION_OFF],
|
|
3930
|
+
displayHints: this.userDisplayHints,
|
|
3931
|
+
}),
|
|
3932
|
+
canStartPracticeSession: ControlsOptionsUtil.hasHints({
|
|
3933
|
+
requiredHints: [DISPLAY_HINTS.SHOW_PRACTICE_SESSION_START],
|
|
3934
|
+
displayHints: this.userDisplayHints,
|
|
3935
|
+
}),
|
|
3936
|
+
canStopPracticeSession: ControlsOptionsUtil.hasHints({
|
|
3937
|
+
requiredHints: [DISPLAY_HINTS.SHOW_PRACTICE_SESSION_STOP],
|
|
3938
|
+
displayHints: this.userDisplayHints,
|
|
3939
|
+
}),
|
|
3918
3940
|
canShareFile:
|
|
3919
3941
|
(ControlsOptionsUtil.hasHints({
|
|
3920
3942
|
requiredHints: [DISPLAY_HINTS.SHARE_FILE],
|
package/src/members/util.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import PermissionError from '../common/errors/permission';
|
|
2
|
+
import LoggerProxy from '../common/logs/logger-proxy';
|
|
2
3
|
import {CONTROLS, HTTP_VERBS, SELF_POLICY} from '../constants';
|
|
3
4
|
import MeetingRequest from '../meeting/request';
|
|
4
|
-
import RecordingAction from './enums';
|
|
5
|
+
import {RecordingAction, RecordingType} from './enums';
|
|
5
6
|
import Util from './util';
|
|
6
|
-
import LoggerProxy from '../common/logs/logger-proxy';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @description Recording manages the recording functionality of the meeting object, there should only be one instantation of recording per meeting
|
|
@@ -228,11 +228,12 @@ export default class RecordingController {
|
|
|
228
228
|
|
|
229
229
|
/**
|
|
230
230
|
* @param {RecordingAction} action
|
|
231
|
+
* @param {RecordingType} recordingType
|
|
231
232
|
* @private
|
|
232
233
|
* @memberof RecordingController
|
|
233
234
|
* @returns {Promise}
|
|
234
235
|
*/
|
|
235
|
-
private recordingService(action: RecordingAction): Promise<any> {
|
|
236
|
+
private recordingService(action: RecordingAction, recordingType: RecordingType): Promise<any> {
|
|
236
237
|
// @ts-ignore
|
|
237
238
|
return this.request.request({
|
|
238
239
|
body: {
|
|
@@ -242,6 +243,7 @@ export default class RecordingController {
|
|
|
242
243
|
recording: {
|
|
243
244
|
action: action.toLowerCase(),
|
|
244
245
|
},
|
|
246
|
+
recordingType,
|
|
245
247
|
},
|
|
246
248
|
uri: `${this.serviceUrl}/loci/${this.locusId}/recording`,
|
|
247
249
|
method: HTTP_VERBS.PUT,
|
|
@@ -276,14 +278,25 @@ export default class RecordingController {
|
|
|
276
278
|
* @returns {Promise}
|
|
277
279
|
*/
|
|
278
280
|
private recordingFacade(action: RecordingAction): Promise<any> {
|
|
281
|
+
const isPremiseRecordingEnabled = Util.isPremiseRecordingEnabled(
|
|
282
|
+
this.displayHints,
|
|
283
|
+
this.selfUserPolicies
|
|
284
|
+
);
|
|
279
285
|
LoggerProxy.logger.log(
|
|
280
286
|
`RecordingController:index#recordingFacade --> recording action [${action}]`
|
|
281
287
|
);
|
|
282
288
|
|
|
289
|
+
let recordingType: RecordingType;
|
|
290
|
+
if (isPremiseRecordingEnabled) {
|
|
291
|
+
recordingType = RecordingType.Premise;
|
|
292
|
+
} else {
|
|
293
|
+
recordingType = RecordingType.Cloud;
|
|
294
|
+
}
|
|
295
|
+
|
|
283
296
|
// assumes action is proper cased (i.e., Example)
|
|
284
297
|
if (Util?.[`canUser${action}`](this.displayHints, this.selfUserPolicies)) {
|
|
285
298
|
if (this.serviceUrl) {
|
|
286
|
-
return this.recordingService(action);
|
|
299
|
+
return this.recordingService(action, recordingType);
|
|
287
300
|
}
|
|
288
301
|
|
|
289
302
|
return this.recordingControls(action);
|
|
@@ -1,33 +1,47 @@
|
|
|
1
1
|
import {DISPLAY_HINTS, SELF_POLICY} from '../constants';
|
|
2
|
-
import RecordingAction from './enums';
|
|
2
|
+
import {RecordingAction} from './enums';
|
|
3
3
|
import MeetingUtil from '../meeting/util';
|
|
4
4
|
|
|
5
5
|
const canUserStart = (
|
|
6
6
|
displayHints: Array<string>,
|
|
7
7
|
userPolicies: Record<SELF_POLICY, boolean>
|
|
8
8
|
): boolean =>
|
|
9
|
-
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START)
|
|
9
|
+
(displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START) ||
|
|
10
|
+
displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_START)) &&
|
|
10
11
|
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
11
12
|
|
|
12
13
|
const canUserPause = (
|
|
13
14
|
displayHints: Array<string>,
|
|
14
15
|
userPolicies: Record<SELF_POLICY, boolean>
|
|
15
16
|
): boolean =>
|
|
16
|
-
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE)
|
|
17
|
+
(displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE) ||
|
|
18
|
+
displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_PAUSE)) &&
|
|
17
19
|
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
18
20
|
|
|
19
21
|
const canUserResume = (
|
|
20
22
|
displayHints: Array<string>,
|
|
21
23
|
userPolicies: Record<SELF_POLICY, boolean>
|
|
22
24
|
): boolean =>
|
|
23
|
-
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME)
|
|
25
|
+
(displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME) ||
|
|
26
|
+
displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_RESUME)) &&
|
|
24
27
|
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
25
28
|
|
|
26
29
|
const canUserStop = (
|
|
27
30
|
displayHints: Array<string>,
|
|
28
31
|
userPolicies: Record<SELF_POLICY, boolean>
|
|
29
32
|
): boolean =>
|
|
30
|
-
displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP)
|
|
33
|
+
(displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP) ||
|
|
34
|
+
displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_STOP)) &&
|
|
35
|
+
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
36
|
+
|
|
37
|
+
const isPremiseRecordingEnabled = (
|
|
38
|
+
displayHints: Array<string>,
|
|
39
|
+
userPolicies: Record<SELF_POLICY, boolean>
|
|
40
|
+
): boolean =>
|
|
41
|
+
(displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_START) ||
|
|
42
|
+
displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_PAUSE) ||
|
|
43
|
+
displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_STOP) ||
|
|
44
|
+
displayHints.includes(DISPLAY_HINTS.PREMISE_RECORDING_CONTROL_RESUME)) &&
|
|
31
45
|
MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
|
|
32
46
|
|
|
33
47
|
const extractLocusId = (url: string) => {
|
|
@@ -70,6 +84,7 @@ export default {
|
|
|
70
84
|
canUserPause,
|
|
71
85
|
canUserResume,
|
|
72
86
|
canUserStop,
|
|
87
|
+
isPremiseRecordingEnabled,
|
|
73
88
|
deriveRecordingStates,
|
|
74
89
|
extractLocusId,
|
|
75
90
|
};
|
package/src/webinar/index.ts
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import {WebexPlugin} from '@webex/webex-core';
|
|
5
5
|
import {get} from 'lodash';
|
|
6
|
-
import {MEETINGS, SELF_ROLES} from '../constants';
|
|
6
|
+
import {HTTP_VERBS, MEETINGS, SELF_ROLES} from '../constants';
|
|
7
7
|
|
|
8
8
|
import WebinarCollection from './collection';
|
|
9
|
+
import LoggerProxy from '../common/logs/logger-proxy';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @class Webinar
|
|
@@ -22,6 +23,7 @@ const Webinar = WebexPlugin.extend({
|
|
|
22
23
|
canManageWebcast: 'boolean', // appears the ability to manage webcast
|
|
23
24
|
selfIsPanelist: 'boolean', // self is panelist
|
|
24
25
|
selfIsAttendee: 'boolean', // self is attendee
|
|
26
|
+
practiceSessionEnabled: 'boolean', // practice session enabled
|
|
25
27
|
},
|
|
26
28
|
|
|
27
29
|
/**
|
|
@@ -59,18 +61,48 @@ const Webinar = WebexPlugin.extend({
|
|
|
59
61
|
* @returns {{isPromoted: boolean, isDemoted: boolean}} Role transition states
|
|
60
62
|
*/
|
|
61
63
|
updateRoleChanged(payload) {
|
|
64
|
+
const oldRoles = get(payload, 'oldRoles', []);
|
|
65
|
+
const newRoles = get(payload, 'newRoles', []);
|
|
66
|
+
|
|
62
67
|
const isPromoted =
|
|
63
|
-
|
|
64
|
-
get(payload, 'newRoles', []).includes(SELF_ROLES.PANELIST);
|
|
68
|
+
oldRoles.includes(SELF_ROLES.ATTENDEE) && newRoles.includes(SELF_ROLES.PANELIST);
|
|
65
69
|
const isDemoted =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this.set('
|
|
69
|
-
this.
|
|
70
|
-
this.updateCanManageWebcast(get(payload, 'newRoles', []).includes(SELF_ROLES.MODERATOR));
|
|
70
|
+
oldRoles.includes(SELF_ROLES.PANELIST) && newRoles.includes(SELF_ROLES.ATTENDEE);
|
|
71
|
+
this.set('selfIsPanelist', newRoles.includes(SELF_ROLES.PANELIST));
|
|
72
|
+
this.set('selfIsAttendee', newRoles.includes(SELF_ROLES.ATTENDEE));
|
|
73
|
+
this.updateCanManageWebcast(newRoles.includes(SELF_ROLES.MODERATOR));
|
|
71
74
|
|
|
72
75
|
return {isPromoted, isDemoted};
|
|
73
76
|
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* start or stop practice session for webinar
|
|
80
|
+
* @param {boolean} enabled
|
|
81
|
+
* @returns {Promise}
|
|
82
|
+
*/
|
|
83
|
+
setPracticeSessionState(enabled) {
|
|
84
|
+
return this.request({
|
|
85
|
+
method: HTTP_VERBS.PATCH,
|
|
86
|
+
uri: `${this.locusUrl}/controls`,
|
|
87
|
+
body: {
|
|
88
|
+
practiceSession: {
|
|
89
|
+
enabled,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
}).catch((error) => {
|
|
93
|
+
LoggerProxy.logger.error('Meeting:webinar#setPracticeSessionState failed', error);
|
|
94
|
+
throw error;
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* update practice session status
|
|
100
|
+
* @param {object} payload
|
|
101
|
+
* @returns {void}
|
|
102
|
+
*/
|
|
103
|
+
updatePracticeSessionStatus(payload) {
|
|
104
|
+
this.set('practiceSessionEnabled', payload.enabled);
|
|
105
|
+
},
|
|
74
106
|
});
|
|
75
107
|
|
|
76
108
|
export default Webinar;
|
|
@@ -33,6 +33,7 @@ describe('plugin-meetings', () => {
|
|
|
33
33
|
canStartManualCaption: null,
|
|
34
34
|
canStopManualCaption: null,
|
|
35
35
|
isManualCaptionActive: null,
|
|
36
|
+
isPremiseRecordingEnabled: null,
|
|
36
37
|
isSaveTranscriptsEnabled: null,
|
|
37
38
|
isWebexAssistantActive: null,
|
|
38
39
|
canViewCaptionPanel: null,
|
|
@@ -88,6 +89,11 @@ describe('plugin-meetings', () => {
|
|
|
88
89
|
canShowStageView: null,
|
|
89
90
|
canEnableStageView: null,
|
|
90
91
|
canDisableStageView: null,
|
|
92
|
+
isPracticeSessionOn : null,
|
|
93
|
+
isPracticeSessionOff : null,
|
|
94
|
+
canStartPracticeSession: null,
|
|
95
|
+
canStopPracticeSession: null,
|
|
96
|
+
|
|
91
97
|
...expected,
|
|
92
98
|
};
|
|
93
99
|
|
|
@@ -126,6 +132,7 @@ describe('plugin-meetings', () => {
|
|
|
126
132
|
'canStartManualCaption',
|
|
127
133
|
'canStopManualCaption',
|
|
128
134
|
'isManualCaptionActive',
|
|
135
|
+
'isPremiseRecordingEnabled',
|
|
129
136
|
'isSaveTranscriptsEnabled',
|
|
130
137
|
'isWebexAssistantActive',
|
|
131
138
|
'canViewCaptionPanel',
|
|
@@ -181,7 +188,12 @@ describe('plugin-meetings', () => {
|
|
|
181
188
|
'canShowStageView',
|
|
182
189
|
'canEnableStageView',
|
|
183
190
|
'canDisableStageView',
|
|
184
|
-
|
|
191
|
+
'isPracticeSessionOn',
|
|
192
|
+
'isPracticeSessionOff',
|
|
193
|
+
'canStartPracticeSession',
|
|
194
|
+
'canStopPracticeSession',
|
|
195
|
+
|
|
196
|
+
].forEach((key) => {
|
|
185
197
|
it(`get and set for ${key} work as expected`, () => {
|
|
186
198
|
const inMeetingActions = new InMeetingActions();
|
|
187
199
|
|
|
@@ -9044,6 +9044,8 @@ describe('plugin-meetings', () => {
|
|
|
9044
9044
|
});
|
|
9045
9045
|
|
|
9046
9046
|
it('listens to MEETING_CONTROLS_PRACTICE_SESSION_STATUS_UPDATED', async () => {
|
|
9047
|
+
meeting.webinar.updatePracticeSessionStatus = sinon.stub();
|
|
9048
|
+
|
|
9047
9049
|
const state = {example: 'value'};
|
|
9048
9050
|
|
|
9049
9051
|
await meeting.locusInfo.emitScoped(
|
|
@@ -9052,6 +9054,7 @@ describe('plugin-meetings', () => {
|
|
|
9052
9054
|
{state}
|
|
9053
9055
|
);
|
|
9054
9056
|
|
|
9057
|
+
assert.calledOnceWithExactly( meeting.webinar.updatePracticeSessionStatus, state);
|
|
9055
9058
|
assert.calledWith(
|
|
9056
9059
|
TriggerProxy.trigger,
|
|
9057
9060
|
meeting,
|
|
@@ -262,5 +262,100 @@ describe('plugin-meetings', () => {
|
|
|
262
262
|
testParams(false);
|
|
263
263
|
});
|
|
264
264
|
});
|
|
265
|
+
|
|
266
|
+
describe('#getAddMemberBody', () => {
|
|
267
|
+
it('returns the correct body with email address and roles', () => {
|
|
268
|
+
const options = {
|
|
269
|
+
invitee: {
|
|
270
|
+
emailAddress: 'test@example.com',
|
|
271
|
+
roles: ['role1', 'role2'],
|
|
272
|
+
},
|
|
273
|
+
alertIfActive: true,
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
assert.deepEqual(MembersUtil.getAddMemberBody(options), {
|
|
277
|
+
invitees: [
|
|
278
|
+
{
|
|
279
|
+
address: 'test@example.com',
|
|
280
|
+
roles: ['role1', 'role2'],
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
alertIfActive: true,
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it('returns the correct body with phone number and no roles', () => {
|
|
288
|
+
const options = {
|
|
289
|
+
invitee: {
|
|
290
|
+
phoneNumber: '1234567890',
|
|
291
|
+
},
|
|
292
|
+
alertIfActive: false,
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
assert.deepEqual(MembersUtil.getAddMemberBody(options), {
|
|
296
|
+
invitees: [
|
|
297
|
+
{
|
|
298
|
+
address: '1234567890',
|
|
299
|
+
},
|
|
300
|
+
],
|
|
301
|
+
alertIfActive: false,
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('returns the correct body with fallback to email', () => {
|
|
306
|
+
const options = {
|
|
307
|
+
invitee: {
|
|
308
|
+
email: 'fallback@example.com',
|
|
309
|
+
},
|
|
310
|
+
alertIfActive: true,
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
assert.deepEqual(MembersUtil.getAddMemberBody(options), {
|
|
314
|
+
invitees: [
|
|
315
|
+
{
|
|
316
|
+
address: 'fallback@example.com',
|
|
317
|
+
},
|
|
318
|
+
],
|
|
319
|
+
alertIfActive: true,
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it('handles missing `alertIfActive` gracefully', () => {
|
|
324
|
+
const options = {
|
|
325
|
+
invitee: {
|
|
326
|
+
emailAddress: 'test@example.com',
|
|
327
|
+
roles: ['role1'],
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
assert.deepEqual(MembersUtil.getAddMemberBody(options), {
|
|
332
|
+
invitees: [
|
|
333
|
+
{
|
|
334
|
+
address: 'test@example.com',
|
|
335
|
+
roles: ['role1'],
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
alertIfActive: undefined,
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('ignores roles if not provided', () => {
|
|
343
|
+
const options = {
|
|
344
|
+
invitee: {
|
|
345
|
+
emailAddress: 'test@example.com',
|
|
346
|
+
},
|
|
347
|
+
alertIfActive: false,
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
assert.deepEqual(MembersUtil.getAddMemberBody(options), {
|
|
351
|
+
invitees: [
|
|
352
|
+
{
|
|
353
|
+
address: 'test@example.com',
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
alertIfActive: false,
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
});
|
|
265
360
|
});
|
|
266
361
|
});
|