Browse Source

Introduce SafeArea for Settings and Header

master
zbettenbuk 7 years ago
parent
commit
9a9890f86c
24 changed files with 398 additions and 384 deletions
  1. 0
    1
      android/app/src/main/res/values/styles.xml
  2. 4
    2
      lang/main.json
  3. 2
    2
      react/features/app-settings/actionTypes.js
  4. 2
    2
      react/features/app-settings/actions.js
  5. 1
    7
      react/features/app-settings/components/AbstractAppSettings.js
  6. 83
    103
      react/features/app-settings/components/AppSettings.native.js
  7. 0
    117
      react/features/app-settings/components/FormSectionHeader.native.js
  8. 1
    0
      react/features/app-settings/components/_.native.js
  9. 0
    0
      react/features/app-settings/components/_.web.js
  10. 4
    5
      react/features/app-settings/components/native/BackButton.js
  11. 8
    39
      react/features/app-settings/components/native/FormRow.js
  12. 60
    0
      react/features/app-settings/components/native/FormSectionHeader.js
  13. 3
    0
      react/features/app-settings/components/native/index.js
  14. 83
    0
      react/features/app-settings/components/native/styles.js
  15. 4
    104
      react/features/app-settings/components/styles.js
  16. 56
    0
      react/features/base/react/components/native/Header.js
  17. 2
    0
      react/features/base/react/components/native/index.js
  18. 39
    0
      react/features/base/react/components/native/styles.js
  19. 0
    1
      react/features/base/react/index.js
  20. 1
    0
      react/features/base/styles/components/styles/ColorPalette.js
  21. 42
    0
      react/features/base/styles/components/styles/PlatformElements.native.js
  22. 0
    0
      react/features/base/styles/components/styles/PlatformElements.web.js
  23. 1
    0
      react/features/base/styles/components/styles/index.js
  24. 2
    1
      react/features/conference/components/Conference.native.js

+ 0
- 1
android/app/src/main/res/values/styles.xml View File

2
     <!-- Base application theme. -->
2
     <!-- Base application theme. -->
3
     <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
3
     <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
4
         <!-- Customize your theme here. -->
4
         <!-- Customize your theme here. -->
5
-        <item name="android:windowTranslucentStatus">true</item>
6
     </style>
5
     </style>
7
 </resources>
6
 </resources>

+ 4
- 2
lang/main.json View File

47
     },
47
     },
48
     "welcomepage":{
48
     "welcomepage":{
49
         "appDescription": "Go ahead, video chat with the whole team. In fact, invite everyone you know. __app__ is a fully encrypted, 100% open source video conferencing solution that you can use all day, every day, for free — with no account needed.",
49
         "appDescription": "Go ahead, video chat with the whole team. In fact, invite everyone you know. __app__ is a fully encrypted, 100% open source video conferencing solution that you can use all day, every day, for free — with no account needed.",
50
+        "audioOnlyLabel": "Voice",
50
         "go": "GO",
51
         "go": "GO",
51
         "join": "JOIN",
52
         "join": "JOIN",
52
         "privacy": "Privacy",
53
         "privacy": "Privacy",
53
         "roomname": "Enter room name",
54
         "roomname": "Enter room name",
54
         "sendFeedback": "Send feedback",
55
         "sendFeedback": "Send feedback",
55
         "terms": "Terms",
56
         "terms": "Terms",
56
-        "title": "More secure, more flexible, and completely free video conferencing"
57
+        "title": "More secure, more flexible, and completely free video conferencing",
58
+        "videoEnabledLabel": "Video"
57
     },
59
     },
58
     "startupoverlay": {
60
     "startupoverlay": {
59
         "policyText": " ",
61
         "policyText": " ",
500
         "title": "Call info",
502
         "title": "Call info",
501
         "tooltip": "Get access info about the meeting"
503
         "tooltip": "Get access info about the meeting"
502
     },
504
     },
