Selaa lähdekoodia

[RN] LocalVideoTrackUnderlay

Implement a React Component which displays children as an overlay of
local video. The WelcomePage implemented such a component inside of it
among other WelcomePage-specific logic so I split
LocalVideoTrackUnderlay out of it. The new Component is used on the
BlankPage which may be displayed in the future not only when the
WelcomePage is disabled but also when there are long running network
requests, for example.
j8
Lyubo Marinov 7 vuotta sitten
vanhempi
commit
a7ee632f43

+ 7
- 29
react/features/welcome/components/AbstractWelcomePage.js Näytä tiedosto

@@ -1,12 +1,10 @@
1 1
 import PropTypes from 'prop-types';
2
-import React, { Component } from 'react';
2
+import { Component } from 'react';
3 3
 
4 4
 import { appNavigate } from '../../app';
5 5
 import { isRoomValid } from '../../base/conference';
6
-import { VideoTrack } from '../../base/media';
7
-import { getLocalVideoTrack } from '../../base/tracks';
8 6
 
9
-import { generateRoomWithoutSeparator } from '../roomnameGenerator';
7
+import { generateRoomWithoutSeparator } from '../functions';
10 8
 
11 9
 /**
12 10
  * Base (abstract) class for container component rendering the welcome page.
@@ -15,12 +13,11 @@ import { generateRoomWithoutSeparator } from '../roomnameGenerator';
15 13
  */
16 14
 export class AbstractWelcomePage extends Component {
17 15
     /**
18
-     * {@code AbstractWelcomePage} component's property types.
16
+     * {@code AbstractWelcomePage}'s React {@code Component} prop types.
19 17
      *
20 18
      * @static
21 19
      */
22 20
     static propTypes = {
23
-        _localVideoTrack: PropTypes.object,
24 21
         _room: PropTypes.string,
25 22
         dispatch: PropTypes.func
26 23
     };
@@ -159,18 +156,6 @@ export class AbstractWelcomePage extends Component {
159 156
         this.setState({ room: value });
160 157
     }
161 158
 
162
-    /**
163
-     * Renders a local video if any.
164
-     *
165
-     * @protected
166
-     * @returns {(ReactElement|null)}
167
-     */
168
-    _renderLocalVideo() {
169
-        return (
170
-            <VideoTrack videoTrack = { this.props._localVideoTrack } />
171
-        );
172
-    }
173
-
174 159
     /**
175 160
      * Triggers the generation of a new room name and initiates an animation of
176 161
      * its changing.
@@ -195,24 +180,17 @@ export class AbstractWelcomePage extends Component {
195 180
 }
196 181
 
197 182
 /**
198
- * Selects local video track from tracks in state, local participant and room
199
- * and maps them to component props. It seems it's not possible to 'connect'
200
- * base component and then extend from it. So we export this function in order
201
- * to be used in child classes for 'connect'.
183
+ * Maps (parts of) the redux state to the React {@code Component} props of
184
+ * {@code AbstractWelcomePage}.
202 185
  *
203
- * @param {Object} state - Redux state.
186
+ * @param {Object} state - The redux state.
204 187
  * @protected
205 188
  * @returns {{
206
- *     _localVideoTrack: (Track|undefined),
207 189
  *     _room: string
208 190
  * }}
209 191
  */
210 192
 export function _mapStateToProps(state) {
211
-    const conference = state['features/base/conference'];
212
-    const tracks = state['features/base/tracks'];
213
-
214 193
     return {
215
-        _localVideoTrack: getLocalVideoTrack(tracks),
216
-        _room: conference.room
194
+        _room: state['features/base/conference'].room
217 195
     };
218 196
 }

+ 4
- 3
react/features/welcome/components/BlankPage.native.js Näytä tiedosto

@@ -2,12 +2,13 @@
2 2
 
3 3
 import PropTypes from 'prop-types';
4 4
 import React, { Component } from 'react';
5
-import { ActivityIndicator, View } from 'react-native';
5
+import { ActivityIndicator } from 'react-native';
6 6
 import { connect } from 'react-redux';
7 7
 
8 8
 import { destroyLocalTracks } from '../../base/tracks';
9 9
 
10 10
 import { isWelcomePageAppEnabled } from '../functions';
11
+import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay';
11 12
 import styles from './styles';
12 13
 
13 14
 /**
@@ -62,11 +63,11 @@ class BlankPage extends Component {
62 63
      */
63 64
     render() {
64 65
         return (
65
-            <View style = { styles.blankPage }>
66
+            <LocalVideoTrackUnderlay style = { styles.blankPage }>
66 67
                 <ActivityIndicator
67 68
                     animating = { this.props._networkActivity }
68 69
                     size = { 'large' } />
69
-            </View>
70
+            </LocalVideoTrackUnderlay>
70 71
         );
71 72
     }
72 73
 }

