Skip to content

Commit

Permalink
fix(record):web/mobile match disable functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
hristoterezov committed May 28, 2020
1 parent ce1de9e commit a2c4d17
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 176 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow

import { openDialog } from '../../../base/dialog';
import { IconLiveStreaming } from '../../../base/icons';
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
import { getLocalParticipant } from '../../../base/participants';
import {
Expand Down Expand Up @@ -30,6 +31,11 @@ export type Props = AbstractButtonProps & {
*/
_disabled: Boolean,

/**
* The tooltip to display when hovering over the button.
*/
_tooltip: ?String,

/**
* The redux {@code dispatch} function.
*/
Expand All @@ -44,12 +50,22 @@ export type Props = AbstractButtonProps & {
/**
* An abstract class of a button for starting and stopping live streaming.
*/
export default class AbstractLiveStreamButton<P: Props>
extends AbstractButton<P, *> {
export default class AbstractLiveStreamButton<P: Props> extends AbstractButton<P, *> {
accessibilityLabel = 'dialog.accessibilityLabel.liveStreaming';
icon = IconLiveStreaming;
label = 'dialog.startLiveStreaming';
toggledLabel = 'dialog.stopLiveStreaming';

/**
* Returns the tooltip that should be displayed when the button is disabled.
*
* @private
* @returns {string}
*/
_getTooltip() {
return this.props._tooltip || '';
}

/**
* Handles clicking / pressing the button.
*
Expand All @@ -65,6 +81,16 @@ export default class AbstractLiveStreamButton<P: Props>
));
}

/**
* Returns a boolean value indicating if this button is disabled or not.
*
* @protected
* @returns {boolean}
*/
_isDisabled() {
return this.props._disabled;
}

/**
* Indicates whether this button is in toggled state or not.
*
Expand Down Expand Up @@ -96,6 +122,7 @@ export function _mapStateToProps(state: Object, ownProps: Props) {
// A button can be disabled/enabled only if enableFeaturesBasedOnToken
// is on or if the recording is running.
let _disabled;
let _tooltip = '';

if (typeof visible === 'undefined') {
// If the containing component provides the visible prop, that is one
Expand All @@ -112,18 +139,32 @@ export function _mapStateToProps(state: Object, ownProps: Props) {
if (enableFeaturesBasedOnToken) {
visible = visible && String(features.livestreaming) === 'true';
_disabled = String(features.livestreaming) === 'disabled';

if (!visible && !_disabled) {
_disabled = true;
visible = true;

// button and tooltip
if (state['features/base/jwt'].isGuest) {
_tooltip = 'dialog.liveStreamingDisabledForGuestTooltip';
} else {
_tooltip = 'dialog.liveStreamingDisabledTooltip';
}
}
}
}

// disable the button if the recording is running.
if (getActiveSession(state, JitsiRecordingConstants.mode.FILE)) {
_disabled = true;
_tooltip = 'dialog.liveStreamingDisabledBecauseOfActiveRecordingTooltip';
}

return {
_disabled,
_isLiveStreamRunning: Boolean(
getActiveSession(state, JitsiRecordingConstants.mode.STREAM)),
_tooltip,
visible
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,8 @@

import { LIVE_STREAMING_ENABLED, getFeatureFlag } from '../../../../base/flags';
import { translate } from '../../../../base/i18n';
import { IconLiveStreaming } from '../../../../base/icons';
import { connect } from '../../../../base/redux';
import AbstractLiveStreamButton, {
_mapStateToProps as _abstractMapStateToProps,
type Props
} from '../AbstractLiveStreamButton';

/**
* An implementation of a button for starting and stopping live streaming.
*/
class LiveStreamButton extends AbstractLiveStreamButton<Props> {
icon = IconLiveStreaming;
}
import AbstractLiveStreamButton, { _mapStateToProps as _abstractMapStateToProps } from '../AbstractLiveStreamButton';

/**
* Maps (parts of) the redux state to the associated props for this component.
Expand All @@ -35,4 +24,4 @@ export function mapStateToProps(state: Object, ownProps: Object) {
};
}

export default translate(connect(mapStateToProps)(LiveStreamButton));
export default translate(connect(mapStateToProps)(AbstractLiveStreamButton));
Original file line number Diff line number Diff line change
@@ -1,61 +1,14 @@
// @flow

import { translate } from '../../../../base/i18n';
import { IconLiveStreaming } from '../../../../base/icons';
import { connect } from '../../../../base/redux';
import AbstractLiveStreamButton, {
_mapStateToProps as _abstractMapStateToProps,
type Props as AbstractProps
type Props
} from '../AbstractLiveStreamButton';

declare var interfaceConfig: Object;

type Props = AbstractProps & {

/**
* True if the button should be disabled, false otherwise.
*
* NOTE: On web, if the feature is not disabled on purpose, then we still
* show the button but disabled and with a tooltip rendered on it,
* explaining why it's not available.
*/
_disabled: boolean,

/**
* Tooltip for the button when it's disabled in a certain way.
*/
_liveStreamDisabledTooltipKey: ?string
}

/**
* An implementation of a button for starting and stopping live streaming.
*/
class LiveStreamButton extends AbstractLiveStreamButton<Props> {
icon = IconLiveStreaming;

/**
* Returns the tooltip that should be displayed when the button is disabled.
*
* @private
* @returns {string}
*/
_getTooltip() {
return this.props._liveStreamDisabledTooltipKey || '';
}

/**
* Helper function to be implemented by subclasses, which must return a
* boolean value indicating if this button is disabled or not.
*
* @override
* @protected
* @returns {boolean}
*/
_isDisabled() {
return this.props._disabled;
}
}

/**
* Maps (parts of) the redux state to the associated props for the
* {@code LiveStreamButton} component.
Expand All @@ -74,37 +27,14 @@ function _mapStateToProps(state: Object, ownProps: Props) {
const abstractProps = _abstractMapStateToProps(state, ownProps);
let { visible } = ownProps;

let { _disabled } = abstractProps;
let _liveStreamDisabledTooltipKey;

if (!abstractProps.visible && _disabled !== undefined && !_disabled) {
_disabled = true;

// button and tooltip
if (state['features/base/jwt'].isGuest) {
_liveStreamDisabledTooltipKey
= 'dialog.liveStreamingDisabledForGuestTooltip';
} else {
_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));
visible = interfaceConfig.TOOLBAR_BUTTONS.includes('livestreaming') && abstractProps.visible;
}

return {
...abstractProps,
_disabled,
_liveStreamDisabledTooltipKey,
visible
};
}

export default translate(connect(_mapStateToProps)(LiveStreamButton));
export default translate(connect(_mapStateToProps)(AbstractLiveStreamButton));
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
sendAnalytics
} from '../../../analytics';
import { openDialog } from '../../../base/dialog';
import { IconToggleRecording } from '../../../base/icons';
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
import {
getLocalParticipant,
Expand Down Expand Up @@ -34,6 +35,11 @@ export type Props = AbstractButtonProps & {
*/
_isRecordingRunning: boolean,

/**
* The tooltip to display when hovering over the button.
*/
_tooltip: ?String,

/**
* The redux {@code dispatch} function.
*/
Expand All @@ -48,12 +54,22 @@ export type Props = AbstractButtonProps & {
/**
* An abstract implementation of a button for starting and stopping recording.
*/
export default class AbstractRecordButton<P: Props>
extends AbstractButton<P, *> {
export default class AbstractRecordButton<P: Props> extends AbstractButton<P, *> {
accessibilityLabel = 'toolbar.accessibilityLabel.recording';
icon = IconToggleRecording;
label = 'dialog.startRecording';
toggledLabel = 'dialog.stopRecording';

/**
* Returns the tooltip that should be displayed when the button is disabled.
*
* @private
* @returns {string}
*/
_getTooltip() {
return this.props._tooltip || '';
}

/**
* Handles clicking / pressing the button.
*
Expand Down Expand Up @@ -85,7 +101,7 @@ export default class AbstractRecordButton<P: Props>
* @returns {boolean}
*/
_isDisabled() {
return false;
return this.props._disabled;
}

/**
Expand Down Expand Up @@ -119,6 +135,7 @@ export function _mapStateToProps(state: Object, ownProps: Props): Object {
// a button can be disabled/enabled if enableFeaturesBasedOnToken
// is on or if the livestreaming is running.
let _disabled;
let _tooltip = '';

if (typeof visible === 'undefined') {
// If the containing component provides the visible prop, that is one
Expand All @@ -136,17 +153,30 @@ export function _mapStateToProps(state: Object, ownProps: Props): Object {
if (enableFeaturesBasedOnToken) {
visible = visible && String(features.recording) === 'true';
_disabled = String(features.recording) === 'disabled';
if (!visible && !_disabled) {
_disabled = true;
visible = true;

// button and tooltip
if (state['features/base/jwt'].isGuest) {
_tooltip = 'dialog.recordingDisabledForGuestTooltip';
} else {
_tooltip = 'dialog.recordingDisabledTooltip';
}
}
}
}

// disable the button if the livestreaming is running.
if (getActiveSession(state, JitsiRecordingConstants.mode.STREAM)) {
_disabled = true;
_tooltip = 'dialog.recordingDisabledBecauseOfActiveLiveStreamingTooltip';
}

return {
_disabled,
_isRecordingRunning: Boolean(getActiveSession(state, JitsiRecordingConstants.mode.FILE)),
_tooltip,
visible
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,8 @@ import { Platform } from 'react-native';

import { IOS_RECORDING_ENABLED, RECORDING_ENABLED, getFeatureFlag } from '../../../../base/flags';
import { translate } from '../../../../base/i18n';
import { IconToggleRecording } from '../../../../base/icons';
import { connect } from '../../../../base/redux';
import AbstractRecordButton, {
_mapStateToProps as _abstractMapStateToProps,
type Props
} from '../AbstractRecordButton';

/**
* An implementation of a button for starting and stopping recording.
*/
class RecordButton extends AbstractRecordButton<Props> {
icon = IconToggleRecording;
}
import AbstractRecordButton, { _mapStateToProps as _abstractMapStateToProps } from '../AbstractRecordButton';

/**
* Maps (parts of) the redux state to the associated props for this component.
Expand All @@ -38,4 +27,4 @@ export function mapStateToProps(state: Object, ownProps: Object) {
};
}

export default translate(connect(mapStateToProps)(RecordButton));
export default translate(connect(mapStateToProps)(AbstractRecordButton));
Loading

0 comments on commit a2c4d17

Please sign in to comment.