浏览代码

fix(rn,bottom-sheet) fix scroll

In the past we used a PanResponder to detect user gestures in the sheet
to show a reduced version or a full-height version of it, and also to
close it.

There is an obvious conflic between the gestures and scrolling, which
didn't work all that great, but we could live with it.

After reactions were introduced we no longer rendered the 2 different
heights, so that functionaligy stopped being used but the PanResponder
still remained there.

This commit removes it completely and sets a max height of 75% on any
BottomSheet, so any tap outside will close it.
master
Saúl Ibarra Corretgé 3 年前
父节点
当前提交
ad8cdcd81b

+ 8
- 118
react/features/base/dialog/components/native/BottomSheet.js 查看文件

1
-// @flow
2
-
3
 import React, { PureComponent, type Node } from 'react';
1
 import React, { PureComponent, type Node } from 'react';
4
-import { PanResponder, SafeAreaView, ScrollView, View } from 'react-native';
2
+import { SafeAreaView, ScrollView, View } from 'react-native';
5
 
3
 
6
-import { ColorSchemeRegistry } from '../../../color-scheme';
7
 import { SlidingView } from '../../../react';
4
 import { SlidingView } from '../../../react';
8
-import { connect } from '../../../redux';
9
-import { StyleType } from '../../../styles';
10
 
5
 
11
 import { bottomSheetStyles as styles } from './styles';
6
 import { bottomSheetStyles as styles } from './styles';
12
 
7
 
13
-/**
14
- * Minimal distance that needs to be moved by the finger to consider it a swipe.
15
- */
16
-const GESTURE_DISTANCE_THRESHOLD = 5;
17
-
18
-/**
19
- * The minimal speed needed to be achieved by the finger to consider it as a swipe.
20
- */
21
-const GESTURE_SPEED_THRESHOLD = 0.2;
22
-
23
 /**
8
 /**
24
  * The type of {@code BottomSheet}'s React {@code Component} prop types.
9
  * The type of {@code BottomSheet}'s React {@code Component} prop types.
25
  */
10
  */