+ 117
- 0
react/features/welcome/components/LocalVideoTrackUnderlay.native.js Näytä tiedosto

@@ -0,0 +1,117 @@
1
+/* @flow */
2
+
3
+import PropTypes from 'prop-types';
4
+import React, { Component } from 'react';
5
+import { View } from 'react-native';
6
+import { connect } from 'react-redux';
7
+
8
+import { VideoTrack } from '../../base/media';
9
+import { getLocalVideoTrack } from '../../base/tracks';
10
+
11
+import styles from './styles';
12
+
13
+/**
14
+ * Implements a React {@code Component} which underlays the local video track,
15
+ * if any, underneath its children.
16
+ */
17
+class LocalVideoTrackUnderlay extends Component {
18
+    state: {
19
+
20
+        /**
21
+         * The style of <tt>LocalVideoTrackUnderlay</tt> which is a combination
22
+         * of its default style and the consumer-specified style.
23
+         */
24
+        style: Object
25
+    };
26
+
27
+    /**
28
+     * {@code LocalVideoTrackUnderlay}'s React {@code Component} prop types.
29
+     *
30
+     * @static
31
+     */
32
+    static propTypes = {
33
+        _localVideoTrack: PropTypes.object,
34
+        children: PropTypes.node,
35
+        style: PropTypes.object
36
+    };
37
+
38
+    /**
39
+     * Initializes a new {@code LocalVideoTrackUnderlay} instance.
40
+     *
41
+     * @param {Object} props - The read-only React {@code Component} props with
42
+     * which the new instance is to be initialized.
43
+     */
44
+    constructor(props) {
45
+        super(props);
46
+
47
+        this.componentWillReceiveProps(props);
48
+    }
49
+
50
+    /**
51
+     * Notifies this mounted React {@code Component} that it will receive new
52
+     * props. Forks (in Facebook/React speak) the prop {@code style} because its
53
+     * value is to be combined with the default style.
54
+     *
55
+     * @inheritdoc
56
+     * @param {Object} nextProps - The read-only React {@code Component} props
57
+     * that this instance will receive.
58
+     * @returns {void}
59
+     */
60
+    componentWillReceiveProps(nextProps) {
61
+        // style
62
+        const prevStyle = this.props && this.props.style;
63
+        const nextStyle = nextProps && nextProps.style;
64
+        const assignState = !this.state;
65
+
66
+        if (prevStyle !== nextStyle || assignState) {
67
+            const nextState = {
68
+                style: {
69
+                    ...styles.localVideoTrackUnderlay,
70
+                    ...nextStyle
71
+                }
72
+            };
73
+
74
+            if (assignState) {
75
+                this.state = nextState;
76
+            } else {
77
+                this.setState(nextState);
78
+            }
79
+        }
80
+    }
81
+
82
+    /**
83
+     * Implements React's {@link Component#render()}.
84
+     *
85
+     * @inheritdoc
86
+     * @override
87
+     * @returns {ReactElement}
88
+     */
89
+    render() {
90
+        return (
91
+            <View style = { this.state.style }>
92
+                <VideoTrack videoTrack = { this.props._localVideoTrack } />
93
+                <View style = { styles.localVideoTrackOverlay }>
94
+                    { this.props.children }
95
+                </View>
96
+            </View>
97
+        );
98
+    }
99
+}
100
+
101
+/**
102
+ * Maps (parts of) the redux state to the React {@code Component} props of
103
+ * {@code LocalVideoTrackUnderlay}.
104
+ *
105
+ * @param {Object} state - The redux state.
106
+ * @private
107
+ * @returns {{
108
+ *     _localVideoTrack: (Track|undefined)
109
+ * }}
110
+ */
111
+function _mapStateToProps(state) {
112
+    return {
113
+        _localVideoTrack: getLocalVideoTrack(state['features/base/tracks'])
114
+    };
115
+}
116
+
117
+export default connect(_mapStateToProps)(LocalVideoTrackUnderlay);

