Browse Source

[RN] Add TintedView component

It's designed to cover a container and give it a "tint" by using a color and
opacity.
master
Saúl Ibarra Corretgé 7 years ago
parent
commit
ac09233558

+ 140
- 0
react/features/base/react/components/native/TintedView.js View File

@@ -0,0 +1,140 @@
1
+// @flow
2
+
3
+import React, { Component } from 'react';
4
+import { View } from 'react-native';
5
+
6
+import { ColorPalette } from '../../../styles';
7
+
8
+/**
9
+ * Base style for the {@code TintedView} component.
10
+ */
11
+const BASE_STYLE = {
12
+    alignItems: 'center',
13
+    bottom: 0,
14
+    justifyContent: 'center',
15
+    left: 0,
16
+    position: 'absolute',
17
+    right: 0,
18
+    top: 0
19
+};
20
+
21
+/**
22
+ * {@code TintedView}'s React {@code Component} prop types.
23
+ */
24
+type Props = {
25
+
26
+    /**
27
+     * The children components of this component.
28
+     */
29
+    children?: React$Node,
30
+
31
+    /**
32
+     * Color used as the background of the view. Defaults to
33
+     */
34
+    color: string,
35
+
36
+    /**
37
+     * Opacity for the
38
+     */
39
+    opacity: number,
40
+
41
+    /**
42
+     * Style to override the base style.
43
+     */
44
+    style: Object
45
+};
46
+
47
+/**
48
+ * {@code TintedView}'s React {@code Component} state.
49
+ */
50
+type State = {
51
+
52
+    /**
53
+     * The style of {@code TintedView} which is a combination of its default
54
+     * style, the consumer-specified style.
55
+     */
56
+    style: Object
57
+};
58
+
59
+/**
60
+ * Implements a component aimed at covering another view and tinting it with
61
+ * the given color and opacity.
62
+ */
63
+export default class TintedView extends Component<Props, State> {
64
+    /**
65
+     * Default values for the component's props.
66
+     */
67
+    static defaultProps = {
68
+        color: ColorPalette.appBackground,
69
+        opacity: 0.8,
70
+        style: {}
71
+    };
72
+
73
+    /**
74
+     * Initializes a new {@code TintedView} instance.
75
+     *
76
+     * @param {Object} props - The read-only React {@code Component} props with
77
+     * which the new instance is to be initialized.
78
+     */
79
+    constructor(props: Object) {
80
+        super(props);
81
+
82
+        this.componentWillReceiveProps(props);
83
+    }
84
+
85
+    /**
86
+     * Notifies this mounted React {@code Component} that it will receive new
87
+     * props. Forks (in Facebook/React speak) the prop {@code style} because its
88
+     * value is to be combined with the default style.
89
+     *
90
+     * @inheritdoc
91
+     * @param {Object} nextProps - The read-only React {@code Component} props
92
+     * that this instance will receive.
93
+     * @returns {void}
94
+     */
95
+    componentWillReceiveProps(nextProps: Object) {
96
+        // style
97
+        const prevColor = this.props && this.props.color;
98
+        const prevOpacity = this.props && this.props.opacity;
99
+        const prevStyle = this.props && this.props.style;
100
+
101
+        const nextColor = nextProps && nextProps.color;
102
+        const nextOpacity = nextProps && nextProps.opacity;
103
+        const nextStyle = nextProps && nextProps.style;
104
+
105
+        const assignState = !this.state;
106
+
107
+        if (prevColor !== nextColor || prevOpacity !== nextOpacity
108
+                || prevStyle !== nextStyle || assignState) {
109
+            const nextState = {
110
+                style: {
111
+                    ...BASE_STYLE,
112
+                    ...nextStyle,
113
+                    backgroundColor: nextColor,
114
+                    opacity: nextOpacity
115
+                }
116
+            };
117
+
118
+            if (assignState) {
119
+                // eslint-disable-next-line react/no-direct-mutation-state
120
+                this.state = nextState;
121
+            } else {
122
+                this.setState(nextState);
123
+            }
124
+        }
125
+    }
126
+
127
+    /**
128
+     * Implements React's {@link Component#render()}.
129
+     *
130
+     * @inheritdoc
131
+     * @returns {ReactElement}
132
+     */
133
+    render() {
134
+        return (
135
+            <View style = { this.state.style }>
136
+                { this.props.children }
137
+            </View>
138
+        );
139
+    }
140
+}

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

@@ -1,4 +1,5 @@
1 1
 export { default as Container } from './Container';
2 2
 export { default as Link } from './Link';
3 3
 export { default as LoadingIndicator } from './LoadingIndicator';
