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
     static propTypes = {
21
     static propTypes = {
22
         dispatch: PropTypes.func,
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
         videoTrack: PropTypes.object,
30
         videoTrack: PropTypes.object,
25
 
31
 
26
         waitForVideoStarted: PropTypes.bool,
32
         waitForVideoStarted: PropTypes.bool,
106
             <Video
112
             <Video
107
                 mirror = { videoTrack && videoTrack.mirror }
113
                 mirror = { videoTrack && videoTrack.mirror }
108
                 onPlaying = { this._onVideoPlaying }
114
                 onPlaying = { this._onVideoPlaying }
115
+                onPress = { this.props.onPress }
109
                 stream = { stream }
116
                 stream = { stream }
110
                 zOrder = { this.props.zOrder } />
117
                 zOrder = { this.props.zOrder } />
111
         );
118
         );
120
     _onVideoPlaying() {
127
     _onVideoPlaying() {
121
         const videoTrack = this.props.videoTrack;
128
         const videoTrack = this.props.videoTrack;
122
 
129
 
123
-        if (videoTrack
124
-            && !videoTrack.videoStarted) {
130
+        if (videoTrack && !videoTrack.videoStarted) {
125
             this.props.dispatch(trackVideoStarted(videoTrack.jitsiTrack));
131
             this.props.dispatch(trackVideoStarted(videoTrack.jitsiTrack));
126
         }
132
         }
127
     }
133
     }

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

1
-/* @flow */
1
+// @flow
2
 
2
 
3
 import PropTypes from 'prop-types';
3
 import PropTypes from 'prop-types';
4
 import React, { Component } from 'react';
4
 import React, { Component } from 'react';
5
 import { RTCView } from 'react-native-webrtc';
5
 import { RTCView } from 'react-native-webrtc';
6
 
6
 
7
+import { Pressable } from '../../../react';
8
+
7
 import styles from './styles';
9
 import styles from './styles';
8
 
10
 
9
 /**
11
 /**
19
      */
21
      */
