@webex/plugin-meetings 3.8.0-next.31 → 3.8.0-next.32

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.
@@ -148,7 +148,6 @@ var MuteState = exports.MuteState = /*#__PURE__*/function () {
148
148
  * @public
149
149
  * @memberof MuteState
150
150
  * @param {Object} [meeting] the meeting object
151
- * @param {Boolean} [mute] true for muting, false for unmuting request
152
151
  * @returns {void}
153
152
  */
154
153
  }, {
@@ -309,7 +308,6 @@ var MuteState = exports.MuteState = /*#__PURE__*/function () {
309
308
  * @param {Meeting} meeting
310
309
  * @returns {void}
311
310
  */
312
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
313
311
  }, {
314
312
  key: "applyUnmuteAllowedToStream",
315
313
  value: function applyUnmuteAllowedToStream(meeting) {
@@ -1 +1 @@
1
- {"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_parameter","_util","_constants","createMuteState","exports","type","meeting","enabled","LoggerProxy","logger","info","concat","id","muteState","MuteState","_meeting$remoteVideoM","_meeting$unmuteVideoA","_classCallCheck2","default","_defineProperty2","AUDIO","VIDEO","ParameterError","ignoreMuteStateChange","state","client","localMute","server","remoteMute","remoteMuted","remoteVideoMuted","unmuteAllowed","unmuteVideoAllowed","syncToServerInProgress","_createClass2","key","value","init","_meeting$mediaPropert","_meeting$mediaPropert2","applyUnmuteAllowedToStream","muteLocalStream","initialMute","mediaProperties","audioStream","muted","videoStream","undefined","applyClientStateToServer","handleLocalStreamChange","enable","mute","reason","_meeting$mediaPropert3","setServerMuted","_meeting$mediaPropert4","handleLocalStreamMuteStateChange","newMuteState","userMuteState","systemMuteState","_meeting$mediaPropert5","_meeting$mediaPropert6","_meeting$mediaPropert7","userMuted","systemMuted","_meeting$mediaPropert8","_meeting$mediaPropert9","_meeting$mediaPropert10","applyClientStateLocally","getClientLocalMuteState","_this","localMuteState","localMuteRequiresSync","remoteMuteRequiresSync","localMuteSyncPromise","sendLocalMuteRequestToServer","_promise","resolve","then","sendRemoteMuteRequestToServer","catch","e","warn","_this2","audioMuted","videoMuted","MeetingUtil","remoteUpdateAudioVideo","locus","locusInfo","handleLocusDelta","remoteUpdateError","reject","_this3","members","muteMember","selfId","_meeting$mediaPropert11","setUnmuteAllowed","_meeting$mediaPropert12","handleServerRemoteMuteUpdate","handleServerLocalUnmuteRequired","_meeting$mediaPropert13","_meeting$mediaPropert14","isMuted","isRemotelyMuted","isUnmuteAllowed","isLocallyMuted"],"sources":["muteState.ts"],"sourcesContent":["import {ServerMuteReason} from '@webex/media-helpers';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport ParameterError from '../common/errors/parameter';\nimport MeetingUtil from './util';\nimport {AUDIO, VIDEO} from '../constants';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const createMuteState = (type, meeting, enabled: boolean) => {\n // todo: remove the meeting argument (SPARK-399695)\n\n LoggerProxy.logger.info(\n `Meeting:muteState#createMuteState --> ${type}: creating MuteState for meeting id ${meeting?.id}`\n );\n\n const muteState = new MuteState(type, meeting, enabled);\n\n return muteState;\n};\n\n/** The purpose of this class is to manage the local and remote mute state and make sure that the server state always matches\n the last requested state by the client.\n\n More info about Locus muting API: https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html#\n\n This class is exported only for unit tests. It should never be instantiated directly with new MuteState(), instead createMuteState() should be called\n*/\nexport class MuteState {\n state: {\n client: {\n enabled: boolean; // indicates if audio/video is enabled at all or not\n localMute: boolean;\n };\n server: {localMute: boolean; remoteMute: boolean; unmuteAllowed: boolean};\n syncToServerInProgress: boolean;\n };\n\n type: any;\n ignoreMuteStateChange: boolean;\n\n /**\n * Constructor\n *\n * @param {String} type - audio or video\n * @param {Object} meeting - the meeting object (used for reading current remote mute status)\n * @param {boolean} enabled - whether the client audio/video is enabled at all\n */\n constructor(type: string, meeting: any, enabled: boolean) {\n if (type !== AUDIO && type !== VIDEO) {\n throw new ParameterError('Mute state is designed for handling audio or video only');\n }\n this.type = type;\n this.ignoreMuteStateChange = false;\n this.state = {\n client: {\n enabled,\n localMute: true,\n },\n server: {\n localMute: true,\n // because remoteVideoMuted and unmuteVideoAllowed are updated seperately, they might be undefined\n remoteMute: type === AUDIO ? meeting.remoteMuted : meeting.remoteVideoMuted ?? false,\n unmuteAllowed: type === AUDIO ? meeting.unmuteAllowed : meeting.unmuteVideoAllowed ?? true,\n },\n syncToServerInProgress: false,\n };\n }\n\n /**\n * Starts the mute state machine. Needs to be called after a new MuteState instance is created.\n *\n * @param {Object} meeting - the meeting object\n * @returns {void}\n */\n public init(meeting: any) {\n this.applyUnmuteAllowedToStream(meeting);\n\n // if we are remotely muted, we need to apply that to the local stream now (mute on-entry)\n if (this.state.server.remoteMute) {\n this.muteLocalStream(meeting, this.state.server.remoteMute, 'remotelyMuted');\n }\n\n const initialMute =\n this.type === AUDIO\n ? meeting.mediaProperties.audioStream?.muted\n : meeting.mediaProperties.videoStream?.muted;\n\n LoggerProxy.logger.info(\n `Meeting:muteState#init --> ${this.type}: local stream initial mute state: ${initialMute}`\n );\n\n if (initialMute !== undefined) {\n this.state.client.localMute = initialMute;\n } else {\n // there is no stream, so it's like we are locally muted\n // (this is important especially for transcoded meetings, in which the SDP m-line direction always stays \"sendrecv\")\n this.state.client.localMute = true;\n }\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * This method needs to be called whenever the local audio/video stream has changed.\n * It reapplies the remote mute state onto the new stream and also reads the current\n * local mute state from the stream and updates the internal state machine and sends\n * any required requests to the server.\n *\n * @param {Object} meeting - the meeting object\n * @returns {void}\n */\n public handleLocalStreamChange(meeting: any) {\n return this.init(meeting);\n }\n\n /**\n * Enables/disables audio/video\n *\n * @param {Object} meeting - the meeting object\n * @param {boolean} enable\n * @returns {void}\n */\n public enable(meeting: any, enable: boolean) {\n this.state.client.enabled = enable;\n\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * Mutes/unmutes local stream\n *\n * @param {Object} meeting - the meeting object\n * @param {Boolean} mute - true to mute the stream, false to unmute it\n * @param {ServerMuteReason} reason - reason for muting/unmuting\n * @returns {void}\n */\n private muteLocalStream(meeting: any, mute: boolean, reason: ServerMuteReason) {\n this.ignoreMuteStateChange = true;\n if (this.type === AUDIO) {\n meeting.mediaProperties.audioStream?.setServerMuted(mute, reason);\n } else {\n meeting.mediaProperties.videoStream?.setServerMuted(mute, reason);\n }\n this.ignoreMuteStateChange = false;\n }\n\n /**\n * This method should be called when the local stream mute state is changed\n * @public\n * @memberof MuteState\n * @param {Object} [meeting] the meeting object\n * @param {Boolean} [mute] true for muting, false for unmuting request\n * @returns {void}\n */\n public handleLocalStreamMuteStateChange(meeting?: any) {\n if (this.ignoreMuteStateChange) {\n return;\n }\n\n // either user or system may have triggered a mute state change, but localMute should reflect both\n let newMuteState: boolean;\n let userMuteState: boolean;\n let systemMuteState: boolean;\n if (this.type === AUDIO) {\n newMuteState = meeting.mediaProperties.audioStream?.muted;\n userMuteState = meeting.mediaProperties.audioStream?.userMuted;\n systemMuteState = meeting.mediaProperties.audioStream?.systemMuted;\n } else {\n newMuteState = meeting.mediaProperties.videoStream?.muted;\n userMuteState = meeting.mediaProperties.videoStream?.userMuted;\n systemMuteState = meeting.mediaProperties.videoStream?.systemMuted;\n }\n\n LoggerProxy.logger.info(\n `Meeting:muteState#handleLocalStreamMuteStateChange --> ${this.type}: local stream new mute state: ${newMuteState} (user mute: ${userMuteState}, system mute: ${systemMuteState})`\n );\n\n this.state.client.localMute = newMuteState;\n\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * Applies the current mute state to the local stream (by enabling or disabling it accordingly)\n *\n * @public\n * @param {Object} [meeting] the meeting object\n * @param {ServerMuteReason} reason - reason why we're applying our client state to the local stream\n * @memberof MuteState\n * @returns {void}\n */\n public applyClientStateLocally(meeting?: any, reason?: ServerMuteReason) {\n this.muteLocalStream(meeting, this.state.client.localMute, reason);\n }\n\n /** Returns true if client is locally muted - it takes into account not just the client local mute state,\n * but also whether audio/video is enabled at all\n *\n * @returns {boolean}\n */\n private getClientLocalMuteState() {\n return this.state.client.enabled ? this.state.client.localMute : true;\n }\n\n /**\n * Updates the server local and remote mute values so that they match the current client desired state.\n *\n * @private\n * @param {Object} [meeting] the meeting object\n * @memberof MuteState\n * @returns {void}\n */\n private applyClientStateToServer(meeting?: any) {\n if (this.state.syncToServerInProgress) {\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: request to server in progress, we need to wait for it to complete`\n );\n\n return;\n }\n\n const localMuteState = this.getClientLocalMuteState();\n const localMuteRequiresSync = localMuteState !== this.state.server.localMute;\n const remoteMuteRequiresSync = !localMuteState && this.state.server.remoteMute;\n\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: localMuteRequiresSync: ${localMuteRequiresSync} (${localMuteState} ?= ${this.state.server.localMute})`\n );\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: remoteMuteRequiresSync: ${remoteMuteRequiresSync}`\n );\n\n if (!localMuteRequiresSync && !remoteMuteRequiresSync) {\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: client state already matching server state, nothing to do`\n );\n\n return;\n }\n\n this.state.syncToServerInProgress = true;\n\n // first sync local mute with server\n const localMuteSyncPromise = localMuteRequiresSync\n ? this.sendLocalMuteRequestToServer(meeting)\n : Promise.resolve();\n\n localMuteSyncPromise\n .then(() =>\n // then follow it up with remote mute sync\n remoteMuteRequiresSync ? this.sendRemoteMuteRequestToServer(meeting) : Promise.resolve()\n )\n .then(() => {\n this.state.syncToServerInProgress = false;\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: sync with server completed`\n );\n\n // need to check if a new sync is required, because this.state.client may have changed while we were doing the current sync\n this.applyClientStateToServer(meeting);\n })\n .catch((e) => {\n this.state.syncToServerInProgress = false;\n\n LoggerProxy.logger.warn(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: error: ${e}`\n );\n\n // failed to apply client state to server, so revert stream mute state to server state\n this.muteLocalStream(\n meeting,\n this.state.server.localMute || this.state.server.remoteMute,\n 'clientRequestFailed'\n );\n });\n }\n\n /**\n * Sets the local mute value in the server\n *\n * @private\n * @param {Object} [meeting] the meeting object\n * @memberof MuteState\n * @returns {Promise}\n */\n private sendLocalMuteRequestToServer(meeting?: any) {\n const audioMuted = this.type === AUDIO ? this.getClientLocalMuteState() : undefined;\n const videoMuted = this.type === VIDEO ? this.getClientLocalMuteState() : undefined;\n\n LoggerProxy.logger.info(\n `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: sending local mute (audio=${audioMuted}, video=${videoMuted}) to server`\n );\n\n return MeetingUtil.remoteUpdateAudioVideo(meeting, audioMuted, videoMuted)\n .then((locus) => {\n LoggerProxy.logger.info(\n `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: local mute (audio=${audioMuted}, video=${videoMuted}) applied to server`\n );\n\n this.state.server.localMute = this.type === AUDIO ? audioMuted : videoMuted;\n\n if (locus) {\n meeting.locusInfo.handleLocusDelta(locus, meeting);\n }\n\n return locus;\n })\n .catch((remoteUpdateError) => {\n LoggerProxy.logger.warn(\n `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: failed to apply local mute (audio=${audioMuted}, video=${videoMuted}) to server: ${remoteUpdateError}`\n );\n\n return Promise.reject(remoteUpdateError);\n });\n }\n\n /**\n * Sets the remote mute value in the server\n *\n * @private\n * @param {Object} [meeting] the meeting object\n * @memberof MuteState\n * @returns {Promise}\n */\n private sendRemoteMuteRequestToServer(meeting?: any) {\n const remoteMute = this.getClientLocalMuteState();\n\n LoggerProxy.logger.info(\n `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: sending remote mute:${remoteMute} to server`\n );\n\n return meeting.members\n .muteMember(meeting.members.selfId, remoteMute, this.type === AUDIO)\n .then(() => {\n LoggerProxy.logger.info(\n `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: remote mute:${remoteMute} applied to server`\n );\n\n this.state.server.remoteMute = remoteMute;\n })\n .catch((remoteUpdateError) => {\n LoggerProxy.logger.warn(\n `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: failed to apply remote mute ${remoteMute} to server: ${remoteUpdateError}`\n );\n\n return Promise.reject(remoteUpdateError);\n });\n }\n\n /** Applies the current value for unmute allowed to the underlying stream\n *\n * @param {Meeting} meeting\n * @returns {void}\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private applyUnmuteAllowedToStream(meeting: any) {\n if (this.type === AUDIO) {\n meeting.mediaProperties.audioStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);\n } else {\n meeting.mediaProperties.videoStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);\n }\n }\n\n /**\n * This method should be called whenever the server remote mute state is changed\n *\n * @public\n * @memberof MuteState\n * @param {Meeting} meeting\n * @param {Boolean} [muted] true if user is remotely muted, false otherwise\n * @param {Boolean} [unmuteAllowed] indicates if user is allowed to unmute self (false when \"hard mute\" feature is used)\n * @returns {undefined}\n */\n public handleServerRemoteMuteUpdate(meeting: any, muted?: boolean, unmuteAllowed?: boolean) {\n LoggerProxy.logger.info(\n `Meeting:muteState#handleServerRemoteMuteUpdate --> ${this.type}: updating server remoteMute to (${muted})`\n );\n if (unmuteAllowed !== undefined) {\n this.state.server.unmuteAllowed = unmuteAllowed;\n this.applyUnmuteAllowedToStream(meeting);\n }\n if (muted !== undefined) {\n this.state.server.remoteMute = muted;\n this.muteLocalStream(meeting, muted, 'remotelyMuted');\n }\n }\n\n /**\n * This method should be called whenever we receive from the server a requirement to locally unmute\n *\n * @public\n * @memberof MuteState\n * @param {Object} [meeting] the meeting object\n * @param {Boolean} [unmuteAllowed] whether the user is allowed to unmute self\n * @returns {undefined}\n */\n public handleServerLocalUnmuteRequired(meeting: any, unmuteAllowed: boolean) {\n if (!this.state.client.enabled) {\n LoggerProxy.logger.warn(\n `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received while ${this.type} is disabled -> local unmute will not result in ${this.type} being sent`\n );\n } else {\n LoggerProxy.logger.info(\n `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute (unmuteAllowed=${unmuteAllowed})`\n );\n }\n\n // todo: I'm seeing \"you can now unmute yourself \" popup when this happens - but same thing happens on web.w.c so we can ignore for now\n this.state.server.remoteMute = false;\n this.state.server.unmuteAllowed = unmuteAllowed;\n\n this.applyUnmuteAllowedToStream(meeting);\n\n // change user mute state to false, but keep localMute true if overall mute state is still true\n this.muteLocalStream(meeting, false, 'localUnmuteRequired');\n if (this.type === AUDIO) {\n this.state.client.localMute = meeting.mediaProperties.audioStream?.muted;\n } else {\n this.state.client.localMute = meeting.mediaProperties.videoStream?.muted;\n }\n\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * Returns true if the user is locally or remotely muted.\n * It only checks the mute status, ignoring the fact whether audio/video is enabled.\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isMuted() {\n return (\n this.state.client.localMute || this.state.server.localMute || this.state.server.remoteMute\n );\n }\n\n /**\n * Returns true if the user is remotely muted\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isRemotelyMuted() {\n return this.state.server.remoteMute;\n }\n\n /**\n * Returns true if unmute is allowed\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isUnmuteAllowed() {\n return this.state.server.unmuteAllowed;\n }\n\n /**\n * Returns true if the user is locally muted or audio/video is disabled\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isLocallyMuted() {\n return this.getClientLocalMuteState();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_parameter","_util","_constants","createMuteState","exports","type","meeting","enabled","LoggerProxy","logger","info","concat","id","muteState","MuteState","_meeting$remoteVideoM","_meeting$unmuteVideoA","_classCallCheck2","default","_defineProperty2","AUDIO","VIDEO","ParameterError","ignoreMuteStateChange","state","client","localMute","server","remoteMute","remoteMuted","remoteVideoMuted","unmuteAllowed","unmuteVideoAllowed","syncToServerInProgress","_createClass2","key","value","init","_meeting$mediaPropert","_meeting$mediaPropert2","applyUnmuteAllowedToStream","muteLocalStream","initialMute","mediaProperties","audioStream","muted","videoStream","undefined","applyClientStateToServer","handleLocalStreamChange","enable","mute","reason","_meeting$mediaPropert3","setServerMuted","_meeting$mediaPropert4","handleLocalStreamMuteStateChange","newMuteState","userMuteState","systemMuteState","_meeting$mediaPropert5","_meeting$mediaPropert6","_meeting$mediaPropert7","userMuted","systemMuted","_meeting$mediaPropert8","_meeting$mediaPropert9","_meeting$mediaPropert10","applyClientStateLocally","getClientLocalMuteState","_this","localMuteState","localMuteRequiresSync","remoteMuteRequiresSync","localMuteSyncPromise","sendLocalMuteRequestToServer","_promise","resolve","then","sendRemoteMuteRequestToServer","catch","e","warn","_this2","audioMuted","videoMuted","MeetingUtil","remoteUpdateAudioVideo","locus","locusInfo","handleLocusDelta","remoteUpdateError","reject","_this3","members","muteMember","selfId","_meeting$mediaPropert11","setUnmuteAllowed","_meeting$mediaPropert12","handleServerRemoteMuteUpdate","handleServerLocalUnmuteRequired","_meeting$mediaPropert13","_meeting$mediaPropert14","isMuted","isRemotelyMuted","isUnmuteAllowed","isLocallyMuted"],"sources":["muteState.ts"],"sourcesContent":["import {ServerMuteReason} from '@webex/media-helpers';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport ParameterError from '../common/errors/parameter';\nimport MeetingUtil from './util';\nimport {AUDIO, VIDEO} from '../constants';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const createMuteState = (type, meeting, enabled: boolean) => {\n // todo: remove the meeting argument (SPARK-399695)\n\n LoggerProxy.logger.info(\n `Meeting:muteState#createMuteState --> ${type}: creating MuteState for meeting id ${meeting?.id}`\n );\n\n const muteState = new MuteState(type, meeting, enabled);\n\n return muteState;\n};\n\n/** The purpose of this class is to manage the local and remote mute state and make sure that the server state always matches\n the last requested state by the client.\n\n More info about Locus muting API: https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html#\n\n This class is exported only for unit tests. It should never be instantiated directly with new MuteState(), instead createMuteState() should be called\n*/\nexport class MuteState {\n state: {\n client: {\n enabled: boolean; // indicates if audio/video is enabled at all or not\n localMute: boolean;\n };\n server: {localMute: boolean; remoteMute: boolean; unmuteAllowed: boolean};\n syncToServerInProgress: boolean;\n };\n\n type: any;\n ignoreMuteStateChange: boolean;\n\n /**\n * Constructor\n *\n * @param {String} type - audio or video\n * @param {Object} meeting - the meeting object (used for reading current remote mute status)\n * @param {boolean} enabled - whether the client audio/video is enabled at all\n */\n constructor(type: string, meeting: any, enabled: boolean) {\n if (type !== AUDIO && type !== VIDEO) {\n throw new ParameterError('Mute state is designed for handling audio or video only');\n }\n this.type = type;\n this.ignoreMuteStateChange = false;\n this.state = {\n client: {\n enabled,\n localMute: true,\n },\n server: {\n localMute: true,\n // because remoteVideoMuted and unmuteVideoAllowed are updated seperately, they might be undefined\n remoteMute: type === AUDIO ? meeting.remoteMuted : meeting.remoteVideoMuted ?? false,\n unmuteAllowed: type === AUDIO ? meeting.unmuteAllowed : meeting.unmuteVideoAllowed ?? true,\n },\n syncToServerInProgress: false,\n };\n }\n\n /**\n * Starts the mute state machine. Needs to be called after a new MuteState instance is created.\n *\n * @param {Object} meeting - the meeting object\n * @returns {void}\n */\n public init(meeting: any) {\n this.applyUnmuteAllowedToStream(meeting);\n\n // if we are remotely muted, we need to apply that to the local stream now (mute on-entry)\n if (this.state.server.remoteMute) {\n this.muteLocalStream(meeting, this.state.server.remoteMute, 'remotelyMuted');\n }\n\n const initialMute =\n this.type === AUDIO\n ? meeting.mediaProperties.audioStream?.muted\n : meeting.mediaProperties.videoStream?.muted;\n\n LoggerProxy.logger.info(\n `Meeting:muteState#init --> ${this.type}: local stream initial mute state: ${initialMute}`\n );\n\n if (initialMute !== undefined) {\n this.state.client.localMute = initialMute;\n } else {\n // there is no stream, so it's like we are locally muted\n // (this is important especially for transcoded meetings, in which the SDP m-line direction always stays \"sendrecv\")\n this.state.client.localMute = true;\n }\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * This method needs to be called whenever the local audio/video stream has changed.\n * It reapplies the remote mute state onto the new stream and also reads the current\n * local mute state from the stream and updates the internal state machine and sends\n * any required requests to the server.\n *\n * @param {Object} meeting - the meeting object\n * @returns {void}\n */\n public handleLocalStreamChange(meeting: any) {\n return this.init(meeting);\n }\n\n /**\n * Enables/disables audio/video\n *\n * @param {Object} meeting - the meeting object\n * @param {boolean} enable\n * @returns {void}\n */\n public enable(meeting: any, enable: boolean) {\n this.state.client.enabled = enable;\n\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * Mutes/unmutes local stream\n *\n * @param {Object} meeting - the meeting object\n * @param {Boolean} mute - true to mute the stream, false to unmute it\n * @param {ServerMuteReason} reason - reason for muting/unmuting\n * @returns {void}\n */\n private muteLocalStream(meeting: any, mute: boolean, reason: ServerMuteReason) {\n this.ignoreMuteStateChange = true;\n if (this.type === AUDIO) {\n meeting.mediaProperties.audioStream?.setServerMuted(mute, reason);\n } else {\n meeting.mediaProperties.videoStream?.setServerMuted(mute, reason);\n }\n this.ignoreMuteStateChange = false;\n }\n\n /**\n * This method should be called when the local stream mute state is changed\n * @public\n * @memberof MuteState\n * @param {Object} [meeting] the meeting object\n * @returns {void}\n */\n public handleLocalStreamMuteStateChange(meeting?: any) {\n if (this.ignoreMuteStateChange) {\n return;\n }\n\n // either user or system may have triggered a mute state change, but localMute should reflect both\n let newMuteState: boolean;\n let userMuteState: boolean;\n let systemMuteState: boolean;\n if (this.type === AUDIO) {\n newMuteState = meeting.mediaProperties.audioStream?.muted;\n userMuteState = meeting.mediaProperties.audioStream?.userMuted;\n systemMuteState = meeting.mediaProperties.audioStream?.systemMuted;\n } else {\n newMuteState = meeting.mediaProperties.videoStream?.muted;\n userMuteState = meeting.mediaProperties.videoStream?.userMuted;\n systemMuteState = meeting.mediaProperties.videoStream?.systemMuted;\n }\n\n LoggerProxy.logger.info(\n `Meeting:muteState#handleLocalStreamMuteStateChange --> ${this.type}: local stream new mute state: ${newMuteState} (user mute: ${userMuteState}, system mute: ${systemMuteState})`\n );\n\n this.state.client.localMute = newMuteState;\n\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * Applies the current mute state to the local stream (by enabling or disabling it accordingly)\n *\n * @public\n * @param {Object} [meeting] the meeting object\n * @param {ServerMuteReason} reason - reason why we're applying our client state to the local stream\n * @memberof MuteState\n * @returns {void}\n */\n public applyClientStateLocally(meeting?: any, reason?: ServerMuteReason) {\n this.muteLocalStream(meeting, this.state.client.localMute, reason);\n }\n\n /** Returns true if client is locally muted - it takes into account not just the client local mute state,\n * but also whether audio/video is enabled at all\n *\n * @returns {boolean}\n */\n private getClientLocalMuteState() {\n return this.state.client.enabled ? this.state.client.localMute : true;\n }\n\n /**\n * Updates the server local and remote mute values so that they match the current client desired state.\n *\n * @private\n * @param {Object} [meeting] the meeting object\n * @memberof MuteState\n * @returns {void}\n */\n private applyClientStateToServer(meeting?: any) {\n if (this.state.syncToServerInProgress) {\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: request to server in progress, we need to wait for it to complete`\n );\n\n return;\n }\n\n const localMuteState = this.getClientLocalMuteState();\n const localMuteRequiresSync = localMuteState !== this.state.server.localMute;\n const remoteMuteRequiresSync = !localMuteState && this.state.server.remoteMute;\n\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: localMuteRequiresSync: ${localMuteRequiresSync} (${localMuteState} ?= ${this.state.server.localMute})`\n );\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: remoteMuteRequiresSync: ${remoteMuteRequiresSync}`\n );\n\n if (!localMuteRequiresSync && !remoteMuteRequiresSync) {\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: client state already matching server state, nothing to do`\n );\n\n return;\n }\n\n this.state.syncToServerInProgress = true;\n\n // first sync local mute with server\n const localMuteSyncPromise = localMuteRequiresSync\n ? this.sendLocalMuteRequestToServer(meeting)\n : Promise.resolve();\n\n localMuteSyncPromise\n .then(() =>\n // then follow it up with remote mute sync\n remoteMuteRequiresSync ? this.sendRemoteMuteRequestToServer(meeting) : Promise.resolve()\n )\n .then(() => {\n this.state.syncToServerInProgress = false;\n LoggerProxy.logger.info(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: sync with server completed`\n );\n\n // need to check if a new sync is required, because this.state.client may have changed while we were doing the current sync\n this.applyClientStateToServer(meeting);\n })\n .catch((e) => {\n this.state.syncToServerInProgress = false;\n\n LoggerProxy.logger.warn(\n `Meeting:muteState#applyClientStateToServer --> ${this.type}: error: ${e}`\n );\n\n // failed to apply client state to server, so revert stream mute state to server state\n this.muteLocalStream(\n meeting,\n this.state.server.localMute || this.state.server.remoteMute,\n 'clientRequestFailed'\n );\n });\n }\n\n /**\n * Sets the local mute value in the server\n *\n * @private\n * @param {Object} [meeting] the meeting object\n * @memberof MuteState\n * @returns {Promise}\n */\n private sendLocalMuteRequestToServer(meeting?: any) {\n const audioMuted = this.type === AUDIO ? this.getClientLocalMuteState() : undefined;\n const videoMuted = this.type === VIDEO ? this.getClientLocalMuteState() : undefined;\n\n LoggerProxy.logger.info(\n `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: sending local mute (audio=${audioMuted}, video=${videoMuted}) to server`\n );\n\n return MeetingUtil.remoteUpdateAudioVideo(meeting, audioMuted, videoMuted)\n .then((locus) => {\n LoggerProxy.logger.info(\n `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: local mute (audio=${audioMuted}, video=${videoMuted}) applied to server`\n );\n\n this.state.server.localMute = this.type === AUDIO ? audioMuted : videoMuted;\n\n if (locus) {\n meeting.locusInfo.handleLocusDelta(locus, meeting);\n }\n\n return locus;\n })\n .catch((remoteUpdateError) => {\n LoggerProxy.logger.warn(\n `Meeting:muteState#sendLocalMuteRequestToServer --> ${this.type}: failed to apply local mute (audio=${audioMuted}, video=${videoMuted}) to server: ${remoteUpdateError}`\n );\n\n return Promise.reject(remoteUpdateError);\n });\n }\n\n /**\n * Sets the remote mute value in the server\n *\n * @private\n * @param {Object} [meeting] the meeting object\n * @memberof MuteState\n * @returns {Promise}\n */\n private sendRemoteMuteRequestToServer(meeting?: any) {\n const remoteMute = this.getClientLocalMuteState();\n\n LoggerProxy.logger.info(\n `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: sending remote mute:${remoteMute} to server`\n );\n\n return meeting.members\n .muteMember(meeting.members.selfId, remoteMute, this.type === AUDIO)\n .then(() => {\n LoggerProxy.logger.info(\n `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: remote mute:${remoteMute} applied to server`\n );\n\n this.state.server.remoteMute = remoteMute;\n })\n .catch((remoteUpdateError) => {\n LoggerProxy.logger.warn(\n `Meeting:muteState#sendRemoteMuteRequestToServer --> ${this.type}: failed to apply remote mute ${remoteMute} to server: ${remoteUpdateError}`\n );\n\n return Promise.reject(remoteUpdateError);\n });\n }\n\n /** Applies the current value for unmute allowed to the underlying stream\n *\n * @param {Meeting} meeting\n * @returns {void}\n */\n private applyUnmuteAllowedToStream(meeting: any) {\n if (this.type === AUDIO) {\n meeting.mediaProperties.audioStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);\n } else {\n meeting.mediaProperties.videoStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);\n }\n }\n\n /**\n * This method should be called whenever the server remote mute state is changed\n *\n * @public\n * @memberof MuteState\n * @param {Meeting} meeting\n * @param {Boolean} [muted] true if user is remotely muted, false otherwise\n * @param {Boolean} [unmuteAllowed] indicates if user is allowed to unmute self (false when \"hard mute\" feature is used)\n * @returns {undefined}\n */\n public handleServerRemoteMuteUpdate(meeting: any, muted?: boolean, unmuteAllowed?: boolean) {\n LoggerProxy.logger.info(\n `Meeting:muteState#handleServerRemoteMuteUpdate --> ${this.type}: updating server remoteMute to (${muted})`\n );\n if (unmuteAllowed !== undefined) {\n this.state.server.unmuteAllowed = unmuteAllowed;\n this.applyUnmuteAllowedToStream(meeting);\n }\n if (muted !== undefined) {\n this.state.server.remoteMute = muted;\n this.muteLocalStream(meeting, muted, 'remotelyMuted');\n }\n }\n\n /**\n * This method should be called whenever we receive from the server a requirement to locally unmute\n *\n * @public\n * @memberof MuteState\n * @param {Object} [meeting] the meeting object\n * @param {Boolean} [unmuteAllowed] whether the user is allowed to unmute self\n * @returns {undefined}\n */\n public handleServerLocalUnmuteRequired(meeting: any, unmuteAllowed: boolean) {\n if (!this.state.client.enabled) {\n LoggerProxy.logger.warn(\n `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received while ${this.type} is disabled -> local unmute will not result in ${this.type} being sent`\n );\n } else {\n LoggerProxy.logger.info(\n `Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute (unmuteAllowed=${unmuteAllowed})`\n );\n }\n\n // todo: I'm seeing \"you can now unmute yourself \" popup when this happens - but same thing happens on web.w.c so we can ignore for now\n this.state.server.remoteMute = false;\n this.state.server.unmuteAllowed = unmuteAllowed;\n\n this.applyUnmuteAllowedToStream(meeting);\n\n // change user mute state to false, but keep localMute true if overall mute state is still true\n this.muteLocalStream(meeting, false, 'localUnmuteRequired');\n if (this.type === AUDIO) {\n this.state.client.localMute = meeting.mediaProperties.audioStream?.muted;\n } else {\n this.state.client.localMute = meeting.mediaProperties.videoStream?.muted;\n }\n\n this.applyClientStateToServer(meeting);\n }\n\n /**\n * Returns true if the user is locally or remotely muted.\n * It only checks the mute status, ignoring the fact whether audio/video is enabled.\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isMuted() {\n return (\n this.state.client.localMute || this.state.server.localMute || this.state.server.remoteMute\n );\n }\n\n /**\n * Returns true if the user is remotely muted\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isRemotelyMuted() {\n return this.state.server.remoteMute;\n }\n\n /**\n * Returns true if unmute is allowed\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isUnmuteAllowed() {\n return this.state.server.unmuteAllowed;\n }\n\n /**\n * Returns true if the user is locally muted or audio/video is disabled\n *\n * @public\n * @memberof MuteState\n * @returns {Boolean}\n */\n public isLocallyMuted() {\n return this.getClientLocalMuteState();\n }\n}\n"],"mappings":"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"}
@@ -69,7 +69,6 @@ export declare class MuteState {
69
69
  * @public
70
70
  * @memberof MuteState
71
71
  * @param {Object} [meeting] the meeting object
72
- * @param {Boolean} [mute] true for muting, false for unmuting request
73
72
  * @returns {void}
74
73
  */
75
74
  handleLocalStreamMuteStateChange(meeting?: any): void;
@@ -458,7 +458,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
458
458
  }, _callee7);
459
459
  }))();
