33 triggerClickHaptic ,
44 triggerSlowRiseHaptic ,
55} from '@/modules/native-crypto/src/ReactNativeHapticsModule' ;
6- import { ReactNode , useEffect , useState } from 'react' ;
7- import { ViewProps } from 'react-native' ;
6+ import { ReactNode } from 'react' ;
7+ import { Gesture , GestureDetector } from 'react-native-gesture-handler ' ;
88import Animated , {
99 useAnimatedStyle ,
1010 useSharedValue ,
@@ -22,51 +22,36 @@ export default function Holdable({
2222 duration = 500 ,
2323} : HoldableProps ) {
2424 const holdingScale = useSharedValue ( 1 ) ;
25- const [ isHolding , setIsHolding ] = useState ( false ) ;
26- const [ holdTimeout , setHoldTimeout ] = useState < number > ( ) ;
2725
2826 const handleLongPress = ( ) => {
29- triggerClickHaptic ( ) ;
3027 onLongPress ( ) ;
31- setIsHolding ( false ) ;
28+ triggerClickHaptic ( ) ;
3229 } ;
3330 const enterHold = ( ) => {
34- setIsHolding ( true ) ;
35-
31+ holdingScale . value = withTiming ( 1.1 , {
32+ duration,
33+ } ) ;
3634 triggerSlowRiseHaptic ( ) ;
37- clearTimeout ( holdTimeout ) ;
38- setHoldTimeout (
39- setTimeout ( ( ) => {
40- handleLongPress ( ) ;
41- } , duration ) ,
42- ) ;
4335 } ;
44- const exitHold = ( ) => {
45- clearTimeout ( holdTimeout ) ;
46- setIsHolding ( false ) ;
47- cancelHaptic ( ) ;
48- } ;
49- const callbacks : Partial < ViewProps > = {
50- onTouchStart : enterHold ,
51- onPointerDown : enterHold ,
52- onPointerUp : exitHold ,
53- onPointerLeave : exitHold ,
54- onTouchEnd : exitHold ,
55- onTouchMove : exitHold ,
56- onPointerMove : exitHold ,
57- } ;
58-
59- useEffect ( ( ) => {
60- holdingScale . value = withTiming ( isHolding ? 1.1 : 1 , {
36+ const exitHold = ( triggered : boolean ) => {
37+ holdingScale . value = withTiming ( 1 , {
6138 duration,
6239 } ) ;
63- } , [ holdingScale , isHolding , duration ] ) ;
40+ if ( ! triggered ) cancelHaptic ( ) ;
41+ } ;
42+ const gesture = Gesture . LongPress ( )
43+ . minDuration ( duration )
44+ . runOnJS ( true )
45+ . onBegin ( enterHold )
46+ . onFinalize ( ( _ , triggered ) => exitHold ( triggered ) )
47+ . onStart ( handleLongPress ) ;
48+
6449 const scaleStyle = useAnimatedStyle ( ( ) => ( {
6550 transform : [ { scale : holdingScale . value } ] ,
6651 } ) ) ;
6752 return (
68- < Animated . View style = { [ scaleStyle ] } { ... callbacks } >
69- { children }
70- </ Animated . View >
53+ < GestureDetector gesture = { gesture } >
54+ < Animated . View style = { [ scaleStyle ] } > { children } </ Animated . View >
55+ </ GestureDetector >
7156 ) ;
7257}
0 commit comments