Przeglądaj źródła

rn,flags: add more feature flags to toggle specific behavior

- Invite funcionality (altogether)
- Recording
- Live streaming
- Meeting name
- Meeting password
master
Saúl Ibarra Corretgé 5 lat temu
rodzic
commit
e5b563ba46

+ 32
- 0
react/features/base/flags/constants.js Wyświetl plik

@@ -1,5 +1,11 @@
1 1
 // @flow
2 2
 
3
+/**
4
+ * Flag indicating if add-people functionality should be enabled.
5
+ * Default: enabled (true).
6
+ */
7
+export const ADD_PEOPLE_ENABLED = 'add-people.enabled';
8
+
3 9
 /**
4 10
  * Flag indicating if calendar integration should be enabled.
5 11
  * Default: enabled (true) on Android, auto-detected on iOS.
@@ -37,12 +43,38 @@ export const INVITE_ENABLED = 'invite.enabled';
37 43
  */
38 44
 export const IOS_RECORDING_ENABLED = 'ios.recording.enabled';
39 45
 
46
+/**
47
+ * Flag indicating if live-streaming should be enabled.
48
+ * Default: auto-detected.
49
+ */
50
+export const LIVE_STREAMING_ENABLED = 'live-streaming.enabled';
51
+
52
+/**
53
+ * Flag indicating if displaying the meeting name should be enabled.
54
+ * Default: enabled (true).
55
+ */
56
+export const MEETING_NAME_ENABLED = 'meeting-name.enabled';
57
+
58
+/**
59
+ * Flag indicating if the meeting password button should be enabled.
60
+ * Note that this flag just decides on the buttton, if a meeting has a password
61
+ * set, the password ddialog will still show up.
62
+ * Default: enabled (true).
63
+ */
64
+export const MEETING_PASSWORD_ENABLED = 'meeting-password.enabled';
65
+
40 66
 /**
41 67
  * Flag indicating if Picture-in-Picture should be enabled.
42 68
  * Default: auto-detected.
43 69
  */
44 70
 export const PIP_ENABLED = 'pip.enabled';
45 71
 
72
+/**
73
+ * Flag indicating if recording should be enabled.
74
+ * Default: auto-detected.
75
+ */
76
+export const RECORDING_ENABLED = 'recording.enabled';
77
+
46 78
 /**
47 79
  * Flag indicating if the welcome page should be enabled.
48 80
  * Default: disabled (false).

+ 8
- 5
react/features/chat/components/native/ChatButton.js Wyświetl plik

@@ -1,5 +1,6 @@
1 1
 // @flow
2 2
 
3
+import { CHAT_ENABLED, getFeatureFlag } from '../../../base/flags';
3 4
 import { IconChat, IconChatUnread } from '../../../base/icons';
4 5
 import { setActiveModalId } from '../../../base/modal';
5 6
 import { getLocalParticipant } from '../../../base/participants';
@@ -114,16 +115,18 @@ function _mapDispatchToProps(dispatch: Function) {
114 115
  * Maps part of the redux state to the component's props.
115 116
  *
116 117
  * @param {Object} state - The Redux state.
117
- * @returns {{
118
- *     _unreadMessageCount
119
- * }}
118
+ * @param {Object} ownProps - The properties explicitly passed to the component instance.
119
+ * @returns {Props}
120 120
  */