+ 0
- 0
react/features/welcome/components/LocalVideoTrackUnderlay.web.js Näytä tiedosto


+ 32
- 53
react/features/welcome/components/WelcomePage.native.js Näytä tiedosto

@@ -9,6 +9,7 @@ import { ColorPalette } from '../../base/styles';
9 9
 import { createDesiredLocalTracks } from '../../base/tracks';
10 10
 
11 11
 import { AbstractWelcomePage, _mapStateToProps } from './AbstractWelcomePage';
12
+import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay';
12 13
 import styles from './styles';
13 14
 
14 15
 /**
@@ -55,15 +56,40 @@ class WelcomePage extends AbstractWelcomePage {
55 56
      * @returns {ReactElement}
56 57
      */
57 58
     render() {
59
+        const { t } = this.props;
60
+
58 61
         return (
59
-            <View style = { styles.container }>
60
-                {
61
-                    this._renderLocalVideo()
62
-                }
62
+            <LocalVideoTrackUnderlay style = { styles.welcomePage }>
63
+                <View style = { styles.roomContainer }>
64
+                    <Text style = { styles.title }>
65
+                        { t('welcomepage.roomname') }
66
+                    </Text>
67
+                    <TextInput
68
+                        accessibilityLabel = { 'Input room name.' }
69
+                        autoCapitalize = 'none'
70
+                        autoComplete = { false }
71
+                        autoCorrect = { false }
72
+                        autoFocus = { false }
73
+                        onChangeText = { this._onRoomChange }
74
+                        placeholder = { t('welcomepage.roomnamePlaceHolder') }
75
+                        style = { styles.textInput }
76
+                        underlineColorAndroid = 'transparent'
77
+                        value = { this.state.room } />
78
+                    <TouchableHighlight
79
+                        accessibilityLabel = { 'Tap to Join.' }
80
+                        disabled = { this._isJoinDisabled() }
81
+                        onPress = { this._onJoin }
82
+                        style = { styles.button }
83
+                        underlayColor = { ColorPalette.white }>
84
+                        <Text style = { styles.buttonText }>
85
+                            { t('welcomepage.join') }
86
+                        </Text>
87
+                    </TouchableHighlight>
88
+                </View>
63 89
                 {
64
-                    this._renderLocalVideoOverlay()
90
+                    this._renderLegalese()
65 91
                 }
66
-            </View>
92
+            </LocalVideoTrackUnderlay>
67 93
         );
68 94
     }
69 95
 
@@ -97,53 +123,6 @@ class WelcomePage extends AbstractWelcomePage {
97 123
             </View>
98 124
         );
99 125
     }
100
-
101
-    /**
102
-     * Renders a View over the local video. The latter is thought of as the
103
-     * background (content) of this WelcomePage. The former is thought of as the
104
-     * foreground (content) of this WelcomePage such as the room name input, the
105
-     * button to initiate joining the specified room, etc.
106
-     *
107
-     * @private
108
-     * @returns {ReactElement}
109
-     */
110
-    _renderLocalVideoOverlay() {
111
-        const { t } = this.props;
112
-
113
-        return (
114
-            <View style = { styles.localVideoOverlay }>
115
-                <View style = { styles.roomContainer }>
116
-                    <Text style = { styles.title }>
117
-                        { t('welcomepage.roomname') }
118
-                    </Text>
119
-                    <TextInput
120
-                        accessibilityLabel = { 'Input room name.' }
121
-                        autoCapitalize = 'none'
122
-                        autoComplete = { false }
123
-                        autoCorrect = { false }
124
-                        autoFocus = { false }
125
-                        onChangeText = { this._onRoomChange }
126
-                        placeholder = { t('welcomepage.roomnamePlaceHolder') }
127
-                        style = { styles.textInput }
128
-                        underlineColorAndroid = 'transparent'
129
-                        value = { this.state.room } />
130
-                    <TouchableHighlight
131
-                        accessibilityLabel = { 'Tap to Join.' }
132
-                        disabled = { this._isJoinDisabled() }
133
-                        onPress = { this._onJoin }
134
-                        style = { styles.button }
135
-                        underlayColor = { ColorPalette.white }>
136
-                        <Text style = { styles.buttonText }>
137
-                            { t('welcomepage.join') }
138
-                        </Text>
139
-                    </TouchableHighlight>
140
-                </View>
141
-                {
142
-                    this._renderLegalese()
143
-                }
144
-            </View>
145
-        );
146
-    }
147 126
 }
