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

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
 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 TintedView } from './TintedView';
4
 export { default as Text } from './Text';
5
 export { default as Text } from './Text';

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

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

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

18
         flex: 1
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
      * The style of the {@link View} which expands over the whole
22
      * The style of the {@link View} which expands over the whole
46
      * {@link Conference} area and splits it between the {@link Filmstrip} and
23
      * {@link Conference} area and splits it between the {@link Filmstrip} and

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

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

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

65
         margin: BoxModel.margin
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
      * The style of the top-level container/{@code View} of
69
      * The style of the top-level container/{@code View} of
88
      * {@code LocalVideoTrackUnderlay}.
70
      * {@code LocalVideoTrackUnderlay}.
97
      * Container for room name input box and 'join' button.
79
      * Container for room name input box and 'join' button.
98
      */
80
      */
99
     roomContainer: {
81
     roomContainer: {
82
+        alignSelf: 'stretch',
100
         flex: 1,
83
         flex: 1,
101
         flexDirection: 'column',
84
         flexDirection: 'column',
102
         justifyContent: 'center',
85
         justifyContent: 'center',

Loading…
Cancel
Save