From ff6cba8d5306a6ccd8bb84bd529505e2a2ac47b7 Mon Sep 17 00:00:00 2001 From: Mario Jr <mariogasparoni@gmail.com> Date: Sat, 6 Mar 2021 22:09:43 -0300 Subject: [PATCH] Store information about user status during breakout room audio transfer Currently this information is lost everytime breakout-room component is unmounted, causing the panel to shows wrong information during next renders Fixes #11333 --- .../audio/audio-controls/container.jsx | 7 +++- .../imports/ui/components/audio/service.js | 10 ++--- .../ui/components/breakout-room/component.jsx | 32 ++++++++++++---- .../ui/components/breakout-room/container.jsx | 8 +++- .../ui/services/audio-manager/index.js | 38 ++++++++++++++++--- 5 files changed, 74 insertions(+), 21 deletions(-) diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx index c59170c9ce..f179c49584 100755 --- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/container.jsx @@ -55,8 +55,11 @@ const { } = Service; export default lockContextContainer(withModalMounter(withTracker(({ mountModal, userLocks }) => { - if (Service.isReturningFromBreakoutAudioTransfer()) { - Service.setReturningFromBreakoutAudioTransfer(false); + const { status } = Service.getBreakoutAudioTransferStatus(); + + if (status === AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.RETURNING) { + Service.setBreakoutAudioTransferStatus(null, + AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.DISCONNECTED); Service.recoverMicState(); } diff --git a/bigbluebutton-html5/imports/ui/components/audio/service.js b/bigbluebutton-html5/imports/ui/components/audio/service.js index 6d55831504..5bc9b9a977 100755 --- a/bigbluebutton-html5/imports/ui/components/audio/service.js +++ b/bigbluebutton-html5/imports/ui/components/audio/service.js @@ -125,10 +125,10 @@ export default { updateAudioConstraints: constraints => AudioManager.updateAudioConstraints(constraints), recoverMicState, - setReturningFromBreakoutAudioTransfer: (value) => { - AudioManager.returningFromBreakoutAudioTransfer = value; - }, - isReturningFromBreakoutAudioTransfer: - () => AudioManager.returningFromBreakoutAudioTransfer, isReconnecting: () => AudioManager.isReconnecting, + setBreakoutAudioTransferStatus: + (breakoutId, status) => AudioManager + .setBreakoutAudioTransferStatus(breakoutId, status), + getBreakoutAudioTransferStatus: () => AudioManager + .getBreakoutAudioTransferStatus(), }; diff --git a/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx b/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx index bdb8898a57..c77e05d398 100644 --- a/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/breakout-room/component.jsx @@ -6,6 +6,7 @@ import { Session } from 'meteor/session'; import logger from '/imports/startup/client/logger'; import { styles } from './styles'; import BreakoutRoomContainer from './breakout-remaining-time/container'; +import AudioManager from '/imports/ui/services/audio-manager'; const intlMessages = defineMessages({ breakoutTitle: { @@ -101,6 +102,7 @@ class BreakoutRoom extends PureComponent { breakoutRoomUser, breakoutRooms, closeBreakoutPanel, + setBreakoutAudioTransferStatus, isMicrophoneUser, isReconnecting, } = this.props; @@ -125,6 +127,8 @@ class BreakoutRoom extends PureComponent { if (joinedAudioOnly && (!isMicrophoneUser || isReconnecting)) { this.clearJoinedAudioOnly(); + setBreakoutAudioTransferStatus('', + AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.DISCONNECTED); } } @@ -173,21 +177,32 @@ class BreakoutRoom extends PureComponent { intl, isUserInBreakoutRoom, exitAudio, - setReturningFromBreakoutAudioTransfer, + setBreakoutAudioTransferStatus, + getBreakoutAudioTransferStatus, } = this.props; const { joinedAudioOnly, - breakoutId: stateBreakoutId, + breakoutId: _stateBreakoutId, requestedBreakoutId, waiting, } = this.state; + const { + breakoutMeetingId: currentAudioTransferBreakoutId, + status, + } = getBreakoutAudioTransferStatus(); + + const isInBreakoutAudioTransfer = status + === AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.CONNECTED; + + const stateBreakoutId = _stateBreakoutId || currentAudioTransferBreakoutId; const moderatorJoinedAudio = isMicrophoneUser && amIModerator; const disable = waiting && requestedBreakoutId !== breakoutId; - const audioAction = joinedAudioOnly + const audioAction = joinedAudioOnly || isInBreakoutAudioTransfer ? () => { - setReturningFromBreakoutAudioTransfer(true); + setBreakoutAudioTransferStatus(breakoutId, + AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.RETURNING); this.returnBackToMeeeting(breakoutId); return logger.debug({ logCode: 'breakoutroom_return_main_audio', @@ -195,6 +210,8 @@ class BreakoutRoom extends PureComponent { }, 'Returning to main audio (breakout room audio closed)'); } : () => { + setBreakoutAudioTransferStatus(breakoutId, + AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.CONNECTED); this.transferUserToBreakoutRoom(breakoutId); return logger.debug({ logCode: 'breakoutroom_join_audio_from_main_room', @@ -234,9 +251,10 @@ class BreakoutRoom extends PureComponent { ( <Button label={ - stateBreakoutId === breakoutId && joinedAudioOnly - ? intl.formatMessage(intlMessages.breakoutReturnAudio) - : intl.formatMessage(intlMessages.breakoutJoinAudio) + stateBreakoutId === breakoutId + && (joinedAudioOnly || isInBreakoutAudioTransfer) + ? intl.formatMessage(intlMessages.breakoutReturnAudio) + : intl.formatMessage(intlMessages.breakoutJoinAudio) } className={styles.button} disabled={stateBreakoutId !== breakoutId && joinedAudioOnly} diff --git a/bigbluebutton-html5/imports/ui/components/breakout-room/container.jsx b/bigbluebutton-html5/imports/ui/components/breakout-room/container.jsx index f092a239a7..d4f1e30915 100644 --- a/bigbluebutton-html5/imports/ui/components/breakout-room/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/breakout-room/container.jsx @@ -26,7 +26,10 @@ export default withTracker((props) => { const isMicrophoneUser = AudioService.isConnected() && !AudioService.isListenOnly(); const isMeteorConnected = Meteor.status().connected; const isReconnecting = AudioService.isReconnecting(); - const { setReturningFromBreakoutAudioTransfer } = AudioService; + const { + setBreakoutAudioTransferStatus, + getBreakoutAudioTransferStatus, + } = AudioService; return { ...props, @@ -43,7 +46,8 @@ export default withTracker((props) => { isMeteorConnected, isUserInBreakoutRoom, exitAudio: () => AudioManager.exitAudio(), - setReturningFromBreakoutAudioTransfer, isReconnecting, + setBreakoutAudioTransferStatus, + getBreakoutAudioTransferStatus, }; })(BreakoutContainer); diff --git a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js index 23c2b4e8bd..91042209a7 100755 --- a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js +++ b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js @@ -30,6 +30,12 @@ const CALL_STATES = { AUTOPLAY_BLOCKED: 'autoplayBlocked', }; +const BREAKOUT_AUDIO_TRANSFER_STATES = { + CONNECTED: 'connected', + DISCONNECTED: 'disconnected', + RETURNING: 'returning', +}; + class AudioManager { constructor() { this._inputDevice = { @@ -37,7 +43,10 @@ class AudioManager { tracker: new Tracker.Dependency(), }; - this._returningFromBreakoutAudioTransfer = false; + this._breakoutAudioTransferStatus = { + status: BREAKOUT_AUDIO_TRANSFER_STATES.DISCONNECTED, + breakoutMeetingId: null, + }; this.defineProperties({ isMuted: false, @@ -59,6 +68,8 @@ class AudioManager { this.failedMediaElements = []; this.handlePlayElementFailed = this.handlePlayElementFailed.bind(this); this.monitor = this.monitor.bind(this); + + this.BREAKOUT_AUDIO_TRANSFER_STATES = BREAKOUT_AUDIO_TRANSFER_STATES; } init(userData, audioEventHandler) { @@ -534,12 +545,29 @@ class AudioManager { ? this.bridge.inputDeviceId : DEFAULT_INPUT_DEVICE_ID; } - get returningFromBreakoutAudioTransfer() { - return this._returningFromBreakoutAudioTransfer; + /** + * Sets the current status for breakout audio transfer + * @param {String} breakoutMeetingId The id of the current breakout + * audio transfer. + * @param {String} status The status to be set for + * audio transfer. Valid values + * are 'connected', 'disconnected' + * and 'returning' + */ + setBreakoutAudioTransferStatus(breakoutMeetingId, status) { + const data = this._breakoutAudioTransferStatus; + + if (typeof breakoutMeetingId === 'string') { + data.breakoutMeetingId = breakoutMeetingId; + } + + if (typeof status === 'string') { + data.status = status; + } } - set returningFromBreakoutAudioTransfer(value) { - this._returningFromBreakoutAudioTransfer = value; + getBreakoutAudioTransferStatus() { + return this._breakoutAudioTransferStatus; } set userData(value) { -- GitLab