Skip to content

Commit ae22a1c

Browse files
authored
chore: Migrate RoomItem's Touchable component to RNGH GestureDetector (#6583)
1 parent 28c6fc9 commit ae22a1c

File tree

2 files changed

+23006
-23689
lines changed

2 files changed

+23006
-23689
lines changed

app/containers/RoomItem/Touchable.tsx

Lines changed: 61 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
import React from 'react';
2-
import Animated, {
3-
useAnimatedGestureHandler,
4-
useSharedValue,
5-
useAnimatedStyle,
6-
withSpring,
7-
runOnJS
8-
} from 'react-native-reanimated';
9-
import {
10-
LongPressGestureHandler,
11-
PanGestureHandler,
12-
State,
13-
HandlerStateChangeEventPayload,
14-
PanGestureHandlerEventPayload
15-
} from 'react-native-gesture-handler';
1+
import React, { useRef, memo } from 'react';
2+
import Animated, { useSharedValue, useAnimatedStyle, withSpring, runOnJS } from 'react-native-reanimated';
3+
import { Gesture, GestureDetector, GestureUpdateEvent, PanGestureHandlerEventPayload } from 'react-native-gesture-handler';
164

175
import Touch from '../Touch';
186
import { ACTION_WIDTH, LONG_SWIPE, SMALL_SWIPE } from './styles';
@@ -44,12 +32,13 @@ const Touchable = ({
4432
const rowOffSet = useSharedValue(0);
4533
const transX = useSharedValue(0);
4634
const rowState = useSharedValue(0); // 0: closed, 1: right opened, -1: left opened
47-
let _value = 0;
35+
const valueRef = useRef(0);
4836

4937
const close = () => {
5038
rowState.value = 0;
5139
transX.value = withSpring(0, { overshootClamping: true });
5240
rowOffSet.value = 0;
41+
valueRef.current = 0;
5342
};
5443

5544
const handleToggleFav = () => {
@@ -96,15 +85,9 @@ const Touchable = ({
9685
}
9786
};
9887

99-
const onLongPressHandlerStateChange = ({ nativeEvent }: { nativeEvent: HandlerStateChangeEventPayload }) => {
100-
if (nativeEvent.state === State.ACTIVE) {
101-
handleLongPress();
102-
}
103-
};
104-
105-
const handleRelease = (event: PanGestureHandlerEventPayload) => {
88+
const handleRelease = (event: GestureUpdateEvent<PanGestureHandlerEventPayload>) => {
10689
const { translationX } = event;
107-
_value += translationX;
90+
valueRef.current += translationX;
10891
let toValue = 0;
10992
if (rowState.value === 0) {
11093
// if no option is opened
@@ -143,10 +126,10 @@ const Touchable = ({
143126
}
144127
} else if (rowState.value === -1) {
145128
// if left option is opened
146-
if (_value < SMALL_SWIPE) {
129+
if (valueRef.current < SMALL_SWIPE) {
147130
toValue = 0;
148131
rowState.value = 0;
149-
} else if (_value > LONG_SWIPE) {
132+
} else if (valueRef.current > LONG_SWIPE) {
150133
toValue = 0;
151134
rowState.value = 0;
152135
if (I18n.isRTL) {
@@ -161,10 +144,10 @@ const Touchable = ({
161144
}
162145
} else if (rowState.value === 1) {
163146
// if right option is opened
164-
if (_value > -2 * SMALL_SWIPE) {
147+
if (valueRef.current > -2 * SMALL_SWIPE) {
165148
toValue = 0;
166149
rowState.value = 0;
167-
} else if (_value < -LONG_SWIPE) {
150+
} else if (valueRef.current < -LONG_SWIPE) {
168151
if (I18n.isRTL) {
169152
handleToggleRead();
170153
} else {
@@ -178,56 +161,66 @@ const Touchable = ({
178161
}
179162
transX.value = withSpring(toValue, { overshootClamping: true });
180163
rowOffSet.value = toValue;
181-
_value = toValue;
164+
valueRef.current = toValue;
182165
};
183166

184-
const onGestureEvent = useAnimatedGestureHandler({
185-
onActive: event => {
167+
const longPressGesture = Gesture.LongPress()
168+
.minDuration(500)
169+
.onStart(() => {
170+
runOnJS(handleLongPress)();
171+
});
172+
173+
const panGesture = Gesture.Pan()
174+
.activeOffsetX([-10, 10]) // More sensitive horizontal detection
175+
.failOffsetY([-20, 20]) // Fail on vertical movement to distinguish scrolling
176+
.enabled(swipeEnabled)
177+
.onUpdate(event => {
186178
transX.value = event.translationX + rowOffSet.value;
187179
if (transX.value > 2 * width) transX.value = 2 * width;
188-
},
189-
onEnd: event => {
180+
})
181+
.onEnd(event => {
190182
runOnJS(handleRelease)(event);
191-
}
192-
});
183+
});
184+
185+
// Use Race instead of Simultaneous to prevent conflicts
186+
// Pan gesture will take priority over long press for horizontal swipes
187+
const composedGesture = Gesture.Race(panGesture, longPressGesture);
193188

194-
const animatedStyles = useAnimatedStyle(() => ({ transform: [{ translateX: transX.value }] }));
189+
const animatedStyles = useAnimatedStyle(() => ({
190+
transform: [{ translateX: transX.value }]
191+
}));
195192

196193
return (
197-
<LongPressGestureHandler onHandlerStateChange={onLongPressHandlerStateChange}>
194+
<GestureDetector gesture={composedGesture}>
198195
<Animated.View>
199-
<PanGestureHandler activeOffsetX={[-20, 20]} onGestureEvent={onGestureEvent} enabled={swipeEnabled}>
200-
<Animated.View>
201-
<LeftActions
202-
transX={transX}
203-
isRead={isRead}
204-
width={width}
205-
onToggleReadPress={onToggleReadPress}
206-
displayMode={displayMode}
207-
/>
208-
<RightActions
209-
transX={transX}
210-
favorite={favorite}
211-
width={width}
212-
toggleFav={handleToggleFav}
213-
onHidePress={onHidePress}
214-
displayMode={displayMode}
215-
/>
216-
<Animated.View style={animatedStyles}>
217-
<Touch
218-
onPress={handlePress}
219-
testID={testID}
220-
style={{
221-
backgroundColor: isFocused ? colors.surfaceTint : colors.surfaceRoom
222-
}}>
223-
{children}
224-
</Touch>
225-
</Animated.View>
226-
</Animated.View>
227-
</PanGestureHandler>
196+
<LeftActions
197+
transX={transX}
198+
isRead={isRead}
199+
width={width}
200+
onToggleReadPress={onToggleReadPress}
201+
displayMode={displayMode}
202+
/>
203+
<RightActions
204+
transX={transX}
205+
favorite={favorite}
206+
width={width}
207+
toggleFav={handleToggleFav}
208+
onHidePress={onHidePress}
209+
displayMode={displayMode}
210+
/>
211+
<Animated.View style={animatedStyles}>
212+
<Touch
213+
onPress={handlePress}
214+
testID={testID}
215+
style={{
216+
backgroundColor: isFocused ? colors.surfaceTint : colors.surfaceRoom
217+
}}>
218+
{children}
219+
</Touch>
220+
</Animated.View>
228221
</Animated.View>
229-
</LongPressGestureHandler>
222+
</GestureDetector>
230223
);
231224
};
232225

233-
export default Touchable;
226+
export default memo(Touchable);

0 commit comments

Comments
 (0)