4
+export { default as TintedView } from './TintedView';
4 5
 export { default as Text } from './Text';

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

@@ -10,7 +10,7 @@ import { appNavigate } from '../../app';
10 10
 import { connect, disconnect } from '../../base/connection';
11 11
 import { DialogContainer } from '../../base/dialog';
12 12
 import { CalleeInfoContainer } from '../../base/jwt';
13
-import { Container, LoadingIndicator } from '../../base/react';
13
+import { Container, LoadingIndicator, TintedView } from '../../base/react';
14 14
 import { createDesiredLocalTracks } from '../../base/tracks';
15 15
 import { Filmstrip } from '../../filmstrip';
16 16
 import { LargeVideo } from '../../large-video';
@@ -200,9 +200,9 @@ class Conference extends Component<Props> {
200 200
                   * the toolbox/toolbars and the dialogs.
201 201
                   */
202 202
                     this.props._connecting
203
-                        && <View style = { styles.connectingIndicator }>
203
+                        && <TintedView>
204 204
                             <LoadingIndicator />
205
-                        </View>
205
+                        </TintedView>
206 206
                 }
207 207
 
208 208
                 <View style = { styles.toolboxAndFilmstripContainer } >

+ 0
- 23
react/features/conference/components/styles.js View File

@@ -18,29 +18,6 @@ export default createStyleSheet({
18 18
         flex: 1
19 19
     }),
20 20
 
21
-    /**
22
-     * The style of the View rendered while the conference is being connected
23
-     * (i.e. the XMPP connection is being established and the MUC is being
24
-     * joined).
25
-     */
26
-    connectingIndicator: {
27
-        alignItems: 'center',
28
-        bottom: 0,
29
-        justifyContent: 'center',
30
-        left: 0,
31
-        position: 'absolute',
32
-        right: 0,
33
-        top: 0,
34
-
35
-        // Because the background of LargeVideo varies wildly (e.g. the
36
-        // participant's video or avatar), the LoadingIndicator may be difficult
37
-        // to see. Reduce the variance of the background of LargeVideo and,
38
-        // thus, increase the visibility of LoadingIndicator by introducing
39
-        // contrast and translucency.
40
-        backgroundColor: ColorPalette.appBackground,
41
-        opacity: 0.5
42
-    },
43
-
44 21
     /**
45 22
      * The style of the {@link View} which expands over the whole
46 23
      * {@link Conference} area and splits it between the {@link Filmstrip} and

+ 3
- 2
react/features/welcome/components/LocalVideoTrackUnderlay.native.js View File

@@ -6,6 +6,7 @@ import { View } from 'react-native';
6 6
 import { connect } from 'react-redux';
7 7
 
8 8
 import { VideoTrack } from '../../base/media';
9
+import { TintedView } from '../../base/react';
9 10
 import { getLocalVideoTrack } from '../../base/tracks';
10 11
 
11 12
 import styles from './styles';
@@ -91,9 +92,9 @@ class LocalVideoTrackUnderlay extends Component<*, *> {
91 92
         return (
92 93
             <View style = { this.state.style }>
93 94
                 <VideoTrack videoTrack = { this.props._localVideoTrack } />
94
-                <View style = { styles.localVideoTrackOverlay }>
95
+                <TintedView>
95 96
                     { this.props.children }
96
-                </View>
97
+                </TintedView>
97 98
             </View>
98 99
         );
99 100
     }

+ 1
- 18
react/features/welcome/components/styles.js View File

@@ -65,24 +65,6 @@ export default createStyleSheet({
65 65
         margin: BoxModel.margin
66 66
     },
67 67
 
68
-    /**
69
-     * The style of the {@code View} displayed over the local video by
70
-     * {@code LocalVideoTrackUnderlay}. The latter is thought of as the
71
-     * background (content). The former is thought of as the foreground
72
-     * (content).
73
-     */
74
-    localVideoTrackOverlay: {
75
-        backgroundColor: 'transparent',
76
-        bottom: 0,
77
-        flex: 1,
78
-        flexDirection: 'column',
79
-        justifyContent: 'center',
80
-        left: 0,
81
-        position: 'absolute',
82
-        right: 0,
83
-        top: 0
84
-    },
85
-
86 68
     /**
87 69
      * The style of the top-level container/{@code View} of
88 70
      * {@code LocalVideoTrackUnderlay}.
@@ -97,6 +79,7 @@ export default createStyleSheet({
97 79
      * Container for room name input box and 'join' button.
98 80
      */
99 81
     roomContainer: {
82
+        alignSelf: 'stretch',
100 83
         flex: 1,
101 84
         flexDirection: 'column',
102 85
         justifyContent: 'center',

Loading…
Cancel
Save