460
460
  },
461
- version: "3.8.0-next.31"
461
+ version: "3.8.0-next.32"
462
462
  });
463
463
  var _default = exports.default = Webinar;
464
464
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,7 +43,7 @@
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.8.0-next.31",
46
+ "@webex/plugin-meetings": "3.8.0-next.32",
47
47
  "@webex/plugin-rooms": "3.8.0-next.13",
48
48
  "@webex/test-helper-chai": "3.8.0-next.11",
49
49
  "@webex/test-helper-mocha": "3.8.0-next.11",
@@ -71,7 +71,7 @@
71
71
  "@webex/internal-plugin-metrics": "3.8.0-next.11",
72
72
  "@webex/internal-plugin-support": "3.8.0-next.13",
73
73
  "@webex/internal-plugin-user": "3.8.0-next.11",
74
- "@webex/internal-plugin-voicea": "3.8.0-next.31",
74
+ "@webex/internal-plugin-voicea": "3.8.0-next.32",
75
75
  "@webex/media-helpers": "3.8.0-next.12",
76
76
  "@webex/plugin-people": "3.8.0-next.13",
77
77
  "@webex/plugin-rooms": "3.8.0-next.13",
@@ -92,5 +92,5 @@
92
92
  "//": [
93
93
  "TODO: upgrade jwt-decode when moving to node 18"
94
94
  ],