20
     static propTypes = {
22
     static propTypes = {
21
         mirror: PropTypes.bool,
23
         mirror: PropTypes.bool,
24
+
22
         onPlaying: PropTypes.func,
25
         onPlaying: PropTypes.func,
26
+
27
+        /**
28
+         * Callback to invoke when the {@code Video} is clicked/pressed.
29
+         */
30
+        onPress: PropTypes.func,
31
+
23
         stream: PropTypes.object,
32
         stream: PropTypes.object,
24
 
33
 
25
         /**
34
         /**
82
             const style = styles.video;
91
             const style = styles.video;
83
             const objectFit = (style && style.objectFit) || 'cover';
92
             const objectFit = (style && style.objectFit) || 'cover';
84
 
93
 
85
-            // eslint-disable-next-line no-extra-parens
86
             return (
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
      */
70
      */
71
     avatarSize: number,
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
      * The ID of the participant (to be) depicted by {@link ParticipantView}.
79
      * The ID of the participant (to be) depicted by {@link ParticipantView}.
75
      *
80
      *
176
      */
181
      */
177
     render() {
182
     render() {
178
         const {
183
         const {
184
+            onPress,
179
             _avatar: avatar,
185
             _avatar: avatar,
180
             _connectionStatus: connectionStatus,
186
             _connectionStatus: connectionStatus,
181
             _videoTrack: videoTrack
187
             _videoTrack: videoTrack
190
         // doesn't retain the last frame forever, so we would end up with a
196
         // doesn't retain the last frame forever, so we would end up with a
191
         // black screen.
197
         // black screen.
192
         const waitForVideoStarted = false;
198
         const waitForVideoStarted = false;
193
-        const renderVideo
199
+        let renderVideo
194
             = !this.props._audioOnly
200
             = !this.props._audioOnly
195
                 && (connectionStatus
201
                 && (connectionStatus
196
                     === JitsiParticipantConnectionStatus.ACTIVE)
202
                     === JitsiParticipantConnectionStatus.ACTIVE)
197
                 && shouldRenderVideoTrack(videoTrack, waitForVideoStarted);
203
                 && shouldRenderVideoTrack(videoTrack, waitForVideoStarted);
198
 
204
 
199
         // Is the avatar to be rendered?
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
         const useTint
219
         const useTint
204
             = connectionStatus === JitsiParticipantConnectionStatus.INACTIVE
220
             = connectionStatus === JitsiParticipantConnectionStatus.INACTIVE
205
                 || connectionStatus
221
                 || connectionStatus
207
 
223
 
208
         return (
224
         return (
209
             <Container
225
             <Container
226
+                onClick = { renderVideo ? undefined : onPress }
210
                 style = {{
227
                 style = {{
211
                     ...styles.participantView,
228
                     ...styles.participantView,
212
                     ...this.props.style
229
                     ...this.props.style
213
-                }}>
230
+                }}
231
+                touchFeedback = { false }>
214
 
232
 
215
                 { renderVideo
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
                     && <VideoTrack
234
                     && <VideoTrack
235
+                        onPress = { renderVideo ? onPress : undefined }
223
                         videoTrack = { videoTrack }
236
                         videoTrack = { videoTrack }
224
                         waitForVideoStarted = { waitForVideoStarted }
237
                         waitForVideoStarted = { waitForVideoStarted }
225
                         zOrder = { this.props.zOrder } /> }
238
                         zOrder = { this.props.zOrder } /> }
226
 
239
 
227
                 { renderAvatar
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
                     && <Avatar
241
                     && <Avatar
235
                         size = { this.props.avatarSize }
242
                         size = { this.props.avatarSize }
236
                         uri = { avatar } /> }
243
                         uri = { avatar } /> }

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

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
 export { default as NavigateSectionList } from './NavigateSectionList';
3
 export { default as NavigateSectionList } from './NavigateSectionList';
4
 export { default as Link } from './Link';
4
 export { default as Link } from './Link';
5
 export { default as LoadingIndicator } from './LoadingIndicator';
5
 export { default as LoadingIndicator } from './LoadingIndicator';
6
+export { default as Pressable } from './Pressable';
6
 export { default as SideBar } from './SideBar';
7
 export { default as SideBar } from './SideBar';
7
 export { default as Text } from './Text';
8
 export { default as Text } from './Text';
8
 export { default as TintedView } from './TintedView';
9
 export { default as TintedView } from './TintedView';

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

190
             <Container
190
             <Container
191
                 accessibilityLabel = 'Conference'
191
                 accessibilityLabel = 'Conference'
192
                 accessible = { false }
192
                 accessible = { false }
193
-                onClick = { this._onClick }
194
-                style = { styles.conference }
195
-                touchFeedback = { false }>
193
+                style = { styles.conference }>
196
                 <StatusBar
194
                 <StatusBar
197
                     hidden = { true }
195
                     hidden = { true }
198
                     translucent = { true } />
196
                     translucent = { true } />
200
                 {/*
198
                 {/*
201
                   * The LargeVideo is the lowermost stacking layer.
199
                   * The LargeVideo is the lowermost stacking layer.
202
                   */}
200
                   */}
203
-                <LargeVideo />
201
+                <LargeVideo onPress = { this._onClick } />
204
 
202
 
205
                 {/*
203
                 {/*
206
                   * If there is a ringing call, show the callee's info.
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
  */
13
  */
14
 type Props = {
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
      * The ID of the participant (to be) depicted by LargeVideo.
22
      * The ID of the participant (to be) depicted by LargeVideo.
18
      *
23
      *
107
             avatarSize,
112
             avatarSize,
108
             useConnectivityInfoLabel
113
             useConnectivityInfoLabel
109
         } = this.state;
114
         } = this.state;
115
+        const {
116
+            onPress,
117
+            _participantId
118
+        } = this.props;
110
 
119
 
111
         return (
120
         return (
112
             <DimensionsDetector
121
             <DimensionsDetector
113
-                onDimensionsChanged = { this._onDimensionsChanged } >
122
+                onDimensionsChanged = { this._onDimensionsChanged }>
114
                 <ParticipantView
123
                 <ParticipantView
115
                     avatarSize = { avatarSize }
124
                     avatarSize = { avatarSize }
116
-                    participantId = { this.props._participantId }
125
+                    onPress = { onPress }
126
+                    participantId = { _participantId }
117
                     style = { styles.largeVideo }
127
                     style = { styles.largeVideo }
118
                     useConnectivityInfoLabel = { useConnectivityInfoLabel }
128
                     useConnectivityInfoLabel = { useConnectivityInfoLabel }
119
                     zOrder = { 0 } />
129
                     zOrder = { 0 } />

Loading…
Cancel
Save