148 127
 
149 128
 export default translate(connect(_mapStateToProps)(WelcomePage));

+ 26
- 25
react/features/welcome/components/styles.js Näytä tiedosto

@@ -16,14 +16,9 @@ const TEXT_COLOR = ColorPalette.white;
16 16
  */
17 17
 export default createStyleSheet({
18 18
     /**
19
-     * The style of <tt>BlankPage</tt>.
19
+     * The style of the top-level container of <tt>BlankPage</tt>.
20 20
      */
21 21
     blankPage: {
22
-        alignItems: 'center',
23
-        backgroundColor: 'transparent',
24
-        flex: 1,
25
-        flexDirection: 'column',
26
-        justifyContent: 'center'
27 22
     },
28 23
 
29 24
     /**
@@ -49,15 +44,6 @@ export default createStyleSheet({
49 44
         fontSize: 18
50 45
     },
51 46
 
52
-    /**
53
-     * The style of the top-level container of WelcomePage.
54
-     */
55
-    container: fixAndroidViewClipping({
56
-        alignSelf: 'stretch',
57
-        backgroundColor: ColorPalette.blue,
58
-        flex: 1
59
-    }),
60
-
61 47
     /**
62 48
      * The style of the legal-related content such as (hyper)links to Privacy
63 49
      * Policy and Terms of Service displayed on the WelcomePage.
@@ -80,27 +66,35 @@ export default createStyleSheet({
80 66
     },
81 67
 
82 68
     /**
83
-     * The style of the View displayed over the local video. The latter is
84
-     * thought of as the background (content) of WelcomePage. The former is
85
-     * thought of as the foreground (content) of WelcomePage.
69
+     * The style of the <tt>View</tt> displayed over the local video by
70
+     * <tt>LocalVideoTrackUnderlay</tt>. The latter is thought of as the
71
+     * background (content). The former is thought of as the foreground
72
+     * (content).
86 73
      */
87
-    localVideoOverlay: {
88
-        // Since (1) the top-level container of WelcomePage is not transparent
89
-        // and, more importantly, (2) this View is displayed over the local
90
-        // video, this View would better not have a background color.
91
-        // Otherwise, Views within this View will inherit its background color
92
-        // and Text, for example, will display non-transparent rectangles over
93
-        // the local video.
74
+    localVideoTrackOverlay: {
94 75
         backgroundColor: 'transparent',
95 76
         bottom: 0,
96 77
         flex: 1,
97 78
         flexDirection: 'column',
79
+        justifyContent: 'center',
98 80
         left: 0,
99 81
         position: 'absolute',
100 82
         right: 0,
101 83
         top: 0
102 84
     },
103 85
 
86
+    /**
87
+     * The style of the top-level container/<tt>View</tt> of
88
+     * <tt>LocalVideoTrackUnderlay</tt>.
89
+     */
90
+    localVideoTrackUnderlay: fixAndroidViewClipping({
91
+        alignItems: 'center',
92
+        alignSelf: 'stretch',
93
+        backgroundColor: 'transparent',
94
+        flex: 1,
95
+        justifyContent: 'center'
96
+    }),
97
+
104 98
     /**
105 99
      * Container for room name input box and 'join' button.
106 100
      */
@@ -134,5 +128,12 @@ export default createStyleSheet({
134 128
         fontSize: 25,
135 129
         marginBottom: 2 * BoxModel.margin,
136 130
         textAlign: 'center'
131
+    },
132
+
133
+    /**
134
+     * The style of the top-level container of <tt>WelcomePage</tt>.
135
+     */
136
+    welcomePage: {
137
+        backgroundColor: ColorPalette.blue
137 138
     }
138 139
 });

Loading…
Peruuta
Tallenna