diff --git a/lang/main.json b/lang/main.json index c0f200ba1..515c4a2f4 100644 --- a/lang/main.json +++ b/lang/main.json @@ -216,6 +216,7 @@ "kickParticipantTitle": "Kick this participant?", "kickTitle": "Ouch! {{participantDisplayName}} kicked you out of the meeting", "liveStreaming": "Live Streaming", + "liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Not possible while recording is active", "liveStreamingDisabledForGuestTooltip": "Guests can't start live streaming.", "liveStreamingDisabledTooltip": "Start live stream disabled.", "lockMessage": "Failed to lock the conference.", @@ -249,6 +250,7 @@ "popupError": "Your browser is blocking pop-up windows from this site. Please enable pop-ups in your browser's security settings and try again.", "popupErrorTitle": "Pop-up blocked", "recording": "Recording", + "recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Not possible while a live stream is active", "recordingDisabledForGuestTooltip": "Guests can't start recordings.", "recordingDisabledTooltip": "Start recording disabled.", "rejoinNow": "Rejoin now", diff --git a/react/features/recording/components/LiveStream/AbstractLiveStreamButton.js b/react/features/recording/components/LiveStream/AbstractLiveStreamButton.js index efe9604c6..1877e561c 100644 --- a/react/features/recording/components/LiveStream/AbstractLiveStreamButton.js +++ b/react/features/recording/components/LiveStream/AbstractLiveStreamButton.js @@ -25,6 +25,11 @@ export type Props = AbstractButtonProps & { */ _isLiveStreamRunning: boolean, + /** + * True if the button needs to be disabled. + */ + _disabled: Boolean, + /** * The redux {@code dispatch} function. */ @@ -80,6 +85,7 @@ export default class AbstractLiveStreamButton * @param {Props} ownProps - The own props of the Component. * @private * @returns {{ + * _disabled: boolean, * _isLiveStreamRunning: boolean, * visible: boolean * }} @@ -87,9 +93,9 @@ export default class AbstractLiveStreamButton export function _mapStateToProps(state: Object, ownProps: Props) { let { visible } = ownProps; - // a button can be disabled/enabled only if enableFeaturesBasedOnToken - // is on - let disabledByFeatures; + // A button can be disabled/enabled only if enableFeaturesBasedOnToken + // is on or if the recording is running. + let _disabled; if (typeof visible === 'undefined') { // If the containing component provides the visible prop, that is one @@ -105,14 +111,19 @@ export function _mapStateToProps(state: Object, ownProps: Props) { if (enableFeaturesBasedOnToken) { visible = visible && String(features.livestreaming) === 'true'; - disabledByFeatures = String(features.livestreaming) === 'disabled'; + _disabled = String(features.livestreaming) === 'disabled'; } } + // disable the button if the recording is running. + if (getActiveSession(state, JitsiRecordingConstants.mode.FILE)) { + _disabled = true; + } + return { + _disabled, _isLiveStreamRunning: Boolean( getActiveSession(state, JitsiRecordingConstants.mode.STREAM)), - disabledByFeatures, visible }; } diff --git a/react/features/recording/components/LiveStream/web/LiveStreamButton.js b/react/features/recording/components/LiveStream/web/LiveStreamButton.js index 6d780a386..2b336c993 100644 --- a/react/features/recording/components/LiveStream/web/LiveStreamButton.js +++ b/react/features/recording/components/LiveStream/web/LiveStreamButton.js @@ -74,12 +74,10 @@ function _mapStateToProps(state: Object, ownProps: Props) { const abstractProps = _abstractMapStateToProps(state, ownProps); let { visible } = ownProps; - const _disabledByFeatures = abstractProps.disabledByFeatures; - let _disabled = false; + let { _disabled } = abstractProps; let _liveStreamDisabledTooltipKey; - if (!abstractProps.visible - && _disabledByFeatures !== undefined && !_disabledByFeatures) { + if (!abstractProps.visible && _disabled !== undefined && !_disabled) { _disabled = true; // button and tooltip @@ -90,12 +88,15 @@ function _mapStateToProps(state: Object, ownProps: Props) { _liveStreamDisabledTooltipKey = 'dialog.liveStreamingDisabledTooltip'; } + } else if (_disabled) { + _liveStreamDisabledTooltipKey = 'dialog.liveStreamingDisabledBecauseOfActiveRecordingTooltip'; + } else { + _disabled = false; } if (typeof visible === 'undefined') { visible = interfaceConfig.TOOLBAR_BUTTONS.includes('livestreaming') - && (abstractProps.visible - || Boolean(_liveStreamDisabledTooltipKey)); + && (abstractProps.visible || Boolean(_liveStreamDisabledTooltipKey)); } return { diff --git a/react/features/recording/components/Recording/AbstractRecordButton.js b/react/features/recording/components/Recording/AbstractRecordButton.js index 716873be6..da03c990c 100644 --- a/react/features/recording/components/Recording/AbstractRecordButton.js +++ b/react/features/recording/components/Recording/AbstractRecordButton.js @@ -24,6 +24,11 @@ import { StartRecordingDialog, StopRecordingDialog } from './_'; */ export type Props = AbstractButtonProps & { + /** + * True if the button needs to be disabled. + */ + _disabled: Boolean, + /** * True if there is a running active recording, false otherwise. */ @@ -103,17 +108,17 @@ export default class AbstractRecordButton * @param {Props} ownProps - The own props of the Component. * @private * @returns {{ + * _disabled: boolean, * _isRecordingRunning: boolean, - * disabledByFeatures: boolean, * visible: boolean * }} */ export function _mapStateToProps(state: Object, ownProps: Props): Object { let { visible } = ownProps; - // a button can be disabled/enabled only if enableFeaturesBasedOnToken - // is on - let disabledByFeatures; + // a button can be disabled/enabled if enableFeaturesBasedOnToken + // is on or if the livestreaming is running. + let _disabled; if (typeof visible === 'undefined') { // If the containing component provides the visible prop, that is one @@ -126,19 +131,22 @@ export function _mapStateToProps(state: Object, ownProps: Props): Object { } = state['features/base/config']; const { features = {} } = getLocalParticipant(state); - visible = isModerator - && fileRecordingsEnabled; + visible = isModerator && fileRecordingsEnabled; if (enableFeaturesBasedOnToken) { visible = visible && String(features.recording) === 'true'; - disabledByFeatures = String(features.recording) === 'disabled'; + _disabled = String(features.recording) === 'disabled'; } } + // disable the button if the livestreaming is running. + if (getActiveSession(state, JitsiRecordingConstants.mode.STREAM)) { + _disabled = true; + } + return { - _isRecordingRunning: - Boolean(getActiveSession(state, JitsiRecordingConstants.mode.FILE)), - disabledByFeatures, + _disabled, + _isRecordingRunning: Boolean(getActiveSession(state, JitsiRecordingConstants.mode.FILE)), visible }; } diff --git a/react/features/recording/components/Recording/web/RecordButton.js b/react/features/recording/components/Recording/web/RecordButton.js index a184957b2..45b3878fc 100644 --- a/react/features/recording/components/Recording/web/RecordButton.js +++ b/react/features/recording/components/Recording/web/RecordButton.js @@ -40,7 +40,7 @@ class RecordButton extends AbstractRecordButton { * @returns {string} */ _getTooltip() { - return this.tooltip || ''; + return this.props._fileRecordingsDisabledTooltipKey || ''; } /** @@ -74,28 +74,27 @@ export function _mapStateToProps(state: Object, ownProps: Props): Object { const abstractProps = _abstractMapStateToProps(state, ownProps); let { visible } = ownProps; - const _disabledByFeatures = abstractProps.disabledByFeatures; - let _disabled = false; + let { _disabled } = abstractProps; let _fileRecordingsDisabledTooltipKey; - if (!abstractProps.visible - && _disabledByFeatures !== undefined && !_disabledByFeatures) { + if (!abstractProps.visible && _disabled !== undefined && !_disabled) { _disabled = true; // button and tooltip if (state['features/base/jwt'].isGuest) { - _fileRecordingsDisabledTooltipKey - = 'dialog.recordingDisabledForGuestTooltip'; + _fileRecordingsDisabledTooltipKey = 'dialog.recordingDisabledForGuestTooltip'; } else { - _fileRecordingsDisabledTooltipKey - = 'dialog.recordingDisabledTooltip'; + _fileRecordingsDisabledTooltipKey = 'dialog.recordingDisabledTooltip'; } + } else if (_disabled) { + _fileRecordingsDisabledTooltipKey = 'dialog.recordingDisabledBecauseOfActiveLiveStreamingTooltip'; + } else { + _disabled = false; } if (typeof visible === 'undefined') { visible = interfaceConfig.TOOLBAR_BUTTONS.includes('recording') - && (abstractProps.visible - || Boolean(_fileRecordingsDisabledTooltipKey)); + && (abstractProps.visible || Boolean(_fileRecordingsDisabledTooltipKey)); } return {