@webex/plugin-meetings 3.0.0-beta.25 → 3.0.0-beta.27
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 +92 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/constants.js +5 -1
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js +14 -0
- package/dist/controls-options-manager/constants.js.map +1 -0
- package/dist/controls-options-manager/enums.js +15 -0
- package/dist/controls-options-manager/enums.js.map +1 -0
- package/dist/controls-options-manager/index.js +203 -0
- package/dist/controls-options-manager/index.js.map +1 -0
- package/dist/controls-options-manager/util.js +28 -0
- package/dist/controls-options-manager/util.js.map +1 -0
- package/dist/meeting/in-meeting-actions.js +8 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +61 -13
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/util.js +17 -0
- package/dist/meetings/util.js.map +1 -1
- package/dist/types/constants.d.ts +4 -0
- package/dist/types/controls-options-manager/constants.d.ts +4 -0
- package/dist/types/controls-options-manager/enums.d.ts +5 -0
- package/dist/types/controls-options-manager/index.d.ts +120 -0
- package/dist/types/controls-options-manager/util.d.ts +7 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +8 -0
- package/dist/types/meeting/index.d.ts +18 -0
- package/package.json +18 -18
- package/src/breakouts/index.ts +73 -1
- package/src/constants.ts +4 -0
- package/src/controls-options-manager/constants.ts +5 -0
- package/src/controls-options-manager/enums.ts +6 -0
- package/src/controls-options-manager/index.ts +183 -0
- package/src/controls-options-manager/util.ts +20 -0
- package/src/meeting/in-meeting-actions.ts +16 -0
- package/src/meeting/index.ts +50 -0
- package/src/meetings/util.ts +24 -0
- package/test/integration/spec/converged-space-meetings.js +176 -0
- package/test/unit/spec/breakouts/index.ts +76 -0
- package/test/unit/spec/controls-options-manager/index.js +124 -0
- package/test/unit/spec/controls-options-manager/util.js +66 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +8 -0
- package/test/unit/spec/meeting/index.js +15 -0
- package/test/utils/constants.js +9 -0
- package/test/utils/testUtils.js +13 -6
- package/test/utils/webex-config.js +4 -0
- package/test/utils/webex-test-users.js +6 -3
package/dist/meetings/util.js
CHANGED
|
@@ -62,11 +62,28 @@ MeetingsUtil.handleRoapMercury = function (envelope, meetingCollection) {
|
|
|
62
62
|
errorType: errorType,
|
|
63
63
|
errorCause: errorCause
|
|
64
64
|
};
|
|
65
|
+
var mediaServer = MeetingsUtil.getMediaServer(roapMessage.sdp);
|
|
65
66
|
meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived(roapMessage);
|
|
67
|
+
if (mediaServer) {
|
|
68
|
+
meeting.mediaProperties.webrtcMediaConnection.mediaServer = mediaServer;
|
|
69
|
+
}
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
};
|
|
74
|
+
MeetingsUtil.getMediaServer = function (sdp) {
|
|
75
|
+
var mediaServer;
|
|
76
|
+
|
|
77
|
+
// Attempt to collect the media server from the roap message.
|
|
78
|
+
try {
|
|
79
|
+
mediaServer = sdp.split('\r\n').find(function (line) {
|
|
80
|
+
return line.startsWith('o=');
|
|
81
|
+
}).split(' ').shift().replace('o=', '');
|
|
82
|
+
} catch (_unused) {
|
|
83
|
+
mediaServer = undefined;
|
|
84
|
+
}
|
|
85
|
+
return mediaServer;
|
|
86
|
+
};
|
|
70
87
|
MeetingsUtil.checkForCorrelationId = function (deviceUrl, locus) {
|
|
71
88
|
var devices = [];
|
|
72
89
|
if (locus) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["MeetingsUtil","getMeetingAddedType","type","_LOCUS_ID_","_INCOMING_","_CREATED_","handleRoapMercury","envelope","meetingCollection","data","eventType","LOCUSEVENT","MESSAGE_ROAP","meeting","getByKey","CORRELATION_ID","correlationId","message","seq","messageType","tieBreaker","errorType","errorCause","ROAP","ROAP_TYPES","TURN_DISCOVERY_RESPONSE","roap","turnDiscovery","handleTurnDiscoveryResponse","roapMessage","sdp","sdps","length","undefined","mediaProperties","webrtcMediaConnection","roapMessageReceived","checkForCorrelationId","deviceUrl","locus","devices","self","foundDevice","find","device","url","parseDefaultSiteFromMeetingPreferences","userPreferences","result","sites","defaultSite","site","default","siteUrl","hasH264Codec","hasCodec","pc","window","RTCPeerConnection","createOffer","offerToReceiveVideo","offer","match","close","LoggerProxy","logger","warn","checkH264Support","options","firstChecked","disableNotifications","delay","maxDuration","shouldTrigger","shouldStopChecking","Trigger","trigger","file","function","EVENT_TRIGGERS","MEDIA_CODEC_LOADED","log","error","MEDIA_CODEC_MISSING","setTimeout","timestamp","call"],"sources":["util.ts"],"sourcesContent":["/* globals window */\n\nimport {\n _LOCUS_ID_,\n _INCOMING_,\n _CREATED_,\n LOCUSEVENT,\n CORRELATION_ID,\n EVENT_TRIGGERS,\n ROAP,\n} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport Trigger from '../common/events/trigger-proxy';\n\n/**\n * Meetings Media Codec Missing Event\n * Emitted when H.264 codec is not\n * found in the browser.\n * @event media:codec:missing\n * @instance\n * @memberof MeetingsUtil\n */\n\n/**\n * Meetings Media Codec Loaded Event\n * Emitted when H.264 codec has been\n * loaded in the browser.\n * @event media:codec:loaded\n * @instance\n * @memberof MeetingsUtil\n */\n\nconst MeetingsUtil: any = {};\n\nMeetingsUtil.getMeetingAddedType = (type) => (type === _LOCUS_ID_ ? _INCOMING_ : _CREATED_);\n\nMeetingsUtil.handleRoapMercury = (envelope, meetingCollection) => {\n const {data} = envelope;\n const {eventType} = data;\n\n if (eventType === LOCUSEVENT.MESSAGE_ROAP) {\n const meeting = meetingCollection.getByKey(CORRELATION_ID, data.correlationId);\n\n if (meeting) {\n const {seq, messageType, tieBreaker, errorType, errorCause} = data.message;\n\n if (messageType === ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {\n // turn discovery is not part of normal roap protocol and so we are not handling it\n // through the usual roap state machine\n meeting.roap.turnDiscovery.handleTurnDiscoveryResponse(data.message);\n } else {\n const roapMessage = {\n seq,\n messageType,\n sdp: data.message.sdps?.length > 0 ? data.message.sdps[0] : undefined,\n tieBreaker,\n errorType,\n errorCause,\n };\n\n meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived(roapMessage);\n }\n }\n }\n};\n\nMeetingsUtil.checkForCorrelationId = (deviceUrl, locus) => {\n let devices = [];\n\n if (locus) {\n if (locus && locus.self && locus.self.devices) {\n devices = locus.self.devices;\n }\n\n const foundDevice = devices.find((device) => device.url === deviceUrl);\n\n if (foundDevice && foundDevice.correlationId) {\n return foundDevice.correlationId;\n }\n }\n\n return false;\n};\n\nMeetingsUtil.parseDefaultSiteFromMeetingPreferences = (userPreferences) => {\n let result = '';\n\n if (userPreferences && userPreferences.sites) {\n const defaultSite = userPreferences.sites.find((site) => site.default);\n\n if (defaultSite) {\n result = defaultSite.siteUrl;\n }\n }\n\n return result;\n};\n\n/**\n * Will check to see if the H.264 media codec is supported.\n * @async\n * @private\n * @returns {Promise<boolean>}\n */\nMeetingsUtil.hasH264Codec = async () => {\n let hasCodec = false;\n\n try {\n const pc = new window.RTCPeerConnection();\n const offer = await pc.createOffer({offerToReceiveVideo: true});\n\n if (offer.sdp.match(/^a=rtpmap:\\d+\\s+H264\\/\\d+/m)) {\n hasCodec = true;\n }\n pc.close();\n } catch (error) {\n LoggerProxy.logger.warn(\n 'Meetings:util#hasH264Codec --> Error creating peerConnection for H.264 test.'\n );\n }\n\n return hasCodec;\n};\n\n/**\n * Notifies the user whether or not the H.264\n * codec is present. Will continuously check\n * until max duration.\n * @async\n * @private\n * @param {object} options\n * @param {Number} options.firstChecked Timestamp in milliseconds\n * @param {boolean} options.disableNotifications Default is false. Boolean to enable/disable notification and events\n * @returns {undefined}\n */\nMeetingsUtil.checkH264Support = async function checkH264Support(options: {\n firstChecked: number;\n disableNotifications: boolean;\n}) {\n const {hasH264Codec} = MeetingsUtil;\n const {firstChecked, disableNotifications} = options || {};\n const delay = 5e3; // ms\n const maxDuration = 3e5; // ms\n const shouldTrigger = firstChecked === undefined;\n const shouldStopChecking = firstChecked && Date.now() - firstChecked >= maxDuration;\n\n // Disable notifications and start H.264 download only\n if (disableNotifications) {\n hasH264Codec();\n\n return;\n }\n\n // Codec loaded trigger event notification\n if (await hasH264Codec()) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_LOADED\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec loaded successfully.');\n\n return;\n }\n\n // Stop checking if past the timelimit\n if (shouldStopChecking) {\n LoggerProxy.logger.error(\n 'Meetings:util#checkH264Support --> Timed out waiting for H264 codec to load.'\n );\n\n return;\n }\n\n // Trigger only once\n if (shouldTrigger) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_MISSING\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec is missing.');\n }\n\n // Keep checking in intervals to see if codec loaded\n window.setTimeout(() => {\n const timestamp = firstChecked || Date.now();\n\n MeetingsUtil.checkH264Support.call(this, {firstChecked: timestamp});\n }, delay);\n};\n\nexport default MeetingsUtil;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["MeetingsUtil","getMeetingAddedType","type","_LOCUS_ID_","_INCOMING_","_CREATED_","handleRoapMercury","envelope","meetingCollection","data","eventType","LOCUSEVENT","MESSAGE_ROAP","meeting","getByKey","CORRELATION_ID","correlationId","message","seq","messageType","tieBreaker","errorType","errorCause","ROAP","ROAP_TYPES","TURN_DISCOVERY_RESPONSE","roap","turnDiscovery","handleTurnDiscoveryResponse","roapMessage","sdp","sdps","length","undefined","mediaServer","getMediaServer","mediaProperties","webrtcMediaConnection","roapMessageReceived","split","find","line","startsWith","shift","replace","checkForCorrelationId","deviceUrl","locus","devices","self","foundDevice","device","url","parseDefaultSiteFromMeetingPreferences","userPreferences","result","sites","defaultSite","site","default","siteUrl","hasH264Codec","hasCodec","pc","window","RTCPeerConnection","createOffer","offerToReceiveVideo","offer","match","close","LoggerProxy","logger","warn","checkH264Support","options","firstChecked","disableNotifications","delay","maxDuration","shouldTrigger","shouldStopChecking","Trigger","trigger","file","function","EVENT_TRIGGERS","MEDIA_CODEC_LOADED","log","error","MEDIA_CODEC_MISSING","setTimeout","timestamp","call"],"sources":["util.ts"],"sourcesContent":["/* globals window */\n\nimport {\n _LOCUS_ID_,\n _INCOMING_,\n _CREATED_,\n LOCUSEVENT,\n CORRELATION_ID,\n EVENT_TRIGGERS,\n ROAP,\n} from '../constants';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport Trigger from '../common/events/trigger-proxy';\n\n/**\n * Meetings Media Codec Missing Event\n * Emitted when H.264 codec is not\n * found in the browser.\n * @event media:codec:missing\n * @instance\n * @memberof MeetingsUtil\n */\n\n/**\n * Meetings Media Codec Loaded Event\n * Emitted when H.264 codec has been\n * loaded in the browser.\n * @event media:codec:loaded\n * @instance\n * @memberof MeetingsUtil\n */\n\nconst MeetingsUtil: any = {};\n\nMeetingsUtil.getMeetingAddedType = (type) => (type === _LOCUS_ID_ ? _INCOMING_ : _CREATED_);\n\nMeetingsUtil.handleRoapMercury = (envelope, meetingCollection) => {\n const {data} = envelope;\n const {eventType} = data;\n\n if (eventType === LOCUSEVENT.MESSAGE_ROAP) {\n const meeting = meetingCollection.getByKey(CORRELATION_ID, data.correlationId);\n\n if (meeting) {\n const {seq, messageType, tieBreaker, errorType, errorCause} = data.message;\n\n if (messageType === ROAP.ROAP_TYPES.TURN_DISCOVERY_RESPONSE) {\n // turn discovery is not part of normal roap protocol and so we are not handling it\n // through the usual roap state machine\n meeting.roap.turnDiscovery.handleTurnDiscoveryResponse(data.message);\n } else {\n const roapMessage = {\n seq,\n messageType,\n sdp: data.message.sdps?.length > 0 ? data.message.sdps[0] : undefined,\n tieBreaker,\n errorType,\n errorCause,\n };\n\n const mediaServer = MeetingsUtil.getMediaServer(roapMessage.sdp);\n\n meeting.mediaProperties.webrtcMediaConnection.roapMessageReceived(roapMessage);\n\n if (mediaServer) {\n meeting.mediaProperties.webrtcMediaConnection.mediaServer = mediaServer;\n }\n }\n }\n }\n};\n\nMeetingsUtil.getMediaServer = (sdp) => {\n let mediaServer;\n\n // Attempt to collect the media server from the roap message.\n try {\n mediaServer = sdp\n .split('\\r\\n')\n .find((line) => line.startsWith('o='))\n .split(' ')\n .shift()\n .replace('o=', '');\n } catch {\n mediaServer = undefined;\n }\n\n return mediaServer;\n};\n\nMeetingsUtil.checkForCorrelationId = (deviceUrl, locus) => {\n let devices = [];\n\n if (locus) {\n if (locus && locus.self && locus.self.devices) {\n devices = locus.self.devices;\n }\n\n const foundDevice = devices.find((device) => device.url === deviceUrl);\n\n if (foundDevice && foundDevice.correlationId) {\n return foundDevice.correlationId;\n }\n }\n\n return false;\n};\n\nMeetingsUtil.parseDefaultSiteFromMeetingPreferences = (userPreferences) => {\n let result = '';\n\n if (userPreferences && userPreferences.sites) {\n const defaultSite = userPreferences.sites.find((site) => site.default);\n\n if (defaultSite) {\n result = defaultSite.siteUrl;\n }\n }\n\n return result;\n};\n\n/**\n * Will check to see if the H.264 media codec is supported.\n * @async\n * @private\n * @returns {Promise<boolean>}\n */\nMeetingsUtil.hasH264Codec = async () => {\n let hasCodec = false;\n\n try {\n const pc = new window.RTCPeerConnection();\n const offer = await pc.createOffer({offerToReceiveVideo: true});\n\n if (offer.sdp.match(/^a=rtpmap:\\d+\\s+H264\\/\\d+/m)) {\n hasCodec = true;\n }\n pc.close();\n } catch (error) {\n LoggerProxy.logger.warn(\n 'Meetings:util#hasH264Codec --> Error creating peerConnection for H.264 test.'\n );\n }\n\n return hasCodec;\n};\n\n/**\n * Notifies the user whether or not the H.264\n * codec is present. Will continuously check\n * until max duration.\n * @async\n * @private\n * @param {object} options\n * @param {Number} options.firstChecked Timestamp in milliseconds\n * @param {boolean} options.disableNotifications Default is false. Boolean to enable/disable notification and events\n * @returns {undefined}\n */\nMeetingsUtil.checkH264Support = async function checkH264Support(options: {\n firstChecked: number;\n disableNotifications: boolean;\n}) {\n const {hasH264Codec} = MeetingsUtil;\n const {firstChecked, disableNotifications} = options || {};\n const delay = 5e3; // ms\n const maxDuration = 3e5; // ms\n const shouldTrigger = firstChecked === undefined;\n const shouldStopChecking = firstChecked && Date.now() - firstChecked >= maxDuration;\n\n // Disable notifications and start H.264 download only\n if (disableNotifications) {\n hasH264Codec();\n\n return;\n }\n\n // Codec loaded trigger event notification\n if (await hasH264Codec()) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_LOADED\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec loaded successfully.');\n\n return;\n }\n\n // Stop checking if past the timelimit\n if (shouldStopChecking) {\n LoggerProxy.logger.error(\n 'Meetings:util#checkH264Support --> Timed out waiting for H264 codec to load.'\n );\n\n return;\n }\n\n // Trigger only once\n if (shouldTrigger) {\n Trigger.trigger(\n this,\n {\n file: 'meetings/util',\n function: 'checkH264Support',\n },\n EVENT_TRIGGERS.MEDIA_CODEC_MISSING\n );\n LoggerProxy.logger.log('Meetings:util#checkH264Support --> H264 codec is missing.');\n }\n\n // Keep checking in intervals to see if codec loaded\n window.setTimeout(() => {\n const timestamp = firstChecked || Date.now();\n\n MeetingsUtil.checkH264Support.call(this, {firstChecked: timestamp});\n }, delay);\n};\n\nexport default MeetingsUtil;\n"],"mappings":"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"}
|
|
@@ -595,6 +595,10 @@ export declare const DISPLAY_HINTS: {
|
|
|
595
595
|
DISABLE_REACTIONS: string;
|
|
596
596
|
REACTIONS_ACTIVE: string;
|
|
597
597
|
REACTIONS_INACTIVE: string;
|
|
598
|
+
ENABLE_MUTE_ON_ENTRY: string;
|
|
599
|
+
DISABLE_MUTE_ON_ENTRY: string;
|
|
600
|
+
ENABLE_HARD_MUTE: string;
|
|
601
|
+
DISABLE_HARD_MUTE: string;
|
|
598
602
|
};
|
|
599
603
|
export declare const SELF_ROLES: {
|
|
600
604
|
COHOST: string;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import MeetingRequest from '../meeting/request';
|
|
2
|
+
/**
|
|
3
|
+
* docs
|
|
4
|
+
* https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html
|
|
5
|
+
* https://confluence-eng-gpk2.cisco.com/conf/display/LOCUS/Hard+Mute+and+Audio+Privacy#HardMuteandAudioPrivacy-SelfMuteonEntry
|
|
6
|
+
* https://confluence-eng-gpk2.cisco.com/conf/pages/viewpage.action?spaceKey=UC&title=WEBEX-124454%3A+UCF%3A+Hard+mute+support+for+Teams+joining+Webex+meeting
|
|
7
|
+
* https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-180867
|
|
8
|
+
* https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-393351
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* @description ControlsOptionsManager is responsible for handling the behavior of participant controls when somebody joins a meeting
|
|
12
|
+
* @export
|
|
13
|
+
* @private
|
|
14
|
+
* @class Recording
|
|
15
|
+
*/
|
|
16
|
+
export default class ControlsOptionsManager {
|
|
17
|
+
/**
|
|
18
|
+
* @instance
|
|
19
|
+
* @type {MeetingRequest}
|
|
20
|
+
* @private
|
|
21
|
+
* @memberof ControlsOptionsManager
|
|
22
|
+
*/
|
|
23
|
+
private request;
|
|
24
|
+
/**
|
|
25
|
+
* @instance
|
|
26
|
+
* @type {Array}
|
|
27
|
+
* @private
|
|
28
|
+
* @memberof ControlsOptionsManager
|
|
29
|
+
*/
|
|
30
|
+
private displayHints;
|
|
31
|
+
/**
|
|
32
|
+
* @instance
|
|
33
|
+
* @type {string}
|
|
34
|
+
* @private
|
|
35
|
+
* @memberof ControlsOptionsManager
|
|
36
|
+
*/
|
|
37
|
+
private locusUrl;
|
|
38
|
+
/**
|
|
39
|
+
* @param {MeetingRequest} request
|
|
40
|
+
* @param {Object} options
|
|
41
|
+
* @constructor
|
|
42
|
+
* @memberof ControlsOptionsManager
|
|
43
|
+
*/
|
|
44
|
+
constructor(request: MeetingRequest, options?: {
|
|
45
|
+
locusUrl: string;
|
|
46
|
+
displayHints?: Array<string>;
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* @param {MeetingRequest} request
|
|
50
|
+
* @returns {void}
|
|
51
|
+
* @private
|
|
52
|
+
* @memberof ControlsOptionsManager
|
|
53
|
+
*/
|
|
54
|
+
private initialize;
|
|
55
|
+
/**
|
|
56
|
+
* @param {Object} options
|
|
57
|
+
* @returns {void}
|
|
58
|
+
* @public
|
|
59
|
+
* @memberof ControlsOptionsManager
|
|
60
|
+
*/
|
|
61
|
+
set(options?: {
|
|
62
|
+
locusUrl: string;
|
|
63
|
+
displayHints?: Array<string>;
|
|
64
|
+
}): void;
|
|
65
|
+
/**
|
|
66
|
+
* @param {string} url
|
|
67
|
+
* @returns {void}
|
|
68
|
+
* @public
|
|
69
|
+
* @memberof ControlsOptionsManager
|
|
70
|
+
*/
|
|
71
|
+
setLocusUrl(url: string): void;
|
|
72
|
+
/**
|
|
73
|
+
* @param {Array} hints
|
|
74
|
+
* @returns {void}
|
|
75
|
+
* @public
|
|
76
|
+
* @memberof ControlsOptionsManager
|
|
77
|
+
*/
|
|
78
|
+
setDisplayHints(hints: Array<string>): void;
|
|
79
|
+
/**
|
|
80
|
+
* @returns {string}
|
|
81
|
+
* @public
|
|
82
|
+
* @memberof ControlsOptionsManager
|
|
83
|
+
*/
|
|
84
|
+
getLocusUrl(): string;
|
|
85
|
+
/**
|
|
86
|
+
* @returns {Array}
|
|
87
|
+
* @public
|
|
88
|
+
* @memberof ControlsOptionsManager
|
|
89
|
+
*/
|
|
90
|
+
getDisplayHints(): string[];
|
|
91
|
+
/**
|
|
92
|
+
* @param {Object} options
|
|
93
|
+
* @returns {void}
|
|
94
|
+
* @private
|
|
95
|
+
* @memberof ControlsOptionsManager
|
|
96
|
+
*/
|
|
97
|
+
private extract;
|
|
98
|
+
/**
|
|
99
|
+
* @param {Setting} setting
|
|
100
|
+
* @param {boolean} enabled
|
|
101
|
+
* @private
|
|
102
|
+
* @memberof ControlsOptionsManager
|
|
103
|
+
* @returns {Promise}
|
|
104
|
+
*/
|
|
105
|
+
private setControls;
|
|
106
|
+
/**
|
|
107
|
+
* @public
|
|
108
|
+
* @param {boolean} enabled
|
|
109
|
+
* @memberof ControlsOptionsManager
|
|
110
|
+
* @returns {Promise}
|
|
111
|
+
*/
|
|
112
|
+
setMuteOnEntry(enabled: boolean): Promise<any>;
|
|
113
|
+
/**
|
|
114
|
+
* @public
|
|
115
|
+
* @param {boolean} enabled
|
|
116
|
+
* @memberof ControlsOptionsManager
|
|
117
|
+
* @returns {Promise}
|
|
118
|
+
*/
|
|
119
|
+
setDisallowUnmute(enabled: boolean): Promise<any>;
|
|
120
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
canSetMuteOnEntry: (displayHints: string[]) => boolean;
|
|
3
|
+
canSetDisallowUnmute: (displayHints: string[]) => boolean;
|
|
4
|
+
canUnsetMuteOnEntry: (displayHints: string[]) => boolean;
|
|
5
|
+
canUnsetDisallowUnmute: (displayHints: string[]) => boolean;
|
|
6
|
+
};
|
|
7
|
+
export default _default;
|
|
@@ -10,6 +10,10 @@ interface IInMeetingActions {
|
|
|
10
10
|
canAdmitParticipant?: boolean;
|
|
11
11
|
canLock?: boolean;
|
|
12
12
|
canUnlock?: boolean;
|
|
13
|
+
canSetMuteOnEntry?: boolean;
|
|
14
|
+
canUnsetMuteOnEntry?: boolean;
|
|
15
|
+
canSetDisallowUnmute?: boolean;
|
|
16
|
+
canUnsetDisallowUnmute?: boolean;
|
|
13
17
|
canAssignHost?: boolean;
|
|
14
18
|
canStartRecording?: boolean;
|
|
15
19
|
canPauseRecording?: boolean;
|
|
@@ -45,6 +49,10 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
45
49
|
canPauseRecording: any;
|
|
46
50
|
canResumeRecording: any;
|
|
47
51
|
canStopRecording: any;
|
|
52
|
+
canSetMuteOnEntry: any;
|
|
53
|
+
canUnsetMuteOnEntry: any;
|
|
54
|
+
canSetDisallowUnmute: any;
|
|
55
|
+
canUnsetDisallowUnmute: any;
|
|
48
56
|
canRaiseHand: any;
|
|
49
57
|
canLowerAllHands: any;
|
|
50
58
|
canLowerSomeoneElsesHand: any;
|
|
@@ -14,6 +14,7 @@ import { RemoteMediaManager } from '../multistream/remoteMediaManager';
|
|
|
14
14
|
import { ReactionServerType, SkinToneType } from '../reactions/reactions.type';
|
|
15
15
|
import InMeetingActions from './in-meeting-actions';
|
|
16
16
|
import RecordingController from '../recording-controller';
|
|
17
|
+
import ControlsOptionsManager from '../controls-options-manager';
|
|
17
18
|
export declare const MEDIA_UPDATE_TYPE: {
|
|
18
19
|
ALL: string;
|
|
19
20
|
AUDIO: string;
|
|
@@ -345,6 +346,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
345
346
|
recording: any;
|
|
346
347
|
remoteMediaManager: RemoteMediaManager | null;
|
|
347
348
|
recordingController: RecordingController;
|
|
349
|
+
controlsOptionsManager: ControlsOptionsManager;
|
|
348
350
|
requiredCaptcha: any;
|
|
349
351
|
receiveSlotManager: ReceiveSlotManager;
|
|
350
352
|
shareStatus: string;
|
|
@@ -1378,6 +1380,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1378
1380
|
* @memberof Meeting
|
|
1379
1381
|
*/
|
|
1380
1382
|
startRecording(): Promise<any>;
|
|
1383
|
+
/**
|
|
1384
|
+
* set the mute on entry flag for participants if you're the host
|
|
1385
|
+
* @returns {Promise}
|
|
1386
|
+
* @param {boolean} enabled
|
|
1387
|
+
* @public
|
|
1388
|
+
* @memberof Meeting
|
|
1389
|
+
*/
|
|
1390
|
+
setMuteOnEntry(enabled: boolean): Promise<any>;
|
|
1391
|
+
/**
|
|
1392
|
+
* set the disallow unmute flag for participants if you're the host
|
|
1393
|
+
* @returns {Promise}
|
|
1394
|
+
* @param {boolean} enabled
|
|
1395
|
+
* @public
|
|
1396
|
+
* @memberof Meeting
|
|
1397
|
+
*/
|
|
1398
|
+
setDisallowUnmute(enabled: boolean): Promise<any>;
|
|
1381
1399
|
/**
|
|
1382
1400
|
* End the recording of this meeting
|
|
1383
1401
|
* @returns {Promise}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.27",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
|
|
6
6
|
"contributors": [
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@webex/plugin-meetings": "3.0.0-beta.
|
|
36
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
37
|
-
"@webex/test-helper-mocha": "3.0.0-beta.
|
|
38
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
39
|
-
"@webex/test-helper-retry": "3.0.0-beta.
|
|
40
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
35
|
+
"@webex/plugin-meetings": "3.0.0-beta.27",
|
|
36
|
+
"@webex/test-helper-chai": "3.0.0-beta.27",
|
|
37
|
+
"@webex/test-helper-mocha": "3.0.0-beta.27",
|
|
38
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.27",
|
|
39
|
+
"@webex/test-helper-retry": "3.0.0-beta.27",
|
|
40
|
+
"@webex/test-helper-test-users": "3.0.0-beta.27",
|
|
41
41
|
"chai": "^4.3.4",
|
|
42
42
|
"chai-as-promised": "^7.1.1",
|
|
43
43
|
"jsdom-global": "3.0.2",
|
|
@@ -45,18 +45,18 @@
|
|
|
45
45
|
"typed-emitter": "^2.1.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@webex/common": "3.0.0-beta.
|
|
48
|
+
"@webex/common": "3.0.0-beta.27",
|
|
49
49
|
"@webex/internal-media-core": "1.33.2",
|
|
50
|
-
"@webex/internal-plugin-conversation": "3.0.0-beta.
|
|
51
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
52
|
-
"@webex/internal-plugin-llm": "3.0.0-beta.
|
|
53
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
54
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
55
|
-
"@webex/internal-plugin-support": "3.0.0-beta.
|
|
56
|
-
"@webex/internal-plugin-user": "3.0.0-beta.
|
|
57
|
-
"@webex/plugin-people": "3.0.0-beta.
|
|
58
|
-
"@webex/plugin-rooms": "3.0.0-beta.
|
|
59
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
50
|
+
"@webex/internal-plugin-conversation": "3.0.0-beta.27",
|
|
51
|
+
"@webex/internal-plugin-device": "3.0.0-beta.27",
|
|
52
|
+
"@webex/internal-plugin-llm": "3.0.0-beta.27",
|
|
53
|
+
"@webex/internal-plugin-mercury": "3.0.0-beta.27",
|
|
54
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.27",
|
|
55
|
+
"@webex/internal-plugin-support": "3.0.0-beta.27",
|
|
56
|
+
"@webex/internal-plugin-user": "3.0.0-beta.27",
|
|
57
|
+
"@webex/plugin-people": "3.0.0-beta.27",
|
|
58
|
+
"@webex/plugin-rooms": "3.0.0-beta.27",
|
|
59
|
+
"@webex/webex-core": "3.0.0-beta.27",
|
|
60
60
|
"ampersand-collection": "^2.0.2",
|
|
61
61
|
"bowser": "^2.11.0",
|
|
62
62
|
"btoa": "^1.2.1",
|
package/src/breakouts/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {WebexPlugin} from '@webex/webex-core';
|
|
|
5
5
|
import {debounce, forEach} from 'lodash';
|
|
6
6
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
7
7
|
|
|
8
|
-
import {BREAKOUTS, MEETINGS} from '../constants';
|
|
8
|
+
import {BREAKOUTS, MEETINGS, HTTP_VERBS} from '../constants';
|
|
9
9
|
|
|
10
10
|
import Breakout from './breakout';
|
|
11
11
|
import BreakoutCollection from './collection';
|
|
@@ -32,6 +32,7 @@ const Breakouts = WebexPlugin.extend({
|
|
|
32
32
|
status: 'string', // only present when in a breakout session
|
|
33
33
|
url: 'string', // appears from the moment you enable breakouts
|
|
34
34
|
locusUrl: 'string', // the current locus url
|
|
35
|
+
breakoutServiceUrl: 'string', // the current breakout resouce url
|
|
35
36
|
},
|
|
36
37
|
|
|
37
38
|
children: {
|
|
@@ -89,6 +90,15 @@ const Breakouts = WebexPlugin.extend({
|
|
|
89
90
|
this.set('locusUrl', locusUrl);
|
|
90
91
|
},
|
|
91
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Update the current breakout resouce url
|
|
95
|
+
* @param {string} breakoutServiceUrl
|
|
96
|
+
* @returns {void}
|
|
97
|
+
*/
|
|
98
|
+
breakoutServiceUrlUpdate(breakoutServiceUrl) {
|
|
99
|
+
this.set('breakoutServiceUrl', `${breakoutServiceUrl}/breakout/`);
|
|
100
|
+
},
|
|
101
|
+
|
|
92
102
|
/**
|
|
93
103
|
* The initial roster lists need to be queried because you don't
|
|
94
104
|
* get a breakout.roster event when you join the meeting
|
|
@@ -184,6 +194,8 @@ const Breakouts = WebexPlugin.extend({
|
|
|
184
194
|
[BREAKOUTS.SESSION_STATES.ASSIGNED_CURRENT]: false,
|
|
185
195
|
[BREAKOUTS.SESSION_STATES.REQUESTED]: false,
|
|
186
196
|
});
|
|
197
|
+
|
|
198
|
+
this.set('enableBreakoutSession', params.enableBreakoutSession);
|
|
187
199
|
},
|
|
188
200
|
|
|
189
201
|
/**
|
|
@@ -220,6 +232,66 @@ const Breakouts = WebexPlugin.extend({
|
|
|
220
232
|
|
|
221
233
|
this.breakouts.set(Object.values(breakouts));
|
|
222
234
|
},
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Make enable breakout resource
|
|
238
|
+
* @returns {Promise}
|
|
239
|
+
*/
|
|
240
|
+
enableBreakouts() {
|
|
241
|
+
if (this.breakoutServiceUrl) {
|
|
242
|
+
// @ts-ignore
|
|
243
|
+
return this.webex
|
|
244
|
+
.request({
|
|
245
|
+
method: HTTP_VERBS.POST,
|
|
246
|
+
uri: this.breakoutServiceUrl,
|
|
247
|
+
body: {
|
|
248
|
+
locusUrl: this.locusUrl,
|
|
249
|
+
},
|
|
250
|
+
})
|
|
251
|
+
.catch((err) => {
|
|
252
|
+
LoggerProxy.logger.error(
|
|
253
|
+
`Meeting:request#touchBreakout --> Error provisioning error ${err}`
|
|
254
|
+
);
|
|
255
|
+
throw err;
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return Promise.reject(new Error(`enableBreakouts: the breakoutServiceUrl is empty`));
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Make the meeting enbale or disable breakout session
|
|
264
|
+
* @param {boolean} enable
|
|
265
|
+
* @returns {Promise}
|
|
266
|
+
*/
|
|
267
|
+
async toggleBreakout(enable) {
|
|
268
|
+
if (this.enableBreakoutSession === undefined) {
|
|
269
|
+
const info = await this.enableBreakouts();
|
|
270
|
+
if (!enable) {
|
|
271
|
+
// if enable is false, updateBreakout set the param then set enableBreakoutSession as false
|
|
272
|
+
this.updateBreakout(info.body);
|
|
273
|
+
await this.doToggleBreakout(enable);
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
await this.doToggleBreakout(enable);
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* do toggle meeting breakout session enable or disable
|
|
282
|
+
* @param {boolean} enable
|
|
283
|
+
* @returns {Promise}
|
|
284
|
+
*/
|
|
285
|
+
doToggleBreakout(enable) {
|
|
286
|
+
// @ts-ignore
|
|
287
|
+
return this.webex.request({
|
|
288
|
+
method: HTTP_VERBS.PUT,
|
|
289
|
+
uri: this.url,
|
|
290
|
+
body: {
|
|
291
|
+
enableBreakoutSession: enable,
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
},
|
|
223
295
|
});
|
|
224
296
|
|
|
225
297
|
export default Breakouts;
|
package/src/constants.ts
CHANGED
|
@@ -761,6 +761,10 @@ export const DISPLAY_HINTS = {
|
|
|
761
761
|
DISABLE_REACTIONS: 'DISABLE_REACTIONS',
|
|
762
762
|
REACTIONS_ACTIVE: 'REACTIONS_ACTIVE',
|
|
763
763
|
REACTIONS_INACTIVE: 'REACTIONS_INACTIVE',
|
|
764
|
+
ENABLE_MUTE_ON_ENTRY: 'ENABLE_MUTE_ON_ENTRY',
|
|
765
|
+
DISABLE_MUTE_ON_ENTRY: 'DISABLE_MUTE_ON_ENTRY',
|
|
766
|
+
ENABLE_HARD_MUTE: 'ENABLE_HARD_MUTE',
|
|
767
|
+
DISABLE_HARD_MUTE: 'DISABLE_HARD_MUTE',
|
|
764
768
|
};
|
|
765
769
|
|
|
766
770
|
export const SELF_ROLES = {
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {camelCase} from 'lodash';
|
|
2
|
+
import PermissionError from '../common/errors/permission';
|
|
3
|
+
import {CONTROLS, HTTP_VERBS} from '../constants';
|
|
4
|
+
import MeetingRequest from '../meeting/request';
|
|
5
|
+
import LoggerProxy from '../common/logs/logger-proxy';
|
|
6
|
+
import Setting from './enums';
|
|
7
|
+
import Util from './util';
|
|
8
|
+
import {CAN_SET, CAN_UNSET, ENABLED} from './constants';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* docs
|
|
12
|
+
* https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html
|
|
13
|
+
* https://confluence-eng-gpk2.cisco.com/conf/display/LOCUS/Hard+Mute+and+Audio+Privacy#HardMuteandAudioPrivacy-SelfMuteonEntry
|
|
14
|
+
* https://confluence-eng-gpk2.cisco.com/conf/pages/viewpage.action?spaceKey=UC&title=WEBEX-124454%3A+UCF%3A+Hard+mute+support+for+Teams+joining+Webex+meeting
|
|
15
|
+
* https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-180867
|
|
16
|
+
* https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-393351
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @description ControlsOptionsManager is responsible for handling the behavior of participant controls when somebody joins a meeting
|
|
21
|
+
* @export
|
|
22
|
+
* @private
|
|
23
|
+
* @class Recording
|
|
24
|
+
*/
|
|
25
|
+
export default class ControlsOptionsManager {
|
|
26
|
+
/**
|
|
27
|
+
* @instance
|
|
28
|
+
* @type {MeetingRequest}
|
|
29
|
+
* @private
|
|
30
|
+
* @memberof ControlsOptionsManager
|
|
31
|
+
*/
|
|
32
|
+
private request: MeetingRequest;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @instance
|
|
36
|
+
* @type {Array}
|
|
37
|
+
* @private
|
|
38
|
+
* @memberof ControlsOptionsManager
|
|
39
|
+
*/
|
|
40
|
+
private displayHints: Array<string> = [];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @instance
|
|
44
|
+
* @type {string}
|
|
45
|
+
* @private
|
|
46
|
+
* @memberof ControlsOptionsManager
|
|
47
|
+
*/
|
|
48
|
+
private locusUrl: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {MeetingRequest} request
|
|
52
|
+
* @param {Object} options
|
|
53
|
+
* @constructor
|
|
54
|
+
* @memberof ControlsOptionsManager
|
|
55
|
+
*/
|
|
56
|
+
constructor(
|
|
57
|
+
request: MeetingRequest,
|
|
58
|
+
options?: {
|
|
59
|
+
locusUrl: string;
|
|
60
|
+
displayHints?: Array<string>;
|
|
61
|
+
}
|
|
62
|
+
) {
|
|
63
|
+
this.initialize(request);
|
|
64
|
+
this.set(options);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {MeetingRequest} request
|
|
69
|
+
* @returns {void}
|
|
70
|
+
* @private
|
|
71
|
+
* @memberof ControlsOptionsManager
|
|
72
|
+
*/
|
|
73
|
+
private initialize(request: MeetingRequest) {
|
|
74
|
+
this.request = request;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @param {Object} options
|
|
79
|
+
* @returns {void}
|
|
80
|
+
* @public
|
|
81
|
+
* @memberof ControlsOptionsManager
|
|
82
|
+
*/
|
|
83
|
+
public set(options?: {locusUrl: string; displayHints?: Array<string>}) {
|
|
84
|
+
this.extract(options);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {string} url
|
|
89
|
+
* @returns {void}
|
|
90
|
+
* @public
|
|
91
|
+
* @memberof ControlsOptionsManager
|
|
92
|
+
*/
|
|
93
|
+
public setLocusUrl(url: string) {
|
|
94
|
+
this.locusUrl = url;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {Array} hints
|
|
99
|
+
* @returns {void}
|
|
100
|
+
* @public
|
|
101
|
+
* @memberof ControlsOptionsManager
|
|
102
|
+
*/
|
|
103
|
+
public setDisplayHints(hints: Array<string>) {
|
|
104
|
+
this.displayHints = hints;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @returns {string}
|
|
109
|
+
* @public
|
|
110
|
+
* @memberof ControlsOptionsManager
|
|
111
|
+
*/
|
|
112
|
+
public getLocusUrl() {
|
|
113
|
+
return this.locusUrl;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @returns {Array}
|
|
118
|
+
* @public
|
|
119
|
+
* @memberof ControlsOptionsManager
|
|
120
|
+
*/
|
|
121
|
+
public getDisplayHints() {
|
|
122
|
+
return this.displayHints;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @param {Object} options
|
|
127
|
+
* @returns {void}
|
|
128
|
+
* @private
|
|
129
|
+
* @memberof ControlsOptionsManager
|
|
130
|
+
*/
|
|
131
|
+
private extract(options?: {locusUrl: string; displayHints?: Array<string>}) {
|
|
132
|
+
this.setDisplayHints(options?.displayHints);
|
|
133
|
+
this.setLocusUrl(options?.locusUrl);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @param {Setting} setting
|
|
138
|
+
* @param {boolean} enabled
|
|
139
|
+
* @private
|
|
140
|
+
* @memberof ControlsOptionsManager
|
|
141
|
+
* @returns {Promise}
|
|
142
|
+
*/
|
|
143
|
+
private setControls(setting: Setting, enabled: boolean): Promise<any> {
|
|
144
|
+
LoggerProxy.logger.log(`ControlsOptionsManager:index#setControls --> ${setting} [${enabled}]`);
|
|
145
|
+
|
|
146
|
+
if (Util?.[`${enabled ? CAN_SET : CAN_UNSET}${setting}`](this.displayHints)) {
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
return this.request.request({
|
|
149
|
+
uri: `${this.locusUrl}/${CONTROLS}`,
|
|
150
|
+
body: {
|
|
151
|
+
[camelCase(setting)]: {
|
|
152
|
+
[ENABLED]: enabled,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
method: HTTP_VERBS.PATCH,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return Promise.reject(
|
|
160
|
+
new PermissionError(`${setting} [${enabled}] not allowed, due to moderator property.`)
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @public
|
|
166
|
+
* @param {boolean} enabled
|
|
167
|
+
* @memberof ControlsOptionsManager
|
|
168
|
+
* @returns {Promise}
|
|
169
|
+
*/
|
|
170
|
+
public setMuteOnEntry(enabled: boolean): Promise<any> {
|
|
171
|
+
return this.setControls(Setting.muteOnEntry, enabled);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @public
|
|
176
|
+
* @param {boolean} enabled
|
|
177
|
+
* @memberof ControlsOptionsManager
|
|
178
|
+
* @returns {Promise}
|
|
179
|
+
*/
|
|
180
|
+
public setDisallowUnmute(enabled: boolean): Promise<any> {
|
|
181
|
+
return this.setControls(Setting.disallowUnmute, enabled);
|
|
182
|
+
}
|
|
183
|
+
}
|