121
-function _mapStateToProps(state) {
121
+function _mapStateToProps(state, ownProps) {
122 122
     const localParticipant = getLocalParticipant(state);
123
+    const enabled = getFeatureFlag(state, CHAT_ENABLED, true);
124
+    const { visible = enabled } = ownProps;
123 125
 
124 126
     return {
125 127
         _showNamePrompt: !localParticipant.name,
126
-        _unreadMessageCount: getUnreadCount(state)
128
+        _unreadMessageCount: getUnreadCount(state),
129
+        visible
127 130
     };
128 131
 }
129 132
 

+ 4
- 2
react/features/conference/components/native/LonelyMeetingExperience.js Wyświetl plik

@@ -4,9 +4,10 @@ import React, { PureComponent } from 'react';
4 4
 import { Text, TouchableOpacity, View } from 'react-native';
5 5
 
6 6
 import { ColorSchemeRegistry } from '../../../base/color-scheme';
7
+import { getFeatureFlag, INVITE_ENABLED } from '../../../base/flags';
8
+import { translate } from '../../../base/i18n';
7 9
 import { connect } from '../../../base/redux';
8 10
 import { StyleType } from '../../../base/styles';
9
-import { translate } from '../../../base/i18n';
10 11
 import { getParticipantCount } from '../../../base/participants';
11 12
 import { doInvitePeople } from '../../../invite/actions.native';
12 13
 
@@ -125,9 +126,10 @@ class LonelyMeetingExperience extends PureComponent<Props> {
125 126
  */
126 127
 function _mapStateToProps(state): $Shape<Props> {
127 128
     const { disableInviteFunctions } = state['features/base/config'];
129
+    const flag = getFeatureFlag(state, INVITE_ENABLED, true);
128 130
 
129 131
     return {
130
-        _isInviteFunctionsDiabled: disableInviteFunctions,
132
+        _isInviteFunctionsDiabled: !flag || disableInviteFunctions,
131 133
         _isLonelyMeeting: getParticipantCount(state) === 1,
132 134
         _styles: ColorSchemeRegistry.get(state, 'Conference')
133 135
     };

+ 16
- 9
react/features/conference/components/native/NavigationBar.js Wyświetl plik

@@ -5,6 +5,7 @@ import { SafeAreaView, Text, View } from 'react-native';
5 5
 import LinearGradient from 'react-native-linear-gradient';
6 6
 
7 7
 import { getConferenceName } from '../../../base/conference';
8
+import { getFeatureFlag, MEETING_NAME_ENABLED } from '../../../base/flags';
8 9
 import { connect } from '../../../base/redux';
9 10
 import { PictureInPictureButton } from '../../../mobile/picture-in-picture';
10 11
 import { isToolboxVisible } from '../../../toolbox';
@@ -19,6 +20,11 @@ type Props = {
19 20
      */
20 21
     _meetingName: string,
21 22
 
23
+    /**
24
+     * Whether displaying the current meeting name is enabled or not.
25
+     */
26
+    _meetingNameEnabled: boolean,
27
+
22 28
     /**
23 29
      * True if the navigation bar should be visible.
24 30
      */
@@ -59,11 +65,14 @@ class NavigationBar extends Component<Props> {
59 65
                 <View
60 66
                     pointerEvents = 'box-none'
61 67
                     style = { styles.roomNameWrapper }>
62
-                    <Text
63
-                        numberOfLines = { 1 }
64
-                        style = { styles.roomName }>
65
-                        { this.props._meetingName }
66
-                    </Text>
68
+                    {
69
+                        this.props._meetingNameEnabled
70
+                        && <Text
71
+                            numberOfLines = { 1 }
72
+                            style = { styles.roomName }>
73
+                            { this.props._meetingName }
74
+                        </Text>
75
+                    }
67 76
                     <ConferenceTimer />
68 77
                 </View>
69 78
             </View>
@@ -76,14 +85,12 @@ class NavigationBar extends Component<Props> {
76 85
  * Maps part of the Redux store to the props of this component.
77 86
  *
78 87
  * @param {Object} state - The Redux state.
79
- * @returns {{
80
- *     _meetingName: string,
81
- *     _visible: boolean
82
- * }}
88
+ * @returns {Props}
83 89
  */
84 90
 function _mapStateToProps(state) {
85 91
     return {
86 92
         _meetingName: getConferenceName(state),
93
+        _meetingNameEnabled: getFeatureFlag(state, MEETING_NAME_ENABLED, true),
87 94
         _visible: isToolboxVisible(state)
88 95
     };
89 96
 }

+ 2
- 2
react/features/invite/actions.native.js Wyświetl plik

@@ -2,7 +2,7 @@
2 2
 
3 3
 import type { Dispatch } from 'redux';
4 4
 
5
-import { getFeatureFlag, INVITE_ENABLED } from '../base/flags';
5
+import { getFeatureFlag, ADD_PEOPLE_ENABLED } from '../base/flags';
6 6
 import { setActiveModalId } from '../base/modal';
7 7
 import { beginShareRoom } from '../share-room';
8 8
 
@@ -20,7 +20,7 @@ export * from './actions.any';
20 20
 export function doInvitePeople() {
21 21
     return (dispatch: Dispatch<any>, getState: Function) => {
22 22
         const state = getState();
23
-        const addPeopleEnabled = getFeatureFlag(state, INVITE_ENABLED, true)
23
+        const addPeopleEnabled = getFeatureFlag(state, ADD_PEOPLE_ENABLED, true)
24 24
             && (isAddPeopleEnabled(state) || isDialOutEnabled(state));
25 25
 
26 26
         if (addPeopleEnabled) {

+ 3
- 1
react/features/invite/components/add-people-dialog/native/InviteButton.js Wyświetl plik

@@ -2,6 +2,7 @@
2 2
 
3 3
 import type { Dispatch } from 'redux';
4 4
 
5
+import { getFeatureFlag, INVITE_ENABLED } from '../../../../base/flags';
5 6
 import { translate } from '../../../../base/i18n';
6 7
 import { IconAddPeople } from '../../../../base/icons';
7 8
 import { connect } from '../../../../base/redux';
@@ -47,9 +48,10 @@ class InviteButton extends AbstractButton<Props, *> {
47 48
  */
48 49
 function _mapStateToProps(state, ownProps: Props) {
49 50
     const { disableInviteFunctions } = state['features/base/config'];
51
+    const flag = getFeatureFlag(state, INVITE_ENABLED, true);
50 52
 
51 53
     return {
52
-        visible: !disableInviteFunctions && ownProps.visible
54
+        visible: flag && !disableInviteFunctions && ownProps.visible
53 55
     };
54 56
 }
55 57
 

+ 22
- 2
react/features/recording/components/LiveStream/native/LiveStreamButton.js Wyświetl plik

@@ -2,10 +2,11 @@
2 2
 
3 3
 import { translate } from '../../../../base/i18n';
4 4
 import { IconLiveStreaming } from '../../../../base/icons';
5
+import { LIVE_STREAMING_ENABLED, getFeatureFlag } from '../../../../base/flags';
5 6
 import { connect } from '../../../../base/redux';
6 7
 
7 8
 import AbstractLiveStreamButton, {
8
-    _mapStateToProps,
9
+    _mapStateToProps as _abstractMapStateToProps,
9 10
     type Props
10 11
 } from '../AbstractLiveStreamButton';
11 12
 
@@ -16,4 +17,23 @@ class LiveStreamButton extends AbstractLiveStreamButton<Props> {
16 17
     icon = IconLiveStreaming;
17 18
 }
18 19
 
19
-export default translate(connect(_mapStateToProps)(LiveStreamButton));
20
+/**
21
+ * Maps (parts of) the redux state to the associated props for this component.
22
+ *
23
+ * @param {Object} state - The redux state.
24
+ * @param {Object} ownProps - The properties explicitly passed to the component
25
+ * instance.
26
+ * @private
27
+ * @returns {Props}
28
+ */
29
+export function mapStateToProps(state: Object, ownProps: Object) {
30
+    const enabled = getFeatureFlag(state, LIVE_STREAMING_ENABLED, true);
31
+    const abstractProps = _abstractMapStateToProps(state, ownProps);
32
+
33
+    return {
34
+        ...abstractProps,
35
+        visible: enabled && abstractProps.visible
36
+    };
37
+}
38
+
39
+export default translate(connect(mapStateToProps)(LiveStreamButton));

+ 25
- 2
react/features/recording/components/Recording/native/RecordButton.js Wyświetl plik

@@ -1,11 +1,14 @@
1 1
 // @flow
2 2
 
3
+import { Platform } from 'react-native';
4
+
5
+import { IOS_RECORDING_ENABLED, RECORDING_ENABLED, getFeatureFlag } from '../../../../base/flags';
3 6
 import { translate } from '../../../../base/i18n';
4 7
 import { IconToggleRecording } from '../../../../base/icons';
5 8
 import { connect } from '../../../../base/redux';
6 9
 
7 10
 import AbstractRecordButton, {
8
-    _mapStateToProps,
11
+    _mapStateToProps as _abstractMapStateToProps,
9 12
     type Props
10 13
 } from '../AbstractRecordButton';
11 14
 
@@ -16,4 +19,24 @@ class RecordButton extends AbstractRecordButton<Props> {
16 19
     icon = IconToggleRecording;
17 20
 }
18 21
 
19
-export default translate(connect(_mapStateToProps)(RecordButton));
22
+/**
23
+ * Maps (parts of) the redux state to the associated props for this component.
24
+ *
25
+ * @param {Object} state - The redux state.
26
+ * @param {Object} ownProps - The properties explicitly passed to the component
27
+ * instance.
28
+ * @private
29
+ * @returns {Props}
30
+ */
31
+export function mapStateToProps(state: Object, ownProps: Object) {
32
+    const enabled = getFeatureFlag(state, RECORDING_ENABLED, true);
33
+    const iosEnabled = Platform.OS !== 'ios' || getFeatureFlag(state, IOS_RECORDING_ENABLED, false);
34
+    const abstractProps = _abstractMapStateToProps(state, ownProps);
35
+
36
+    return {
37
+        ...abstractProps,
38
+        visible: enabled && iosEnabled && abstractProps.visible
39
+    };
40
+}
41
+
42
+export default translate(connect(mapStateToProps)(RecordButton));

+ 9
- 8
react/features/room-lock/components/RoomLockButton.js Wyświetl plik

@@ -1,5 +1,6 @@
1 1
 // @flow
2 2
 
3
+import { MEETING_PASSWORD_ENABLED, getFeatureFlag } from '../../base/flags';
3 4
 import { translate } from '../../base/i18n';
4 5
 import { IconRoomLock, IconRoomUnlock } from '../../base/icons';
5 6
 import { isLocalParticipantModerator } from '../../base/participants';
@@ -83,19 +84,19 @@ class RoomLockButton extends AbstractButton<Props, *> {
83 84
  * {@code RoomLockButton} component.
84 85
  *
85 86
  * @param {Object} state - The Redux state.
87
+ * @param {Object} ownProps - The properties explicitly passed to the component instance.
86 88
  * @private
87
- * @returns {{
88
- *     _localParticipantModerator: boolean,
89
- *     _locked: boolean
90
- * }}
89
+ * @returns {Props}
91 90
  */
92
-function _mapStateToProps(state): Object {
91
+function _mapStateToProps(state, ownProps): Object {
93 92
     const { conference, locked } = state['features/base/conference'];
93
+    const enabled = getFeatureFlag(state, MEETING_PASSWORD_ENABLED, true);
94
+    const { visible = enabled } = ownProps;
94 95
 
95 96
     return {
96
-        _localParticipantModerator:
97
-            Boolean(conference && isLocalParticipantModerator(state)),
98
-        _locked: Boolean(conference && locked)
97
+        _localParticipantModerator: Boolean(conference && isLocalParticipantModerator(state)),
98
+        _locked: Boolean(conference && locked),
99
+        visible
99 100
     };
100 101
 }
101 102
 

+ 3
- 8
react/features/toolbox/components/native/OverflowMenu.js Wyświetl plik

@@ -1,12 +1,11 @@
1 1
 // @flow
2 2
 
3 3
 import React, { PureComponent } from 'react';
4
-import { Platform, TouchableOpacity, View } from 'react-native';
4
+import { TouchableOpacity, View } from 'react-native';
5 5
 import Collapsible from 'react-native-collapsible';
6 6
 
7 7
 import { ColorSchemeRegistry } from '../../../base/color-scheme';
8 8
 import { BottomSheet, hideDialog, isDialogOpen } from '../../../base/dialog';
9
-import { IOS_RECORDING_ENABLED, getFeatureFlag } from '../../../base/flags';
10 9
 import { IconDragHandle } from '../../../base/icons';
11 10
 import { connect } from '../../../base/redux';
12 11
 import { StyleType } from '../../../base/styles';
@@ -134,10 +133,7 @@ class OverflowMenu extends PureComponent<Props, State> {
134 133
                 <Collapsible collapsed = { !showMore }>
135 134
                     <ToggleCameraButton { ...buttonProps } />
136 135
                     <TileViewButton { ...buttonProps } />
137
-                    {
138
-                        this.props._recordingEnabled
139
-                            && <RecordButton { ...buttonProps } />
140
-                    }
136
+                    <RecordButton { ...buttonProps } />
141 137
                     <LiveStreamButton { ...buttonProps } />
142 138
                     <RoomLockButton { ...buttonProps } />
143 139
                     <ClosedCaptionButton { ...buttonProps } />
@@ -240,8 +236,7 @@ class OverflowMenu extends PureComponent<Props, State> {
240 236
 function _mapStateToProps(state) {
241 237
     return {
242 238
         _bottomSheetStyles: ColorSchemeRegistry.get(state, 'BottomSheet'),
243
-        _isOpen: isDialogOpen(state, OverflowMenu_),
244
-        _recordingEnabled: Platform.OS !== 'ios' || getFeatureFlag(state, IOS_RECORDING_ENABLED)
239
+        _isOpen: isDialogOpen(state, OverflowMenu_)
245 240
     };
246 241
 }
247 242
 

+ 5
- 28
react/features/toolbox/components/native/Toolbox.js Wyświetl plik

@@ -4,12 +4,10 @@ import React, { PureComponent } from 'react';
4 4
 import { View } from 'react-native';
5 5
 
6 6
 import { ColorSchemeRegistry } from '../../../base/color-scheme';
7
-import { CHAT_ENABLED, getFeatureFlag } from '../../../base/flags';
8 7
 import { Container } from '../../../base/react';
9 8
 import { connect } from '../../../base/redux';
10 9
 import { StyleType } from '../../../base/styles';
11 10
 import { ChatButton } from '../../../chat';
12
-import { InviteButton } from '../../../invite';
13 11
 
14 12
 import { isToolboxVisible } from '../../functions';
15 13
 
@@ -25,11 +23,6 @@ import VideoMuteButton from '../VideoMuteButton';
25 23
  */
26 24
 type Props = {
27 25
 
28
-    /**
29
-     * Whether the chat feature has been enabled. The meeting info button will be displayed in its place when disabled.
30
-     */
31
-    _chatEnabled: boolean,
32
-
33 26
     /**
34 27
      * The color-schemed stylesheet of the feature.
35 28
      */
@@ -105,7 +98,7 @@ class Toolbox extends PureComponent<Props> {
105 98
      * @returns {React$Node}
106 99
      */
107 100
     _renderToolbar() {
108
-        const { _chatEnabled, _styles } = this.props;
101
+        const { _styles } = this.props;
109 102
         const { buttonStyles, buttonStylesBorderless, hangupButtonStyles, toggledButtonStyles } = _styles;
110 103
 
111 104
         return (
@@ -113,20 +106,9 @@ class Toolbox extends PureComponent<Props> {
113 106
                 accessibilityRole = 'toolbar'
114 107
                 pointerEvents = 'box-none'
115 108
                 style = { styles.toolbar }>
116
-                {
117
-                    _chatEnabled
118
-                        && <ChatButton
119
-                            styles = { buttonStylesBorderless }
120
-                            toggledStyles = {
121
-                                this._getChatButtonToggledStyle(toggledButtonStyles)
122
-                            } />
123
-                }
124
-                {
125
-                    !_chatEnabled
126
-                        && <InviteButton
127
-                            styles = { buttonStyles }
128
-                            toggledStyles = { toggledButtonStyles } />
129
-                }
109
+                <ChatButton
110
+                    styles = { buttonStylesBorderless }
111
+                    toggledStyles = { this._getChatButtonToggledStyle(toggledButtonStyles) } />
130 112
                 <AudioMuteButton
131 113
                     styles = { buttonStyles }
132 114
                     toggledStyles = { toggledButtonStyles } />
@@ -150,15 +132,10 @@ class Toolbox extends PureComponent<Props> {
150 132
  * @param {Object} state - The redux state of which parts are to be mapped to
151 133
  * {@code Toolbox} props.
152 134
  * @private
153
- * @returns {{
154
- *     _chatEnabled: boolean,
155
- *     _styles: StyleType,
156
- *     _visible: boolean
157
- * }}
135
+ * @returns {Props}
158 136
  */
159 137
 function _mapStateToProps(state: Object): Object {
160 138
     return {
161
-        _chatEnabled: getFeatureFlag(state, CHAT_ENABLED, true),
162 139
         _styles: ColorSchemeRegistry.get(state, 'Toolbox'),
163 140
         _visible: isToolboxVisible(state)
164 141
     };

Ładowanie…
Anuluj
Zapisz