95
- "version": "3.8.0-next.31"
95
+ "version": "3.8.0-next.32"
96
96
  }
@@ -3799,7 +3799,13 @@ export default class Meeting extends StatelessWebexPlugin {
3799
3799
  return Promise.reject(error);
3800
3800
  }
3801
3801
 
3802
- return this.brbState.enable(enabled, this.sendSlotManager);
3802
+ return this.brbState.enable(enabled, this.sendSlotManager).then(() => {
3803
+ if (this.audio && enabled) {
3804
+ // locus mutes the participant with brb enabled request,
3805
+ // so we need to explicitly update remote mute for correct logic flow
3806
+ this.audio.handleServerRemoteMuteUpdate(this, enabled);
3807
+ }
3808
+ });
3803
3809
  }
3804
3810
 
3805
3811
  /**
@@ -147,7 +147,6 @@ export class MuteState {
147
147
  * @public
148
148
  * @memberof MuteState
149
149
  * @param {Object} [meeting] the meeting object
150
- * @param {Boolean} [mute] true for muting, false for unmuting request
151
150
  * @returns {void}
152
151
  */
153
152
  public handleLocalStreamMuteStateChange(meeting?: any) {
@@ -350,7 +349,6 @@ export class MuteState {
350
349
  * @param {Meeting} meeting
351
350
  * @returns {void}
352
351
  */
353
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
354
352
  private applyUnmuteAllowedToStream(meeting: any) {
355
353
  if (this.type === AUDIO) {
356
354
  meeting.mediaProperties.audioStream?.setUnmuteAllowed(this.state.server.unmuteAllowed);
@@ -3887,6 +3887,22 @@ describe('plugin-meetings', () => {
3887
3887
  assert.isRejected((Promise.reject()));
3888
3888
  }
3889
3889
  });
3890
+
3891
+ it('updates remote mute state when brb is enabled', async () => {
3892
+ meeting.audio = { handleServerRemoteMuteUpdate: sinon.stub() };
3893
+
3894
+ await meeting.beRightBack(true);
3895
+
3896
+ sinon.assert.calledOnceWithExactly(meeting.audio.handleServerRemoteMuteUpdate, meeting, true);
3897
+ });
3898
+
3899
+ it('does not update remote mute state when brb is disabled', async () => {
3900
+ meeting.audio = { handleServerRemoteMuteUpdate: sinon.stub() };
3901
+
3902
+ await meeting.beRightBack(false);
3903
+
3904
+ assert.notCalled(meeting.audio.handleServerRemoteMuteUpdate);
3905
+ });
3890
3906
  });
3891
3907
  });