26
 type Props = {
11
 type Props = {
27
 
12
 
28
-    /**
29
-     * The height of the screen.
30
-     */
31
-    _height: number,
32
-
33
-    /**
34
-     * The color-schemed stylesheet of the feature.
35
-     */
36
-    _styles: StyleType,
37
-
38
     /**
13
     /**
39
      * Whether to add padding to scroll view.
14
      * Whether to add padding to scroll view.
40
      */
15
      */
51
      */
26
      */
52
     onCancel: ?Function,
27
     onCancel: ?Function,
53
 
28
 
54
-    /**
55
-     * Callback to be attached to the custom swipe event of the BottomSheet.
56
-     */
57
-    onSwipe?: Function,
58
-
59
     /**
29
     /**
60
      * Function to render a bottom sheet header element, if necessary.
30
      * Function to render a bottom sheet header element, if necessary.
61
      */
31
      */
81
  * A component emulating Android's BottomSheet.
51
  * A component emulating Android's BottomSheet.
82
  */
52
  */
83
 class BottomSheet extends PureComponent<Props> {
53
 class BottomSheet extends PureComponent<Props> {
84
-    panResponder: Object;
85
-
86
     /**
54
     /**
87
      * Default values for {@code BottomSheet} component's properties.
55
      * Default values for {@code BottomSheet} component's properties.
88
      *
56
      *
93
         showSlidingView: true
61
         showSlidingView: true
94
     };
62
     };
95
 
63
 
96
-    /**
97
-     * Instantiates a new component.
98
-     *
99
-     * @inheritdoc
100
-     */
101
-    constructor(props: Props) {
102
-        super(props);
103
-
104
-        this.panResponder = PanResponder.create({
105
-            onStartShouldSetPanResponder: this._onShouldSetResponder.bind(this),
106
-            onMoveShouldSetPanResponder: this._onShouldSetResponder.bind(this),
107
-            onPanResponderRelease: this._onGestureEnd.bind(this)
108
-        });
109
-    }
110
-
111
     /**
64
     /**
112
      * Implements React's {@link Component#render()}.
65
      * Implements React's {@link Component#render()}.
113
      *
66
      *
116
      */
69
      */
117
     render() {
70
     render() {
118
         const {
71
         const {
119
-            _height,
120
-            _styles,
121
             addScrollViewPadding,
72
             addScrollViewPadding,
122
             renderHeader,
73
             renderHeader,
123
             renderFooter,
74
             renderFooter,
143
                         style = { [
94
                         style = { [
144
                             styles.sheetItemContainer,
95
                             styles.sheetItemContainer,
145
                             renderHeader
96
                             renderHeader
146
-                                ? _styles.sheetHeader
147
-                                : _styles.sheet,
148
-                            renderFooter && _styles.sheetFooter,
149
-                            style,
150
-                            {
151
-                                maxHeight: _height - 100
152
-                            }
153
-                        ] }
154
-                        { ...this.panResponder.panHandlers }>
97
+                                ? styles.sheetHeader
98
+                                : styles.sheet,
99
+                            renderFooter && styles.sheetFooter,
100
+                            style
101
+                        ] }>
155
                         <ScrollView
102
                         <ScrollView
156
                             bounces = { false }
103
                             bounces = { false }
157
                             showsVerticalScrollIndicator = { false }
104
                             showsVerticalScrollIndicator = { false }
158
                             style = { [
105
                             style = { [
159
-                                renderFooter && _styles.sheet,
106
+                                renderFooter && styles.sheet,
160
                                 addScrollViewPadding && styles.scrollView
107
                                 addScrollViewPadding && styles.scrollView
161
                             ] } >
108
                             ] } >
162
                             { this.props.children }
109
                             { this.props.children }
167
             </SlidingView>
114
             </SlidingView>
168
         );
115
         );
169
     }
116
     }
170
-
171
-    /**
172
-     * Callback to handle a gesture end event.
173
-     *
174
-     * @param {Object} evt - The native gesture event.
175
-     * @param {Object} gestureState - The gesture state.
176
-     * @returns {void}
177
-     */
178
-    _onGestureEnd(evt, gestureState) {
179
-        const verticalSwipe = Math.abs(gestureState.vy) > Math.abs(gestureState.vx)
180
-            && Math.abs(gestureState.vy) > GESTURE_SPEED_THRESHOLD;
181
-
182
-        if (verticalSwipe) {
183
-            const direction = gestureState.vy > 0 ? 'down' : 'up';
184
-            const { onCancel, onSwipe } = this.props;
185
-            let isSwipeHandled = false;
186
-
187
-            if (onSwipe) {
188
-                isSwipeHandled = onSwipe(direction);
189
-            }
190
-
191
-            if (direction === 'down' && !isSwipeHandled) {
192
-                // Swipe down is a special gesture that can be used to close the
193
-                // BottomSheet, so if the swipe is not handled by the parent
194
-                // component, we consider it as a request to close.
195
-                onCancel && onCancel();
196
-            }
197
-        }
198
-    }
199
-
200
-    /**
201
-     * Returns true if the pan responder should activate, false otherwise.
202
-     *
203
-     * @param {Object} evt - The native gesture event.
204
-     * @param {Object} gestureState - The gesture state.
205
-     * @returns {boolean}
206
-     */
207
-    _onShouldSetResponder({ nativeEvent }, gestureState) {
208
-        return nativeEvent.touches.length === 1
209
-            && Math.abs(gestureState.dx) > GESTURE_DISTANCE_THRESHOLD
210
-            && Math.abs(gestureState.dy) > GESTURE_DISTANCE_THRESHOLD;
211
-    }
212
-}
213
-
214
-/**
215
- * Maps part of the Redux state to the props of this component.
216
- *
217
- * @param {Object} state - The Redux state.
218
- * @returns {{
219
- *     _styles: StyleType
220
- * }}
221
- */
222
-function _mapStateToProps(state) {
223
-    return {
224
-        _styles: ColorSchemeRegistry.get(state, 'BottomSheet'),
225
-        _height: state['features/base/responsive-ui'].clientHeight
226
-    };
227
 }
117
 }
228
 
118
 
229
-export default connect(_mapStateToProps)(BottomSheet);
119
+export default BottomSheet;

+ 79
- 84
react/features/base/dialog/components/native/styles.js 查看文件

20
 export const MD_ITEM_HEIGHT = 48;
20
 export const MD_ITEM_HEIGHT = 48;
21
 export const MD_ITEM_MARGIN_PADDING = 16;
21
 export const MD_ITEM_MARGIN_PADDING = 16;
22
 
22
 
23
-/**
24
- * The React {@code Component} styles of {@code BottomSheet}. These have
25
- * been implemented as per the Material Design guidelines:
26
- * {@link https://material.io/guidelines/components/bottom-sheets.html}.
27
- */
28
-export const bottomSheetStyles = {
29
-    sheetAreaCover: {
30
-        backgroundColor: ColorPalette.transparent,
31
-        flex: 1
32
-    },
33
-
34
-    scrollView: {
35
-        paddingHorizontal: 0
36
-    },
37
-
38
-    /**
39
-     * Style for the container of the sheet.
40
-     */
41
-    sheetContainer: {
42
-        alignItems: 'stretch',
43
-        flex: 1,
44
-        flexDirection: 'column',
45
-        justifyContent: 'flex-end',
46
-        maxWidth: 500,
47
-        marginLeft: 'auto',
48
-        marginRight: 'auto',
49
-        width: '100%'
50
-    },
51
-
52
-    sheetItemContainer: {
53
-        flex: -1
54
-    }
55
-};
56
-
57
-export default {
58
-    dialogButton: {
59
-        ...BaseTheme.typography.labelButton
60
-    },
61
-
62
-    destructiveDialogButton: {
63
-        ...BaseTheme.typography.labelButton,
64
-        color: BaseTheme.palette.actionDanger
65
-    }
66
-};
67
-
68
-export const brandedDialog = {
69
-
70
-    /**
71
-     * The style of bold {@code Text} rendered by the {@code Dialog}s of the
72
-     * feature authentication.
73
-     */
74
-    boldDialogText: {
75
-        fontWeight: 'bold'
76
-    },
77
-
78
-    buttonFarRight: {
79
-        borderBottomRightRadius: BORDER_RADIUS
80
-    },
81
-
82
-    buttonWrapper: {
83
-        alignItems: 'stretch',
84
-        borderRadius: BORDER_RADIUS,
85
-        flexDirection: 'row'
86
-    },
87
-
88
-    mainWrapper: {
89
-        alignSelf: 'stretch',
90
-        padding: BoxModel.padding * 2,
91
-
92
-        // The added bottom padding is to compensate the empty space around the
93
-        // close icon.
94
-        paddingBottom: BoxModel.padding * 3
95
-    },
96
-
97
-    overlayTouchable: {
98
-        ...StyleSheet.absoluteFillObject
99
-    }
100
-};
101
-
102
 /**
23
 /**
103
  * Reusable (colored) style for text in any branded dialogs.
24
  * Reusable (colored) style for text in any branded dialogs.
104
  */
25
  */
136
 };
57
 };