503
-    "profileModal": {
505
+    "settingsScreen": {
504
         "alertOk": "OK",
506
         "alertOk": "OK",
505
         "alertTitle": "Warning",
507
         "alertTitle": "Warning",
506
         "alertURLText": "The entered server URL is invalid",
508
         "alertURLText": "The entered server URL is invalid",

+ 2
- 2
react/features/app-settings/actionTypes.js View File

1
 /**
1
 /**
2
  * The type of (redux) action which signals the request
2
  * The type of (redux) action which signals the request
3
- * to hide the app settings modal.
3
+ * to hide the app settings screen.
4
  *
4
  *
5
  * {
5
  * {
6
  *     type: HIDE_APP_SETTINGS
6
  *     type: HIDE_APP_SETTINGS
10
 
10
 
11
 /**
11
 /**
12
  * The type of (redux) action which signals the request
12
  * The type of (redux) action which signals the request
13
- * to show the app settings modal where available.
13
+ * to show the app settings screen where available.
14
  *
14
  *
15
  * {
15
  * {
16
  *     type: SHOW_APP_SETTINGS
16
  *     type: SHOW_APP_SETTINGS

+ 2
- 2
react/features/app-settings/actions.js View File

3
 import { HIDE_APP_SETTINGS, SHOW_APP_SETTINGS } from './actionTypes';
3
 import { HIDE_APP_SETTINGS, SHOW_APP_SETTINGS } from './actionTypes';
4
 
4
 
5
 /**
5
 /**
6
- * Redux-signals the request to hide the app settings modal.
6
+ * Redux-signals the request to hide the app settings screen.
7
  *
7
  *
8
  * @returns {{
8
  * @returns {{
9
  *     type: HIDE_APP_SETTINGS
9
  *     type: HIDE_APP_SETTINGS
16
 }
16
 }
17
 
17
 
18
 /**
18
 /**
19
- * Redux-signals the request to open the app settings modal.
19
+ * Redux-signals the request to open the app settings screen.
20
  *
20
  *
21
  * @returns {{
21
  * @returns {{
22
  *     type: SHOW_APP_SETTINGS
22
  *     type: SHOW_APP_SETTINGS

+ 1
- 7
react/features/app-settings/components/AbstractAppSettings.js View File

9
  */
9
  */
10
 type Props = {
10
 type Props = {
11
 
11
 
12
-    /**
13
-     * The current aspect ratio of the screen.
14
-     */
15
-    _aspectRatio: Symbol,
16
-
17
     /**
12
     /**
18
      * The current profile object.
13
      * The current profile object.
19
      */
14
      */
25
     _serverURL: string,
20
     _serverURL: string,
26
 
21
 
27
     /**
22
     /**
28
-     * The visibility prop of the settings modal.
23
+     * The visibility prop of the settings screen.
29
      */
24
      */
30
     _visible: boolean,
25
     _visible: boolean,
31
 
26
 
173
     const _profile = getProfile(state);
168
     const _profile = getProfile(state);
174
 
169
 
175
     return {
170
     return {
176
-        _aspectRatio: state['features/base/responsive-ui'].aspectRatio,
177
         _profile,
171
         _profile,
178
         _serverURL,
172
         _serverURL,
179
         _visible: state['features/app-settings'].visible
173
         _visible: state['features/app-settings'].visible

+ 83
- 103
react/features/app-settings/components/AppSettings.native.js View File

4
 import {
4
 import {
5
     Alert,
5
     Alert,
6
     Modal,
6
     Modal,
7
+    SafeAreaView,
7
     ScrollView,
8
     ScrollView,
8
     Switch,
9
     Switch,
9
     Text,
10
     Text,
13
 import { connect } from 'react-redux';
14
 import { connect } from 'react-redux';
14
 
15
 
15
 import { translate } from '../../base/i18n';
16
 import { translate } from '../../base/i18n';
16
-import { getSafetyOffset, isIPad } from '../../base/react';
17
-import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui';
17
+import { Header } from '../../base/react';
18
+import { PlatformElements } from '../../base/styles';
18
 
19
 
19
-import { _mapStateToProps, AbstractAppSettings } from './AbstractAppSettings';
20
 import { hideAppSettings } from '../actions';
20
 import { hideAppSettings } from '../actions';
21
-import BackButton from './BackButton.native';
22
-import FormRow from './FormRow.native';
23
-import FormSectionHeader from './FormSectionHeader.native';
24
 import { normalizeUserInputURL } from '../functions';
21
 import { normalizeUserInputURL } from '../functions';
25
-import styles, { HEADER_PADDING } from './styles';
22
+
23
+import { BackButton, FormRow, FormSectionHeader } from './_';
24
+import { _mapStateToProps, AbstractAppSettings } from './AbstractAppSettings';
25
+import styles from './styles';
26
 
26
 
27
 /**
27
 /**
28
  * The native container rendering the app settings page.
28
  * The native container rendering the app settings page.
40
     constructor(props) {
40
     constructor(props) {
41
         super(props);
41
         super(props);
42
 
42
 
43
-        this._getSafetyPadding = this._getSafetyPadding.bind(this);
44
         this._onBlurServerURL = this._onBlurServerURL.bind(this);
43
         this._onBlurServerURL = this._onBlurServerURL.bind(this);
45
         this._onRequestClose = this._onRequestClose.bind(this);
44
         this._onRequestClose = this._onRequestClose.bind(this);
46
         this._setURLFieldReference = this._setURLFieldReference.bind(this);
45
         this._setURLFieldReference = this._setURLFieldReference.bind(this);
56
     render() {
55
     render() {
57
         const { _profile, t } = this.props;
56
         const { _profile, t } = this.props;
58
 
57
 
59
-        // FIXME: presentationStyle is added to workaround orientation issue on
60
-        // iOS
61
-
62
         return (
58
         return (
63
             <Modal
59
             <Modal
64
                 animationType = 'slide'
60
                 animationType = 'slide'
65
                 onRequestClose = { this._onRequestClose }
61
                 onRequestClose = { this._onRequestClose }
66
-                presentationStyle = 'overFullScreen'
62
+                presentationStyle = 'fullScreen'
67
                 supportedOrientations = { [
63
                 supportedOrientations = { [
68
                     'landscape',
64
                     'landscape',
69
                     'portrait'
65
                     'portrait'
70
                 ] }
66
                 ] }
71
                 visible = { this.props._visible }>
67
                 visible = { this.props._visible }>
72
-                <View
73
-                    style = { [
74
-                        styles.headerContainer,
75
-                        this._getSafetyPadding()
76
-                    ] } >
77
-                    <BackButton
78
-                        onPress = { this._onRequestClose }
79
-                        style = { styles.settingsBackButton } />
80
-                    <Text style = { [ styles.text, styles.headerTitle ] } >
81
-                        { t('profileModal.header') }
82
-                    </Text>
68
+                <View style = { PlatformElements.page }>
69
+                    <Header>
70
+                        <BackButton
71
+                            onPress = { this._onRequestClose } />
72
+                        <Text
73
+                            style = { [
74
+                                styles.text,
75
+                                PlatformElements.headerText
76
+                            ] } >
77
+                            { t('settingsScreen.header') }
78
+                        </Text>
79
+                    </Header>
80
+                    <SafeAreaView style = { styles.settingsForm }>
81
+                        <ScrollView>
82
+                            <FormSectionHeader
83
+                                i18nLabel = 'settingsScreen.profileSection' />
84
+                            <FormRow
85
+                                fieldSeparator = { true }
86
+                                i18nLabel = 'settingsScreen.displayName' >
87
+                                <TextInput
88
+                                    onChangeText = { this._onChangeDisplayName }
89
+                                    placeholder = 'John Doe'
90
+                                    value = { _profile.displayName } />
91
+                            </FormRow>
92
+                            <FormRow
93
+                                i18nLabel = 'settingsScreen.email' >
94
+                                <TextInput
95
+                                    keyboardType = { 'email-address' }
96
+                                    onChangeText = { this._onChangeEmail }
97
+                                    placeholder = 'email@example.com'
98
+                                    value = { _profile.email } />
99
+                            </FormRow>
100
+                            <FormSectionHeader
101
+                                i18nLabel
102
+                                    = 'settingsScreen.conferenceSection' />
103
+                            <FormRow
104
+                                fieldSeparator = { true }
105
+                                i18nLabel = 'settingsScreen.serverURL' >
106
+                                <TextInput
107
+                                    autoCapitalize = 'none'
108
+                                    onBlur = { this._onBlurServerURL }
109
+                                    onChangeText = { this._onChangeServerURL }
110
+                                    placeholder = { this.props._serverURL }
111
+                                    value = { _profile.serverURL } />
112
+                            </FormRow>
113
+                            <FormRow
114
+                                fieldSeparator = { true }
115
+                                i18nLabel
116
+                                    = 'settingsScreen.startWithAudioMuted' >
117
+                                <Switch
118
+                                    onValueChange = {
119
+                                        this._onStartAudioMutedChange
120
+                                    }
121
+                                    value = {
122
+                                        _profile.startWithAudioMuted
123
+                                    } />
124
+                            </FormRow>
125
+                            <FormRow
126
+                                i18nLabel
127
+                                    = 'settingsScreen.startWithVideoMuted' >
128
+                                <Switch
129
+                                    onValueChange = {
130
+                                        this._onStartVideoMutedChange
131
+                                    }
132
+                                    value = {
133
+                                        _profile.startWithVideoMuted
134
+                                    } />
135
+                            </FormRow>
136
+                        </ScrollView>
137
+                    </SafeAreaView>
83
                 </View>
138
                 </View>
84
-                <ScrollView style = { styles.settingsContainer } >
85
-                    <FormSectionHeader
86
-                        i18nLabel = 'profileModal.profileSection' />
87
-                    <FormRow
88
-                        fieldSeparator = { true }
89
-                        i18nLabel = 'profileModal.displayName' >
90
-                        <TextInput
91
-                            onChangeText = { this._onChangeDisplayName }
92
-                            placeholder = 'John Doe'
93
-                            value = { _profile.displayName } />
94
-                    </FormRow>
95
-                    <FormRow
96
-                        i18nLabel = 'profileModal.email' >
97
-                        <TextInput
98
-                            keyboardType = { 'email-address' }
99
-                            onChangeText = { this._onChangeEmail }
100
-                            placeholder = 'email@example.com'
101
-                            value = { _profile.email } />
102
-                    </FormRow>
103
-                    <FormSectionHeader
104
-                        i18nLabel = 'profileModal.conferenceSection' />
105
-                    <FormRow
106
-                        fieldSeparator = { true }
107
-                        i18nLabel = 'profileModal.serverURL' >
108
-                        <TextInput
109
-                            autoCapitalize = 'none'
110
-                            onBlur = { this._onBlurServerURL }
111
-                            onChangeText = { this._onChangeServerURL }
112
-                            placeholder = { this.props._serverURL }
113
-                            ref = { this._setURLFieldReference }
114
-                            value = { _profile.serverURL } />
115
-                    </FormRow>
116
-                    <FormRow
117
-                        fieldSeparator = { true }
118
-                        i18nLabel = 'profileModal.startWithAudioMuted' >
119
-                        <Switch
120
-                            onValueChange = {
121
-                                this._onStartAudioMutedChange
122
-                            }
123
-                            value = {
124
-                                _profile.startWithAudioMuted
125
-                            } />
126
-                    </FormRow>
127
-                    <FormRow
128
-                        i18nLabel = 'profileModal.startWithVideoMuted' >
129
-                        <Switch
130
-                            onValueChange = {
131
-                                this._onStartVideoMutedChange
132
-                            }
133
-                            value = {
134
-                                _profile.startWithVideoMuted
135
-                            } />
136
-                    </FormRow>
137
-                </ScrollView>
138
             </Modal>
139
             </Modal>
139
         );
140
         );
140
     }
141
     }
141
 
142
 
142
-    _getSafetyPadding: () => Object;
143
-
144
-    /**
145
-     * Calculates header safety padding for mobile devices. See comment in
146
-     * functions.js.
147
-     *
148
-     * @private
149
-     * @returns {Object}
150
-     */
151
-    _getSafetyPadding() {
152
-        if (isIPad() || this.props._aspectRatio === ASPECT_RATIO_NARROW) {
153
-            const safeOffset = Math.max(getSafetyOffset(), HEADER_PADDING);
154
-
155
-            return {
156
-                paddingTop: safeOffset
157
-            };
158
-        }
159
-
160
-        return undefined;
161
-    }
162
-
163
     _onBlurServerURL: () => void;
143
     _onBlurServerURL: () => void;
164
 
144
 
165
     /**
145
     /**
183
 
163
 
184
     _onStartVideoMutedChange: (boolean) => void;
164
     _onStartVideoMutedChange: (boolean) => void;
185
 
165
 
186
-    _onRequestClose: () => void;
187
-
188
     /**
166
     /**
189
      * Processes the server URL. It normalizes it and an error alert is
167
      * Processes the server URL. It normalizes it and an error alert is
190
      * displayed in case it's incorrect.
168
      * displayed in case it's incorrect.
208
         }
186
         }
209
     }
187
     }
210
 
188
 
189
+    _onRequestClose: () => void;
190
+
211
     /**
191
     /**
212
      * Handles the back button.
192
      * Handles the back button.
213
      * Also invokes normalizeUserInputURL to validate the URL entered
193
      * Also invokes normalizeUserInputURL to validate the URL entered
243
         const { t } = this.props;
223
         const { t } = this.props;
244
 
224
 
245
         Alert.alert(
225
         Alert.alert(
246
-            t('profileModal.alertTitle'),
247
-            t('profileModal.alertURLText'),
226
+            t('settingsScreen.alertTitle'),
227
+            t('settingsScreen.alertURLText'),
248
             [
228
             [
249
                 {
229
                 {
250
                     onPress: () => this._urlField.focus(),
230
                     onPress: () => this._urlField.focus(),
251
-                    text: t('profileModal.alertOk')
231
+                    text: t('settingsScreen.alertOk')
252
                 }
232
                 }
253
             ]
233
             ]
254
         );
234
         );

+ 0
- 117
react/features/app-settings/components/FormSectionHeader.native.js View File

1
-// @flow
2
-
3
-import React, { Component } from 'react';
4
-import { Text, View } from 'react-native';
5
-import { connect } from 'react-redux';
6
-
7
-import { translate } from '../../base/i18n';
8
-import { getSafetyOffset } from '../../base/react';
9
-import { ASPECT_RATIO_WIDE } from '../../base/responsive-ui';
10
-
11
-import styles, { CONTAINER_PADDING } from './styles';
12
-
13
-/**
14
- * The type of the React {@code Component} props of {@link FormSectionHeader}
15
- */
16
-type Props = {
17
-
18
-    /**
19
-     * The current aspect ratio of the screen.
20
-     */
21
-    _aspectRatio: Symbol,
22
-
23
-    /**
24
-     * The i18n key of the text label of the section.
25
-     */
26
-    i18nLabel: string,
27
-
28
-    /**
29
-     * An external style object passed to the component.
30
-     */
31
-    style: Object,
32
-
33
-    /**
34
-     * Invoked to obtain translated strings.
35
-     */
36
-    t: Function
37
-}
38
-
39
-/**
40
- * Implements a React {@code Component} which renders a section header on a
41
- * form. This calculates the available safe view as well.
42
- */
43
-class FormSectionHeader extends Component<Props> {
44
-    /**
45
-     * Initializes a new {@code FormSectionHeader} instance.
46
-     *
47
-     * @param {Object} props - Component properties.
48
-     */
49
-    constructor(props) {
50
-        super(props);
51
-
52
-        this._getSafetyMargin = this._getSafetyMargin.bind(this);
53
-    }
54
-
55
-    /**
56
-     * Implements React's {@link Component#render()}.
57
-     *
58
-     * @inheritdoc
59
-     * @override
60
-     * @returns {ReactElement}
61
-     */
62
-    render() {
63
-        const { t } = this.props;
64
-
65
-        return (
66
-            <View
67
-                style = { [
68
-                    styles.formSectionTitle,
69
-                    this.props.style,
70
-                    this._getSafetyMargin()
71
-                ] } >
72
-                <Text>
73
-                    { t(this.props.i18nLabel) }
74
-                </Text>
75
-            </View>
76
-        );
77
-    }
78
-
79
-    _getSafetyMargin: () => Object;
80
-
81
-    /**
82
-     * Calculates the safety margin for this header. See comment in
83
-     * functions.js.
84
-     *
85
-     * @private
86
-     * @returns {Object}
87
-     */
88
-    _getSafetyMargin() {
89
-        if (this.props._aspectRatio === ASPECT_RATIO_WIDE) {
90
-            const safeOffset
91
-                = Math.max(getSafetyOffset() - CONTAINER_PADDING, 0);
92
-
93
-            return {
94
-                marginLeft: safeOffset,
95
-                marginRight: safeOffset
96
-            };
97
-        }
98
-
99
-        return undefined;
100
-    }
101
-}
102
-
103
-/**
104
- * Maps (parts of) the redux state to the React {@code Component} props of
105
- * {@code FormSectionHeader}.
106
- *
107
- * @param {Object} state - The redux state.
108
- * @protected
109
- * @returns {Object}
110
- */
111
-export function _mapStateToProps(state: Object) {
112
-    return {
113
-        _aspectRatio: state['features/base/responsive-ui'].aspectRatio
114
-    };
115
-}
116
-
117
-export default translate(connect(_mapStateToProps)(FormSectionHeader));

+ 1
- 0
react/features/app-settings/components/_.native.js View File

1
+export * from './native';

react/features/base/react/functions.web.js → react/features/app-settings/components/_.web.js View File


react/features/app-settings/components/BackButton.native.js → react/features/app-settings/components/native/BackButton.js View File

3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 import { TouchableOpacity } from 'react-native';
4
 import { TouchableOpacity } from 'react-native';
5
 
5
 
6
-import { Icon } from '../../base/font-icons';
7
-
8
-import styles from './styles';
6
+import { Icon } from '../../../base/font-icons';
7
+import { PlatformElements } from '../../../base/styles';
9
 
8
 
10
 /**
9
 /**
11
  * The type of the React {@code Component} props of {@link BackButton}
10
  * The type of the React {@code Component} props of {@link BackButton}
20
     /**
19
     /**
21
      * An external style object passed to the component.
20
      * An external style object passed to the component.
22
      */
21
      */
23
-    style: Object
22
+    style?: Object
24
 };
23
 };
25
 
24
 
26
 /**
25
 /**
41
                 <Icon
40
                 <Icon
42
                     name = { 'arrow_back' }
41
                     name = { 'arrow_back' }
43
                     style = { [
42
                     style = { [
44
-                        styles.backIcon,
43
+                        PlatformElements.headerButton,
45
                         this.props.style
44
                         this.props.style
46
                     ] } />
45
                     ] } />
47
             </TouchableOpacity>
46
             </TouchableOpacity>

react/features/app-settings/components/FormRow.native.js → react/features/app-settings/components/native/FormRow.js View File

2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 import { Text, View } from 'react-native';
4
 import { Text, View } from 'react-native';
5
-import { connect } from 'react-redux';
6
 
5
 
7
-import { translate } from '../../base/i18n';
8
-import { getSafetyOffset } from '../../base/react';
9
-import { ASPECT_RATIO_WIDE } from '../../base/responsive-ui';
6
+import { translate } from '../../../base/i18n';
10
 
7
 
11
-import styles, { ANDROID_UNDERLINE_COLOR, CONTAINER_PADDING } from './styles';
8
+import styles, { ANDROID_UNDERLINE_COLOR } from './styles';
12
 
9
 
13
 /**
10
 /**
14
  * The type of the React {@code Component} props of {@link FormRow}
11
  * The type of the React {@code Component} props of {@link FormRow}
15
  */
12
  */
16
 type Props = {
13
 type Props = {
17
 
14
 
18
-    /**
19
-     * The current aspect ratio of the screen.
20
-     */
21
-    _aspectRatio: Symbol,
22
-
23
     /**
15
     /**
24
      *
16
      *
25
      */
17
      */
80
             <View
72
             <View
81
                 style = { this._getRowStyle() } >
73
                 style = { this._getRowStyle() } >
82
                 <View style = { styles.fieldLabelContainer } >
74
                 <View style = { styles.fieldLabelContainer } >
83
-                    <Text style = { styles.text } >
75
+                    <Text
76
+                        style = { [
77
+                            styles.text, styles.fieldLabelText
78
+                        ] } >
84
                         { t(this.props.i18nLabel) }
79
                         { t(this.props.i18nLabel) }
85
                     </Text>
80
                     </Text>
86
                 </View>
81
                 </View>
122
     _getRowStyle: () => Array<Object>;
117
     _getRowStyle: () => Array<Object>;
123
 
118
 
124
     /**
119
     /**
125
-     * Assembles the row style array based on the row's props. For padding, see
126
-     * comment in functions.js.
120
+     * Assembles the row style array based on the row's props.
127
      *
121
      *
128
      * @private
122
      * @private
129
      * @returns {Array<Object>}
123
      * @returns {Array<Object>}
137
             rowStyle.push(styles.fieldSeparator);
131
             rowStyle.push(styles.fieldSeparator);
138
         }
132
         }
139
 
133
 
140
-        if (this.props._aspectRatio === ASPECT_RATIO_WIDE) {
141
-            const safeOffset = Math.max(
142
-                getSafetyOffset() - CONTAINER_PADDING, 0
143
-            );
144
-
145
-            rowStyle.push({
146
-                marginLeft: safeOffset,
147
-                marginRight: safeOffset
148
-            });
149
-        }
150
-
151
         return rowStyle;
134
         return rowStyle;
152
     }
135
     }
153
 }
136
 }
154
 
137
 
155
-/**
156
- * Maps (parts of) the redux state to the React {@code Component} props of
157
- * {@code FormRow}.
158
- *
159
- * @param {Object} state - The redux state.
160
- * @protected
161
- * @returns {Object}
162
- */
163
-export function _mapStateToProps(state: Object) {
164
-    return {
165
-        _aspectRatio: state['features/base/responsive-ui'].aspectRatio
166
-    };
167
-}
168
-
169
-export default translate(connect(_mapStateToProps)(FormRow));
138
+export default translate(FormRow);

+ 60
- 0
react/features/app-settings/components/native/FormSectionHeader.js View File

1
+// @flow
2
+
3
+import React, { Component } from 'react';
4
+import { Text, View } from 'react-native';
5
+
6
+import { translate } from '../../../base/i18n';
7
+
8
+import styles from './styles';
9
+
10
+/**
11
+ * The type of the React {@code Component} props of {@link FormSectionHeader}
12
+ */
13
+type Props = {
14
+
15
+    /**
16
+     * The i18n key of the text label of the section.
17
+     */
18
+    i18nLabel: string,
19
+
20
+    /**
21
+     * An external style object passed to the component.
22
+     */
23
+    style: Object,
24
+
25
+    /**
26
+     * Invoked to obtain translated strings.
27
+     */
28
+    t: Function
29
+}
30
+
31
+/**
32
+ * Implements a React {@code Component} which renders a section header on a
33
+ * form.
34
+ */
35
+class FormSectionHeader extends Component<Props> {
36
+    /**
37
+     * Implements React's {@link Component#render()}.
38
+     *
39
+     * @inheritdoc
40
+     * @override
41
+     * @returns {ReactElement}
42
+     */
43
+    render() {
44
+        const { i18nLabel, style, t } = this.props;
45
+
46
+        return (
47
+            <View
48
+                style = { [
49
+                    styles.formSectionTitle,
50
+                    style
51
+                ] } >
52
+                <Text>
53
+                    { t(i18nLabel) }
54
+                </Text>
55
+            </View>
56
+        );
57
+    }
58
+}
59
+
60
+export default translate(FormSectionHeader);

+ 3
- 0
react/features/app-settings/components/native/index.js View File

1
+export { default as BackButton } from './BackButton';
2
+export { default as FormRow } from './FormRow';
3
+export { default as FormSectionHeader } from './FormSectionHeader';

+ 83
- 0
react/features/app-settings/components/native/styles.js View File

1
+import {
2
+    ColorPalette,
3
+    createStyleSheet
4
+} from '../../../base/styles';
5
+
6
+export const ANDROID_UNDERLINE_COLOR = 'transparent';
7
+const TEXT_SIZE = 17;
8
+
9
+/**
10
+ * The styles of the native components of the feature
11
+ * {@code app-settings}.
12
+ */
13
+export default createStyleSheet({
14
+    /**
15
+     * Standardized style for a field container {@code View}.
16
+     */
17
+    fieldContainer: {
18
+        alignItems: 'center',
19
+        flexDirection: 'row',
20
+        minHeight: 65,
21
+        paddingHorizontal: 8
22
+    },
23
+
24
+    /**
25
+     * Standard container for a {@code View} containing a field label.
26
+     */
27
+    fieldLabelContainer: {
28
+        alignItems: 'center',
29
+        flexDirection: 'row',
30
+        marginRight: 5
31
+    },
32
+
33
+    /**
34
+     * Text of the field labels on the form.
35
+     */
36
+    fieldLabelText: {
37
+        fontSize: TEXT_SIZE
38
+    },
39
+
40
+    /**
41
+     * Field container style for all but last row {@code View}.
42
+     */
43
+    fieldSeparator: {
44
+        borderBottomWidth: 1,
45
+        borderColor: 'rgba(0, 0, 0, 0.1)'
46
+    },
47
+
48
+    /**
49
+     * Style for the {@code View} containing each
50
+     * field values (the actual field).
51
+     */
52
+    fieldValueContainer: {
53
+        alignItems: 'center',
54
+        flex: 1,
55
+        flexDirection: 'row',
56
+        justifyContent: 'flex-end'
57
+    },
58
+
59
+    /**
60
+     * Style fo the form section separator titles.
61
+     */
62
+    formSectionTitle: {
63
+        backgroundColor: 'rgba(0, 0, 0, 0.1)',
64
+        marginTop: 5,
65
+        padding: 5
66
+    },
67
+
68
+    /**
69
+     * Global {@code Text} color for the components.
70
+     */
71
+    text: {
72
+        color: ColorPalette.black
73
+    },
74
+
75
+    /**
76
+     * Standard text input field style.
77
+     */
78
+    textInputField: {
79
+        flex: 1,
80
+        fontSize: TEXT_SIZE,
81
+        textAlign: 'right'
82
+    }
83
+});

+ 4
- 104
react/features/app-settings/components/styles.js View File

4
     createStyleSheet
4
     createStyleSheet
5
 } from '../../base/styles';
5
 } from '../../base/styles';
6
 
6
 
7
-export const ANDROID_UNDERLINE_COLOR = 'transparent';
8
-export const CONTAINER_PADDING = 2 * BoxModel.padding;
9
-export const HEADER_COLOR = ColorPalette.blue;
10
-export const HEADER_PADDING = BoxModel.padding;
11
-const TEXT_SIZE = 17;
12
-
13
 /**
7
 /**
14
  * The styles of the React {@code Components} of the feature
8
  * The styles of the React {@code Components} of the feature
15
  * {@code app-settings}.
9
  * {@code app-settings}.
16
  */
10
  */
17
 export default createStyleSheet({
11
 export default createStyleSheet({
18
-
19
-    /**
20
-     * The back button style.
21
-     */
22
-    backIcon: {
23
-        alignSelf: 'center',
24
-        fontSize: 26,
25
-        padding: 8,
26
-        paddingRight: 22
27
-    },
28
-
29
-    /**
30
-     * Standardized style for a field container {@code View}.
31
-     */
32
-    fieldContainer: {
33
-        alignItems: 'center',
34
-        flexDirection: 'row',
35
-        minHeight: 65
36
-    },
37
-
38
-    /**
39
-     * Standard container for a {@code View} containing a field label.
40
-     */
41
-    fieldLabelContainer: {
42
-        alignItems: 'center',
43
-        flexDirection: 'row',
44
-        marginRight: 5
45
-    },
46
-
47
-    /**
48
-     * Field container style for all but last row {@code View}.
49
-     */
50
-    fieldSeparator: {
51
-        borderBottomWidth: 1,
52
-        borderColor: 'rgba(0, 0, 0, 0.1)'
53
-    },
54
-
55
-    /**
56
-     * Style for the {@code View} containing each
57
-     * field values (the actual field).
58
-     */
59
-    fieldValueContainer: {
60
-        alignItems: 'center',
61
-        flex: 1,
62
-        flexDirection: 'row',
63
-        justifyContent: 'flex-end'
64
-    },
65
-
66
-    formSectionTitle: {
67
-        backgroundColor: 'rgba(0, 0, 0, 0.1)',
68
-        marginTop: 5,
69
-        padding: 5
70
-    },
71
-
72
-    /**
73
-     * Page header {@code View}.
74
-     */
75
-    headerContainer: {
76
-        alignItems: 'center',
77
-        backgroundColor: HEADER_COLOR,
78
-        flexDirection: 'row',
79
-        justifyContent: 'flex-start',
80
-        padding: HEADER_PADDING
81
-    },
82
-
83
-    /**
84
-     * The title {@code Text} of the header.
85
-     */
86
-    headerTitle: {
87
-        color: ColorPalette.white,
88
-        fontSize: 22
89
-    },
90
-
91
     /**
12
     /**
92
      * Style of the ScrollView to be able to scroll the content.
13
      * Style of the ScrollView to be able to scroll the content.
93
      */
14
      */
96
     },
17
     },
97
 
18
 
98
     /**
19
     /**
99
-     * The back button style on the settings screen.
100
-     */
101
-    settingsBackButton: {
102
-        color: ColorPalette.white
103
-    },
104
-
105
-    /**
106
-     * The top level container {@code View}.
20
+     * Style of the settings screen content (form).
107
      */
21
      */
108
-    settingsContainer: {
109
-        backgroundColor: ColorPalette.white,
22
+    settingsForm: {
110
         flex: 1,
23
         flex: 1,
111
-        flexDirection: 'column',
112
-        margin: 0,
113
-        padding: CONTAINER_PADDING,
114
-        paddingTop: 0
24
+        margin: BoxModel.margin
115
     },
25
     },
116
 
26
 
117
     /**
27
     /**
118
      * Global {@code Text} color for the page.
28
      * Global {@code Text} color for the page.
119
      */
29
      */
120
     text: {
30
     text: {
121
-        color: ColorPalette.black,
122
-        fontSize: TEXT_SIZE
123
-    },
124
-
125
-    /**
126
-     * Standard text input field style.
127
-     */
128
-    textInputField: {
129
-        flex: 1,
130
-        fontSize: TEXT_SIZE,
131
-        textAlign: 'right'
31
+        color: ColorPalette.black
132
     }
32
     }
133
 });
33
 });

+ 56
- 0
react/features/base/react/components/native/Header.js View File

1
+// @flow
2
+
3
+import React, { Component } from 'react';
4
+import { SafeAreaView, StatusBar, View } from 'react-native';
5
+
6
+import styles, { STATUSBAR_COLOR } from './styles';
7
+
8
+/**
9
+ * The type of the React {@code Component} props of {@link ScreenHeader}
10
+ */
11
+type Props = {
12
+
13
+    /**
14
+     * Children component(s).
15
+     */
16
+    children: React$Node,
17
+
18
+    /**
19
+     * The component's external style
20
+     */
21
+    style: Object
22
+}
23
+
24
+/**
25
+ * A generic screen header component.
26
+ */
27
+export default class Header extends Component<Props> {
28
+    /**
29
+     * Implements React's {@link Component#render()}.
30
+     *
31
+     * @inheritdoc
32
+     */
33
+    render() {
34
+        return (
35
+            <View
36
+                style = { styles.headerOverlay } >
37
+                <StatusBar
38
+                    backgroundColor = { STATUSBAR_COLOR }
39
+                    barStyle = 'light-content'
40
+                    translucent = { false } />
41
+                <SafeAreaView>
42
+                    <View
43
+                        style = { [
44
+                            styles.screenHeader,
45
+                            this.props.style
46
+                        ] }>
47
+                        {
48
+                            this.props.children
49
+                        }
50
+                    </View>
51
+                </SafeAreaView>
52
+            </View>
53
+        );
54
+    }
55
+
56
+}

+ 2
- 0
react/features/base/react/components/native/index.js View File

1
 export { default as Container } from './Container';
1
 export { default as Container } from './Container';
2
 export { default as Link } from './Link';
2
 export { default as Link } from './Link';
3
 export { default as LoadingIndicator } from './LoadingIndicator';
3
 export { default as LoadingIndicator } from './LoadingIndicator';
4
+export { default as Header } from './Header';
5
+export * from './styles';
4
 export { default as TintedView } from './TintedView';
6
 export { default as TintedView } from './TintedView';
5
 export { default as Text } from './Text';
7
 export { default as Text } from './Text';

+ 39
- 0
react/features/base/react/components/native/styles.js View File

1
+import {
2
+    BoxModel,
3
+    ColorPalette,
4
+    createStyleSheet
5
+} from '../../../styles';
6
+
7
+const HEADER_COLOR = ColorPalette.blue;
8
+
9
+// Header height is from iOS guidelines. Also, this looks good.
10
+const HEADER_HEIGHT = 44;
11
+const HEADER_PADDING = BoxModel.padding;
12
+
13
+export const STATUSBAR_COLOR = ColorPalette.blueHighlight;
14
+
15
+/**
16
+ * The styles of the React {@code Components} of the generic components
17
+ * in the app.
18
+ */
19
+export default createStyleSheet({
20
+
21
+    /**
22
+     * Style of the header overlay to cover the unsafe areas.
23
+     */
24
+    headerOverlay: {
25
+        backgroundColor: HEADER_COLOR
26
+    },
27
+
28
+    /**
29
+     * Base style of Header
30
+     */
31
+    screenHeader: {
32
+        alignItems: 'center',
33
+        backgroundColor: HEADER_COLOR,
34
+        flexDirection: 'row',
35
+        height: HEADER_HEIGHT,
36
+        justifyContent: 'flex-start',
37
+        padding: HEADER_PADDING
38
+    }
39
+});

+ 0
- 1
react/features/base/react/index.js View File

1
 export * from './components';
1
 export * from './components';
2
-export * from './functions';
3
 export { default as Platform } from './Platform';
2
 export { default as Platform } from './Platform';
4
 export { default as RouteRegistry } from './RouteRegistry';
3
 export { default as RouteRegistry } from './RouteRegistry';

+ 1
- 0
react/features/base/styles/components/styles/ColorPalette.js View File

19
      */
19
      */
20
     black: BLACK,
20
     black: BLACK,
21
     blue: '#17A0DB',
21
     blue: '#17A0DB',
22
+    blueHighlight: '#1081b2',
22
     buttonUnderlay: '#495258',
23
     buttonUnderlay: '#495258',
23
     darkGrey: '#555555',
24
     darkGrey: '#555555',
24
     red: '#D00000',
25
     red: '#D00000',

+ 42
- 0
react/features/base/styles/components/styles/PlatformElements.native.js View File

1
+import { ColorPalette } from './ColorPalette';
2
+
3
+import {
4
+    createStyleSheet
5
+} from '../../functions';
6
+
7
+export const PlatformElements = createStyleSheet({
8
+
9
+    /**
10
+     * Platform specific header button (e.g. back, menu...etc).
11
+     */
12
+    headerButton: {
13
+        alignSelf: 'center',
14
+        color: ColorPalette.white,
15
+        fontSize: 26,
16
+        paddingRight: 22,
17
+        zIndex: 9999
18
+    },
19
+
20
+    /**
21
+     * Generic style for a label placed in the header.
22
+     */
23
+    headerText: {
24
+        color: ColorPalette.white,
25
+        fontSize: 20
26
+    },
27
+
28
+    /**
29
+     * The topmost level element of a page.
30
+     */
31
+    page: {
32
+        alignItems: 'stretch',
33
+        bottom: 0,
34
+        flex: 1,
35
+        flexDirection: 'column',
36
+        left: 0,
37
+        overflow: 'hidden',
38
+        position: 'absolute',
39
+        right: 0,
40
+        top: 0
41
+    }
42
+});

+ 0
- 0
react/features/base/styles/components/styles/PlatformElements.web.js View File


+ 1
- 0
react/features/base/styles/components/styles/index.js View File

1
 export * from './BoxModel';
1
 export * from './BoxModel';
2
 export * from './ColorPalette';
2
 export * from './ColorPalette';
3
+export * from './PlatformElements';

+ 2
- 1
react/features/conference/components/Conference.native.js View File

3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 
4
 
5
 // eslint-disable-next-line react-native/split-platform-components
5
 // eslint-disable-next-line react-native/split-platform-components
6
-import { BackAndroid, BackHandler, View } from 'react-native';
6
+import { BackAndroid, BackHandler, StatusBar, View } from 'react-native';
7
 import { connect as reactReduxConnect } from 'react-redux';
7
 import { connect as reactReduxConnect } from 'react-redux';
8
 
8
 
9
 import { appNavigate } from '../../app';
9
 import { appNavigate } from '../../app';
192
                 onClick = { this._onClick }
192
                 onClick = { this._onClick }
193
                 style = { styles.conference }
193
                 style = { styles.conference }
194
                 touchFeedback = { false }>
194
                 touchFeedback = { false }>
195
+                <StatusBar translucent = { true } />
195
 
196
 
196
                 {/*
197
                 {/*
197
                   * The LargeVideo is the lowermost stacking layer.
198
                   * The LargeVideo is the lowermost stacking layer.

Loading…
Cancel
Save