3892
3908
 
@@ -7522,19 +7538,19 @@ describe('plugin-meetings', () => {
7522
7538
  });
7523
7539
  });
7524
7540
 
7525
- describe('#setIsoLocalClientMeetingJoinTime', () => {
7541
+ describe('#setIsoLocalClientMeetingJoinTime', () => {
7526
7542
  it('should fallback to system clock ISO string when given an undefined value', () => {
7527
7543
  const currentSystemTime = new Date().toISOString();
7528
7544
  meeting.isoLocalClientMeetingJoinTime = undefined;
7529
7545
  assert.equal(meeting.isoLocalClientMeetingJoinTime, currentSystemTime);
7530
7546
  });
7531
-
7547
+
7532
7548
  it('should fallback to system clock ISO string when given an invalid value', () => {
7533
7549
  const currentSystemTime = new Date().toISOString();
7534
7550
  meeting.isoLocalClientMeetingJoinTime = 'invalid-date';
7535
7551
  assert.equal(meeting.isoLocalClientMeetingJoinTime, currentSystemTime);
7536
7552
  });
7537
-
7553
+
7538
7554
  it('should set the isoLocalClientMeetingJoinTime correctly for a valid date string', () => {
7539
7555
  const validDateString = 'Tue, 01 Apr 2025 13:00:36 GMT';
7540
7556
  const expectedISOString = new Date(validDateString).toISOString();
@@ -8694,7 +8710,7 @@ describe('plugin-meetings', () => {
8694
8710
  meeting.deferSDPAnswer = {
8695
8711
  reject: sinon.stub(),
8696
8712
  };
8697
-
8713
+
8698
8714
  const clearTimeoutSpy = sinon.spy(clock, 'clearTimeout');
8699
8715
 
8700
8716
  const fakeError = new Errors.SdpAnswerHandlingError(fakeErrorMessage, {
@@ -2,7 +2,6 @@ import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
4
4
  import {createMuteState, MuteState} from '@webex/plugin-meetings/src/meeting/muteState';
5
- import PermissionError from '@webex/plugin-meetings/src/common/errors/permission';
6
5
  import {AUDIO, VIDEO} from '@webex/plugin-meetings/src/constants';
7
6
 
8
7
  import testUtils from '../../../utils/testUtils';
@@ -39,7 +38,6 @@ describe('plugin-meetings', () => {
39
38
  unmuteAllowed: true,
40
39
  remoteVideoMuted: false,
41
40
  unmuteVideoAllowed: true,
42
-
43
41
  locusInfo: {
44
42
  handleLocusDelta: sinon.stub(),
45
43
  },