137
 
58
 
138
 /**
59
 /**
139
- * Default styles for the items of a {@code BottomSheet}-based menu.
140
- *
141
- * These have been implemented as per the Material Design guidelines:
60
+ * The React {@code Component} styles of {@code BottomSheet}. These have
61
+ * been implemented as per the Material Design guidelines:
142
  * {@link https://material.io/guidelines/components/bottom-sheets.html}.
62
  * {@link https://material.io/guidelines/components/bottom-sheets.html}.
143
  */
63
  */
144
-ColorSchemeRegistry.register('BottomSheet', {
64
+export const bottomSheetStyles = {
65
+    sheetAreaCover: {
66
+        backgroundColor: ColorPalette.transparent,
67
+        flex: 1
68
+    },
69
+
70
+    scrollView: {
71
+        paddingHorizontal: 0
72
+    },
73
+
74
+    /**
75
+     * Style for the container of the sheet.
76
+     */
77
+    sheetContainer: {
78
+        borderColor: 'red',
79
+        alignItems: 'stretch',
80
+        flex: 1,
81
+        flexDirection: 'column',
82
+        justifyContent: 'flex-end',
83
+        maxWidth: 500,
84
+        marginLeft: 'auto',
85
+        marginRight: 'auto',
86
+        width: '100%'
87
+    },
88
+
89
+    sheetItemContainer: {
90
+        flex: -1,
91
+        maxHeight: '75%'
92
+    },
93
+
145
     buttons: {
94
     buttons: {
146
         /**
95
         /**
147
          * Style for the {@code Icon} element in a generic item of the menu.
96
          * Style for the {@code Icon} element in a generic item of the menu.
194
     sheetFooter: {
143
     sheetFooter: {
195
         backgroundColor: BaseTheme.palette.bottomSheet
144
         backgroundColor: BaseTheme.palette.bottomSheet
196
     }
145
     }
197
-});
146
+};
147
+
148
+export default {
149
+    dialogButton: {
150
+        ...BaseTheme.typography.labelButton
151
+    },
152
+
153
+    destructiveDialogButton: {
154
+        ...BaseTheme.typography.labelButton,
155
+        color: BaseTheme.palette.actionDanger
156
+    }
157
+};
158
+
159
+export const brandedDialog = {
160
+
161
+    /**
162
+     * The style of bold {@code Text} rendered by the {@code Dialog}s of the
163
+     * feature authentication.
164
+     */
165
+    boldDialogText: {
166
+        fontWeight: 'bold'
167
+    },
168
+
169
+    buttonFarRight: {
170
+        borderBottomRightRadius: BORDER_RADIUS
171
+    },
172
+
173
+    buttonWrapper: {
174
+        alignItems: 'stretch',
175
+        borderRadius: BORDER_RADIUS,
176
+        flexDirection: 'row'
177
+    },
178
+
179
+    mainWrapper: {
180
+        alignSelf: 'stretch',
181
+        padding: BoxModel.padding * 2,
182
+
183
+        // The added bottom padding is to compensate the empty space around the
184
+        // close icon.
185
+        paddingBottom: BoxModel.padding * 3
186
+    },
187
+
188
+    overlayTouchable: {
189
+        ...StyleSheet.absoluteFillObject
190
+    }
191
+};
192
+
198
 
193
 
199
 /**
194
 /**
200
  * Color schemed styles for all the component based on the abstract dialog.
195
  * Color schemed styles for all the component based on the abstract dialog.

+ 4
- 12
react/features/toolbox/components/native/OverflowMenu.js 查看文件

3
 import React, { PureComponent } from 'react';
3
 import React, { PureComponent } from 'react';
4
 import { Divider } from 'react-native-paper';
4
 import { Divider } from 'react-native-paper';
5
 
5
 
6
-import { ColorSchemeRegistry } from '../../../base/color-scheme';
7
 import { BottomSheet, hideDialog, isDialogOpen } from '../../../base/dialog';
6
 import { BottomSheet, hideDialog, isDialogOpen } from '../../../base/dialog';
7
+import { bottomSheetStyles } from '../../../base/dialog/components/native/styles';
8
 import { connect } from '../../../base/redux';
8
 import { connect } from '../../../base/redux';
9
-import { StyleType } from '../../../base/styles';
10
 import { SharedDocumentButton } from '../../../etherpad';
9
 import { SharedDocumentButton } from '../../../etherpad';
11
 import { ParticipantsPaneButton } from '../../../participants-pane/components/native';
10
 import { ParticipantsPaneButton } from '../../../participants-pane/components/native';
12
 import { ReactionMenu } from '../../../reactions/components';
11
 import { ReactionMenu } from '../../../reactions/components';
35
  */
34
  */
36
 type Props = {
35
 type Props = {
37
 
36
 
38
-    /**
39
-     * The color-schemed stylesheet of the dialog feature.
40
-     */
41
-    _bottomSheetStyles: StyleType,
42
-
43
     /**
37
     /**
44
      * True if the overflow menu is currently visible, false otherwise.
38
      * True if the overflow menu is currently visible, false otherwise.
45
      */
39
      */
118
      */
112
      */
119
     render() {
113
     render() {
120
         const {
114
         const {
121
-            _bottomSheetStyles,
122
             _reactionsEnabled,
115
             _reactionsEnabled,
123
             _selfViewHidden,
116
             _selfViewHidden,
124
             _width
117
             _width
128
         const buttonProps = {
121
         const buttonProps = {
129
             afterClick: this._onCancel,
122
             afterClick: this._onCancel,
130
             showLabel: true,
123
             showLabel: true,
131
-            styles: _bottomSheetStyles.buttons
124
+            styles: bottomSheetStyles.buttons
132
         };
125
         };
133
 
126
 
134
         const topButtonProps = {
127
         const topButtonProps = {
135
             afterClick: this._onCancel,
128
             afterClick: this._onCancel,
136
             showLabel: true,
129
             showLabel: true,
137
             styles: {
130
             styles: {
138
-                ..._bottomSheetStyles.buttons,
131
+                ...bottomSheetStyles.buttons,
139
                 style: {
132
                 style: {
140
-                    ..._bottomSheetStyles.buttons.style,
133
+                    ...bottomSheetStyles.buttons.style,
141
                     borderTopLeftRadius: 16,
134
                     borderTopLeftRadius: 16,
142
                     borderTopRightRadius: 16
135
                     borderTopRightRadius: 16
143
                 }
136
                 }
217
     const { disableSelfView } = state['features/base/settings'];
210
     const { disableSelfView } = state['features/base/settings'];
218
 
211
 
219
     return {
212
     return {
220
-        _bottomSheetStyles: ColorSchemeRegistry.get(state, 'BottomSheet'),
221
         _isOpen: isDialogOpen(state, OverflowMenu_),
213
         _isOpen: isDialogOpen(state, OverflowMenu_),
222
         _reactionsEnabled: isReactionsEnabled(state),
214
         _reactionsEnabled: isReactionsEnabled(state),
223
         _selfViewHidden: Boolean(disableSelfView),
215
         _selfViewHidden: Boolean(disableSelfView),

正在加载...
取消
保存