diff options
Diffstat (limited to 'src/components/dms/ActionsWrapper.tsx')
-rw-r--r-- | src/components/dms/ActionsWrapper.tsx | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/src/components/dms/ActionsWrapper.tsx b/src/components/dms/ActionsWrapper.tsx index 3b9a56bdc..a349c3cfa 100644 --- a/src/components/dms/ActionsWrapper.tsx +++ b/src/components/dms/ActionsWrapper.tsx @@ -1,5 +1,6 @@ import React from 'react' -import {Keyboard, Pressable, View} from 'react-native' +import {Keyboard} from 'react-native' +import {Gesture, GestureDetector} from 'react-native-gesture-handler' import Animated, { cancelAnimation, runOnJS, @@ -15,8 +16,6 @@ import {atoms as a} from '#/alf' import {MessageMenu} from '#/components/dms/MessageMenu' import {useMenuControl} from '#/components/Menu' -const AnimatedPressable = Animated.createAnimatedComponent(Pressable) - export function ActionsWrapper({ message, isFromSelf, @@ -30,56 +29,59 @@ export function ActionsWrapper({ const menuControl = useMenuControl() const scale = useSharedValue(1) - const animationDidComplete = useSharedValue(false) const animatedStyle = useAnimatedStyle(() => ({ transform: [{scale: scale.value}], })) - // Reanimated's `runOnJS` doesn't like refs, so we can't use `runOnJS(menuControl.open)()`. Instead, we'll use this - // function const open = React.useCallback(() => { + playHaptic() Keyboard.dismiss() menuControl.open() - }, [menuControl]) + }, [menuControl, playHaptic]) const shrink = React.useCallback(() => { 'worklet' cancelAnimation(scale) - scale.value = withTiming(1, {duration: 200}, () => { - animationDidComplete.value = false - }) - }, [animationDidComplete, scale]) + scale.value = withTiming(1, {duration: 200}) + }, [scale]) - const grow = React.useCallback(() => { - 'worklet' - scale.value = withTiming(1.05, {duration: 450}, finished => { - if (!finished) return - animationDidComplete.value = true - runOnJS(playHaptic)() - runOnJS(open)() + const doubleTapGesture = Gesture.Tap() + .numberOfTaps(2) + .hitSlop(HITSLOP_10) + .onEnd(open) - shrink() + const pressAndHoldGesture = Gesture.LongPress() + .onStart(() => { + scale.value = withTiming(1.05, {duration: 200}, finished => { + if (!finished) return + runOnJS(open)() + shrink() + }) }) - }, [scale, animationDidComplete, playHaptic, shrink, open]) + .onTouchesUp(shrink) + .onTouchesMove(shrink) + .cancelsTouchesInView(false) + .runOnJS(true) + + const composedGestures = Gesture.Exclusive( + doubleTapGesture, + pressAndHoldGesture, + ) return ( - <View - style={[ - { - maxWidth: '80%', - }, - isFromSelf ? a.self_end : a.self_start, - ]}> - <AnimatedPressable - style={animatedStyle} - unstable_pressDelay={200} - onPressIn={grow} - onTouchEnd={shrink} - hitSlop={HITSLOP_10}> + <GestureDetector gesture={composedGestures}> + <Animated.View + style={[ + { + maxWidth: '80%', + }, + isFromSelf ? a.self_end : a.self_start, + animatedStyle, + ]}> {children} - </AnimatedPressable> - <MessageMenu message={message} control={menuControl} /> - </View> + <MessageMenu message={message} control={menuControl} /> + </Animated.View> + </GestureDetector> ) } |