Browse Source

[RN] Don't press on Conference in preparation for 'pinch to zoom'

TouchableWithoutFeedback and TouchableHighlight interfere with the
implementation of 'pinch to zoom' to come. We prepare for it by driving
the onClick/onPress handler(s) out of Conference, through LargeVideo and
ParticipantView into Video itself where the bulk of 'pinch to zoom' will
be implemented.
master
Zoltan Bettenbuk 7 years ago
parent
commit
decbcefbd4

+ 8
- 2
react/features/base/media/components/AbstractVideoTrack.js View File

@@ -21,6 +21,12 @@ export default class AbstractVideoTrack extends Component {
21 21
     static propTypes = {
22 22
         dispatch: PropTypes.func,
23 23
 
24
+        /**
25
+         * Callback to invoke when the {@link Video} of
26
+         * {@code AbstractVideoTrack} is clicked/pressed.
27
+         */
28
+        onPress: PropTypes.func,
29
+
24 30
         videoTrack: PropTypes.object,
25 31
 
26 32
         waitForVideoStarted: PropTypes.bool,
@@ -106,6 +112,7 @@ export default class AbstractVideoTrack extends Component {
106 112
             <Video
107 113
                 mirror = { videoTrack && videoTrack.mirror }
108 114
                 onPlaying = { this._onVideoPlaying }
115
+                onPress = { this.props.onPress }
109 116
                 stream = { stream }
110 117
                 zOrder = { this.props.zOrder } />
111 118
         );
@@ -120,8 +127,7 @@ export default class AbstractVideoTrack extends Component {
120 127
     _onVideoPlaying() {
121 128
         const videoTrack = this.props.videoTrack;
122 129
 
123
-        if (videoTrack
124
-            && !videoTrack.videoStarted) {
130
+        if (videoTrack && !videoTrack.videoStarted) {
125 131
             this.props.dispatch(trackVideoStarted(videoTrack.jitsiTrack));
126 132
         }
127 133
     }

+ 18
- 8
react/features/base/media/components/native/Video.js View File

@@ -1,9 +1,11 @@
1
-/* @flow */
1
+// @flow
2 2
 
3 3
 import PropTypes from 'prop-types';
4 4
 import React, { Component } from 'react';
5 5
 import { RTCView } from 'react-native-webrtc';
6 6
 
7
+import { Pressable } from '../../../react';
8
+
7 9
 import styles from './styles';
8 10
 
9 11
 /**
@@ -19,7 +21,14 @@ export default class Video extends Component<*> {
19 21
      */
20 22
     static propTypes = {
21 23
         mirror: PropTypes.bool,
24
+
22 25
         onPlaying: PropTypes.func,
26
+
27
+        /**
28
+         * Callback to invoke when the {@code Video} is clicked/pressed.
29
+         */
30
+        onPress: PropTypes.func,
31
+
23 32
         stream: PropTypes.object,
24 33
 
25 34
         /**
@@ -82,14 +91,15 @@ export default class Video extends Component<*> {
82 91
             const style = styles.video;
83 92
             const objectFit = (style && style.objectFit) || 'cover';
84 93
 
85
-            // eslint-disable-next-line no-extra-parens
86 94
             return (
87
-                <RTCView
88
-                    mirror = { this.props.mirror }
89
-                    objectFit = { objectFit }
90
-                    streamURL = { streamURL }
91
-                    style = { style }
92
-                    zOrder = { this.props.zOrder } />
95
+                <Pressable onPress = { this.props.onPress }>
96
+                    <RTCView
97
+                        mirror = { this.props.mirror }
98
+                        objectFit = { objectFit }
99
+                        streamURL = { streamURL }
100
+                        style = { style }
101
+                        zOrder = { this.props.zOrder } />
102
+                </Pressable>
93 103
             );
94 104
         }
95 105
 

+ 23
- 16
react/features/base/participants/components/ParticipantView.native.js View File

@@ -70,6 +70,11 @@ type Props = {
70 70
      */
71 71
     avatarSize: number,
72 72
 
73
+    /**
74
+     * Callback to invoke when the {@code ParticipantView} is clicked/pressed.
75
+     */
76
+    onPress: Function,
77
+
73 78
     /**
74 79
      * The ID of the participant (to be) depicted by {@link ParticipantView}.
75 80
      *
@@ -176,6 +181,7 @@ class ParticipantView extends Component<Props> {
176 181
      */
177 182
     render() {
178 183
         const {
184
+            onPress,
179 185
             _avatar: avatar,
180 186
             _connectionStatus: connectionStatus,
181 187
             _videoTrack: videoTrack
@@ -190,16 +196,26 @@ class ParticipantView extends Component<Props> {
190 196
         // doesn't retain the last frame forever, so we would end up with a
191 197
         // black screen.
192 198
         const waitForVideoStarted = false;
193
-        const renderVideo
199
+        let renderVideo
194 200
             = !this.props._audioOnly
195 201
                 && (connectionStatus
196 202
                     === JitsiParticipantConnectionStatus.ACTIVE)
197 203
                 && shouldRenderVideoTrack(videoTrack, waitForVideoStarted);
198 204
 
199 205
         // Is the avatar to be rendered?
200
-        const renderAvatar = Boolean(!renderVideo && avatar);
206
+        let renderAvatar = Boolean(!renderVideo && avatar);
207
+
208
+        // The consumer of this ParticipantView is allowed to forbid showing the
209
+        // video if the private logic of this ParticipantView determines that
210
+        // the video could be rendered.
211
+        renderVideo = renderVideo && _toBoolean(this.props.showVideo, true);
201 212
 
202
-        // If the connection has problems we will "tint" the video / avatar.
213
+        // The consumer of this ParticipantView is allowed to forbid showing the
214
+        // avatar if the private logic of this ParticipantView determines that
215
+        // the avatar could be rendered.
216
+        renderAvatar = renderAvatar && _toBoolean(this.props.showAvatar, true);
217
+
218
+        // If the connection has problems, we will "tint" the video / avatar.
203 219
         const useTint
204 220
             = connectionStatus === JitsiParticipantConnectionStatus.INACTIVE
205 221
                 || connectionStatus
@@ -207,30 +223,21 @@ class ParticipantView extends Component<Props> {
207 223
 
208 224
         return (
209 225
             <Container
226
+                onClick = { renderVideo ? undefined : onPress }
210 227
                 style = {{
211 228
                     ...styles.participantView,
212 229
                     ...this.props.style
213
-                }}>
230
+                }}
231
+                touchFeedback = { false }>
214 232
 
215 233
                 { renderVideo
216
-
217
-                    // The consumer of this ParticipantView is allowed to forbid
218
-                    // showing the video if the private logic of this
219
-                    // ParticipantView determines that the video could be
220
-                    // rendered.
221
-                    && _toBoolean(this.props.showVideo, true)
222 234
                     && <VideoTrack
235
+                        onPress = { renderVideo ? onPress : undefined }
223 236
                         videoTrack = { videoTrack }
224 237
                         waitForVideoStarted = { waitForVideoStarted }
225 238
                         zOrder = { this.props.zOrder } /> }
226 239
 
227 240
                 { renderAvatar
228
-
229
-                    // The consumer of this ParticipantView is allowed to forbid
230
-                    // showing the avatar if the private logic of this
231
-                    // ParticipantView determines that the avatar could be
232
-                    // rendered.
233
-                    && _toBoolean(this.props.showAvatar, true)
234 241
                     && <Avatar
235 242
                         size = { this.props.avatarSize }
236 243
                         uri = { avatar } /> }

+ 46
- 0
react/features/base/react/components/native/Pressable.js View File

@@ -0,0 +1,46 @@
1
+// @flow
2
+
3
+import React, { Component } from 'react';
4
+import { TouchableWithoutFeedback } from 'react-native';
5
+
6
+/**
7
+ * The type of the React {@link Component} props of {@link Pressable}.
8
+ */
9
+type Props = {
10
+    children: React$Node,
11
+
12
+    /**
13
+     * Called when the touch is released, but not if cancelled (e.g. by a scroll
14
+     * that steals the responder lock).
15
+     */
16
+    onPress: Function
17
+};
18
+
19
+/**
20
+ * Adds support for {@code onPress} to a child React {@link Component} (which
21
+ * should probably not support the prop in question; otherwise, there's little
22
+ * point of using {@code Pressable} then in the first place).
23
+ */
24
+export default class Pressable extends Component<Props> {
25
+    /**
26
+     * Implements React's {@link Component#render()}.
27
+     *
28
+     * @inheritdoc
29
+     * @returns {React$Node}
30
+     */
31
+    render() {
32
+        // onPress
33
+        const { children, onPress } = this.props;
34
+
35
+        if (onPress) {
36
+            return (
37
+                <TouchableWithoutFeedback onPress = { onPress }>
38
+                    { children }
39
+                </TouchableWithoutFeedback>
40
+            );
41
+        }
42
+
43
+        // A Pressable without an onPress is a "no-op".
44
+        return children;
45
+    }
46
+}

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

@@ -3,6 +3,7 @@ export { default as Header } from './Header';
3 3
 export { default as NavigateSectionList } from './NavigateSectionList';
4 4
 export { default as Link } from './Link';
5 5
 export { default as LoadingIndicator } from './LoadingIndicator';
6
+export { default as Pressable } from './Pressable';
6 7
 export { default as SideBar } from './SideBar';
7 8
 export { default as Text } from './Text';
8 9
 export { default as TintedView } from './TintedView';

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

@@ -190,9 +190,7 @@ class Conference extends Component<Props> {
190 190
             <Container
191 191
                 accessibilityLabel = 'Conference'
192 192
                 accessible = { false }
193
-                onClick = { this._onClick }
194
-                style = { styles.conference }
195
-                touchFeedback = { false }>
193
+                style = { styles.conference }>
196 194
                 <StatusBar
197 195
                     hidden = { true }
198 196
                     translucent = { true } />
@@ -200,7 +198,7 @@ class Conference extends Component<Props> {
200 198
                 {/*
201 199
                   * The LargeVideo is the lowermost stacking layer.
202 200
                   */}
203
-                <LargeVideo />
201
+                <LargeVideo onPress = { this._onClick } />
204 202
 
205 203
                 {/*
206 204
                   * If there is a ringing call, show the callee's info.

+ 12
- 2
react/features/large-video/components/LargeVideo.native.js View File

@@ -13,6 +13,11 @@ import styles, { AVATAR_SIZE } from './styles';
13 13
  */
14 14
 type Props = {
15 15
 
16
+    /**
17
+     * Callback to invoke when the {@code LargeVideo} is clicked/pressed.
18
+     */
19
+    onPress: Function,
20
+
16 21
     /**
17 22
      * The ID of the participant (to be) depicted by LargeVideo.
18 23
      *
@@ -107,13 +112,18 @@ class LargeVideo extends Component<Props, State> {
107 112
             avatarSize,
108 113
             useConnectivityInfoLabel
109 114
         } = this.state;
115
+        const {
116
+            onPress,
117
+            _participantId
118
+        } = this.props;
110 119
 
111 120
         return (
112 121
             <DimensionsDetector
113
-                onDimensionsChanged = { this._onDimensionsChanged } >
122
+                onDimensionsChanged = { this._onDimensionsChanged }>
114 123
                 <ParticipantView
115 124
                     avatarSize = { avatarSize }
116
-                    participantId = { this.props._participantId }
125
+                    onPress = { onPress }
126
+                    participantId = { _participantId }
117 127
                     style = { styles.largeVideo }
118 128
                     useConnectivityInfoLabel = { useConnectivityInfoLabel }
119 129
                     zOrder = { 0 } />

Loading…
Cancel
Save