rn,flags: add more feature flags to toggle specific behavior
- Invite funcionality (altogether) - Recording - Live streaming - Meeting name - Meeting password
This commit is contained in:
parent
c41047344f
commit
e5b563ba46
|
@ -1,5 +1,11 @@
|
|||
// @flow
|
||||
|
||||
/**
|
||||
* Flag indicating if add-people functionality should be enabled.
|
||||
* Default: enabled (true).
|
||||
*/
|
||||
export const ADD_PEOPLE_ENABLED = 'add-people.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if calendar integration should be enabled.
|
||||
* Default: enabled (true) on Android, auto-detected on iOS.
|
||||
|
@ -37,12 +43,38 @@ export const INVITE_ENABLED = 'invite.enabled';
|
|||
*/
|
||||
export const IOS_RECORDING_ENABLED = 'ios.recording.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if live-streaming should be enabled.
|
||||
* Default: auto-detected.
|
||||
*/
|
||||
export const LIVE_STREAMING_ENABLED = 'live-streaming.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if displaying the meeting name should be enabled.
|
||||
* Default: enabled (true).
|
||||
*/
|
||||
export const MEETING_NAME_ENABLED = 'meeting-name.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if the meeting password button should be enabled.
|
||||
* Note that this flag just decides on the buttton, if a meeting has a password
|
||||
* set, the password ddialog will still show up.
|
||||
* Default: enabled (true).
|
||||
*/
|
||||
export const MEETING_PASSWORD_ENABLED = 'meeting-password.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if Picture-in-Picture should be enabled.
|
||||
* Default: auto-detected.
|
||||
*/
|
||||
export const PIP_ENABLED = 'pip.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if recording should be enabled.
|
||||
* Default: auto-detected.
|
||||
*/
|
||||
export const RECORDING_ENABLED = 'recording.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if the welcome page should be enabled.
|
||||
* Default: disabled (false).
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { CHAT_ENABLED, getFeatureFlag } from '../../../base/flags';
|
||||
import { IconChat, IconChatUnread } from '../../../base/icons';
|
||||
import { setActiveModalId } from '../../../base/modal';
|
||||
import { getLocalParticipant } from '../../../base/participants';
|
||||
|
@ -114,16 +115,18 @@ function _mapDispatchToProps(dispatch: Function) {
|
|||
* Maps part of the redux state to the component's props.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _unreadMessageCount
|
||||
* }}
|
||||
* @param {Object} ownProps - The properties explicitly passed to the component instance.
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
function _mapStateToProps(state, ownProps) {
|
||||
const localParticipant = getLocalParticipant(state);
|
||||
const enabled = getFeatureFlag(state, CHAT_ENABLED, true);
|
||||
const { visible = enabled } = ownProps;
|
||||
|
||||
return {
|
||||
_showNamePrompt: !localParticipant.name,
|
||||
_unreadMessageCount: getUnreadCount(state)
|
||||
_unreadMessageCount: getUnreadCount(state),
|
||||
visible
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@ import React, { PureComponent } from 'react';
|
|||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { getFeatureFlag, INVITE_ENABLED } from '../../../base/flags';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { getParticipantCount } from '../../../base/participants';
|
||||
import { doInvitePeople } from '../../../invite/actions.native';
|
||||
|
||||
|
@ -125,9 +126,10 @@ class LonelyMeetingExperience extends PureComponent<Props> {
|
|||
*/
|
||||
function _mapStateToProps(state): $Shape<Props> {
|
||||
const { disableInviteFunctions } = state['features/base/config'];
|
||||
const flag = getFeatureFlag(state, INVITE_ENABLED, true);
|
||||
|
||||
return {
|
||||
_isInviteFunctionsDiabled: disableInviteFunctions,
|
||||
_isInviteFunctionsDiabled: !flag || disableInviteFunctions,
|
||||
_isLonelyMeeting: getParticipantCount(state) === 1,
|
||||
_styles: ColorSchemeRegistry.get(state, 'Conference')
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import { SafeAreaView, Text, View } from 'react-native';
|
|||
import LinearGradient from 'react-native-linear-gradient';
|
||||
|
||||
import { getConferenceName } from '../../../base/conference';
|
||||
import { getFeatureFlag, MEETING_NAME_ENABLED } from '../../../base/flags';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { PictureInPictureButton } from '../../../mobile/picture-in-picture';
|
||||
import { isToolboxVisible } from '../../../toolbox';
|
||||
|
@ -19,6 +20,11 @@ type Props = {
|
|||
*/
|
||||
_meetingName: string,
|
||||
|
||||
/**
|
||||
* Whether displaying the current meeting name is enabled or not.
|
||||
*/
|
||||
_meetingNameEnabled: boolean,
|
||||
|
||||
/**
|
||||
* True if the navigation bar should be visible.
|
||||
*/
|
||||
|
@ -59,11 +65,14 @@ class NavigationBar extends Component<Props> {
|
|||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.roomNameWrapper }>
|
||||
<Text
|
||||
numberOfLines = { 1 }
|
||||
style = { styles.roomName }>
|
||||
{ this.props._meetingName }
|
||||
</Text>
|
||||
{
|
||||
this.props._meetingNameEnabled
|
||||
&& <Text
|
||||
numberOfLines = { 1 }
|
||||
style = { styles.roomName }>
|
||||
{ this.props._meetingName }
|
||||
</Text>
|
||||
}
|
||||
<ConferenceTimer />
|
||||
</View>
|
||||
</View>
|
||||
|
@ -76,14 +85,12 @@ class NavigationBar extends Component<Props> {
|
|||
* Maps part of the Redux store to the props of this component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @returns {{
|
||||
* _meetingName: string,
|
||||
* _visible: boolean
|
||||
* }}
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_meetingName: getConferenceName(state),
|
||||
_meetingNameEnabled: getFeatureFlag(state, MEETING_NAME_ENABLED, true),
|
||||
_visible: isToolboxVisible(state)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { getFeatureFlag, INVITE_ENABLED } from '../base/flags';
|
||||
import { getFeatureFlag, ADD_PEOPLE_ENABLED } from '../base/flags';
|
||||
import { setActiveModalId } from '../base/modal';
|
||||
import { beginShareRoom } from '../share-room';
|
||||
|
||||
|
@ -20,7 +20,7 @@ export * from './actions.any';
|
|||
export function doInvitePeople() {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
const state = getState();
|
||||
const addPeopleEnabled = getFeatureFlag(state, INVITE_ENABLED, true)
|
||||
const addPeopleEnabled = getFeatureFlag(state, ADD_PEOPLE_ENABLED, true)
|
||||
&& (isAddPeopleEnabled(state) || isDialOutEnabled(state));
|
||||
|
||||
if (addPeopleEnabled) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { getFeatureFlag, INVITE_ENABLED } from '../../../../base/flags';
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { IconAddPeople } from '../../../../base/icons';
|
||||
import { connect } from '../../../../base/redux';
|
||||
|
@ -47,9 +48,10 @@ class InviteButton extends AbstractButton<Props, *> {
|
|||
*/
|
||||
function _mapStateToProps(state, ownProps: Props) {
|
||||
const { disableInviteFunctions } = state['features/base/config'];
|
||||
const flag = getFeatureFlag(state, INVITE_ENABLED, true);
|
||||
|
||||
return {
|
||||
visible: !disableInviteFunctions && ownProps.visible
|
||||
visible: flag && !disableInviteFunctions && ownProps.visible
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
import { translate } from '../../../../base/i18n';
|
||||
import { IconLiveStreaming } from '../../../../base/icons';
|
||||
import { LIVE_STREAMING_ENABLED, getFeatureFlag } from '../../../../base/flags';
|
||||
import { connect } from '../../../../base/redux';
|
||||
|
||||
import AbstractLiveStreamButton, {
|
||||
_mapStateToProps,
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props
|
||||
} from '../AbstractLiveStreamButton';
|
||||
|
||||
|
@ -16,4 +17,23 @@ class LiveStreamButton extends AbstractLiveStreamButton<Props> {
|
|||
icon = IconLiveStreaming;
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(LiveStreamButton));
|
||||
/**
|
||||
* Maps (parts of) the redux state to the associated props for this component.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @param {Object} ownProps - The properties explicitly passed to the component
|
||||
* instance.
|
||||
* @private
|
||||
* @returns {Props}
|
||||
*/
|
||||
export function mapStateToProps(state: Object, ownProps: Object) {
|
||||
const enabled = getFeatureFlag(state, LIVE_STREAMING_ENABLED, true);
|
||||
const abstractProps = _abstractMapStateToProps(state, ownProps);
|
||||
|
||||
return {
|
||||
...abstractProps,
|
||||
visible: enabled && abstractProps.visible
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(mapStateToProps)(LiveStreamButton));
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// @flow
|
||||
|
||||
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,
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props
|
||||
} from '../AbstractRecordButton';
|
||||
|
||||
|
@ -16,4 +19,24 @@ class RecordButton extends AbstractRecordButton<Props> {
|
|||
icon = IconToggleRecording;
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(RecordButton));
|
||||
/**
|
||||
* Maps (parts of) the redux state to the associated props for this component.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @param {Object} ownProps - The properties explicitly passed to the component
|
||||
* instance.
|
||||
* @private
|
||||
* @returns {Props}
|
||||
*/
|
||||
export function mapStateToProps(state: Object, ownProps: Object) {
|
||||
const enabled = getFeatureFlag(state, RECORDING_ENABLED, true);
|
||||
const iosEnabled = Platform.OS !== 'ios' || getFeatureFlag(state, IOS_RECORDING_ENABLED, false);
|
||||
const abstractProps = _abstractMapStateToProps(state, ownProps);
|
||||
|
||||
return {
|
||||
...abstractProps,
|
||||
visible: enabled && iosEnabled && abstractProps.visible
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(mapStateToProps)(RecordButton));
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
|
||||
import { MEETING_PASSWORD_ENABLED, getFeatureFlag } from '../../base/flags';
|
||||
import { translate } from '../../base/i18n';
|
||||
import { IconRoomLock, IconRoomUnlock } from '../../base/icons';
|
||||
import { isLocalParticipantModerator } from '../../base/participants';
|
||||
|
@ -83,19 +84,19 @@ class RoomLockButton extends AbstractButton<Props, *> {
|
|||
* {@code RoomLockButton} component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @param {Object} ownProps - The properties explicitly passed to the component instance.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _localParticipantModerator: boolean,
|
||||
* _locked: boolean
|
||||
* }}
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state): Object {
|
||||
function _mapStateToProps(state, ownProps): Object {
|
||||
const { conference, locked } = state['features/base/conference'];
|
||||
const enabled = getFeatureFlag(state, MEETING_PASSWORD_ENABLED, true);
|
||||
const { visible = enabled } = ownProps;
|
||||
|
||||
return {
|
||||
_localParticipantModerator:
|
||||
Boolean(conference && isLocalParticipantModerator(state)),
|
||||
_locked: Boolean(conference && locked)
|
||||
_localParticipantModerator: Boolean(conference && isLocalParticipantModerator(state)),
|
||||
_locked: Boolean(conference && locked),
|
||||
visible
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Platform, TouchableOpacity, View } from 'react-native';
|
||||
import { TouchableOpacity, View } from 'react-native';
|
||||
import Collapsible from 'react-native-collapsible';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { BottomSheet, hideDialog, isDialogOpen } from '../../../base/dialog';
|
||||
import { IOS_RECORDING_ENABLED, getFeatureFlag } from '../../../base/flags';
|
||||
import { IconDragHandle } from '../../../base/icons';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
|
@ -134,10 +133,7 @@ class OverflowMenu extends PureComponent<Props, State> {
|
|||
<Collapsible collapsed = { !showMore }>
|
||||
<ToggleCameraButton { ...buttonProps } />
|
||||
<TileViewButton { ...buttonProps } />
|
||||
{
|
||||
this.props._recordingEnabled
|
||||
&& <RecordButton { ...buttonProps } />
|
||||
}
|
||||
<RecordButton { ...buttonProps } />
|
||||
<LiveStreamButton { ...buttonProps } />
|
||||
<RoomLockButton { ...buttonProps } />
|
||||
<ClosedCaptionButton { ...buttonProps } />
|
||||
|
@ -240,8 +236,7 @@ class OverflowMenu extends PureComponent<Props, State> {
|
|||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_bottomSheetStyles: ColorSchemeRegistry.get(state, 'BottomSheet'),
|
||||
_isOpen: isDialogOpen(state, OverflowMenu_),
|
||||
_recordingEnabled: Platform.OS !== 'ios' || getFeatureFlag(state, IOS_RECORDING_ENABLED)
|
||||
_isOpen: isDialogOpen(state, OverflowMenu_)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,10 @@ import React, { PureComponent } from 'react';
|
|||
import { View } from 'react-native';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { CHAT_ENABLED, getFeatureFlag } from '../../../base/flags';
|
||||
import { Container } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import { ChatButton } from '../../../chat';
|
||||
import { InviteButton } from '../../../invite';
|
||||
|
||||
import { isToolboxVisible } from '../../functions';
|
||||
|
||||
|
@ -25,11 +23,6 @@ import VideoMuteButton from '../VideoMuteButton';
|
|||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Whether the chat feature has been enabled. The meeting info button will be displayed in its place when disabled.
|
||||
*/
|
||||
_chatEnabled: boolean,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of the feature.
|
||||
*/
|
||||
|
@ -105,7 +98,7 @@ class Toolbox extends PureComponent<Props> {
|
|||
* @returns {React$Node}
|
||||
*/
|
||||
_renderToolbar() {
|
||||
const { _chatEnabled, _styles } = this.props;
|
||||
const { _styles } = this.props;
|
||||
const { buttonStyles, buttonStylesBorderless, hangupButtonStyles, toggledButtonStyles } = _styles;
|
||||
|
||||
return (
|
||||
|
@ -113,20 +106,9 @@ class Toolbox extends PureComponent<Props> {
|
|||
accessibilityRole = 'toolbar'
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.toolbar }>
|
||||
{
|
||||
_chatEnabled
|
||||
&& <ChatButton
|
||||
styles = { buttonStylesBorderless }
|
||||
toggledStyles = {
|
||||
this._getChatButtonToggledStyle(toggledButtonStyles)
|
||||
} />
|
||||
}
|
||||
{
|
||||
!_chatEnabled
|
||||
&& <InviteButton
|
||||
styles = { buttonStyles }
|
||||
toggledStyles = { toggledButtonStyles } />
|
||||
}
|
||||
<ChatButton
|
||||
styles = { buttonStylesBorderless }
|
||||
toggledStyles = { this._getChatButtonToggledStyle(toggledButtonStyles) } />
|
||||
<AudioMuteButton
|
||||
styles = { buttonStyles }
|
||||
toggledStyles = { toggledButtonStyles } />
|
||||
|
@ -150,15 +132,10 @@ class Toolbox extends PureComponent<Props> {
|
|||
* @param {Object} state - The redux state of which parts are to be mapped to
|
||||
* {@code Toolbox} props.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _chatEnabled: boolean,
|
||||
* _styles: StyleType,
|
||||
* _visible: boolean
|
||||
* }}
|
||||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state: Object): Object {
|
||||
return {
|
||||
_chatEnabled: getFeatureFlag(state, CHAT_ENABLED, true),
|
||||
_styles: ColorSchemeRegistry.get(state, 'Toolbox'),
|
||||
_visible: isToolboxVisible(state)
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue