Skip to content

Commit 29b96ce

Browse files
committed
Move the event logic to ReanimatedNativeDetector add fallback
1 parent 48cb50c commit 29b96ce

File tree

8 files changed

+127
-70
lines changed

8 files changed

+127
-70
lines changed

packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ export type ReanimatedHandler<THandlerData> = {
2929
context: ReanimatedContext<THandlerData>;
3030
};
3131

32+
export type NativeEventsManager = new (component: {
33+
props: Record<string, unknown>;
34+
_componentRef: React.Ref<unknown>;
35+
getComponentViewTag: () => number;
36+
}) => {
37+
attachEvents: () => void;
38+
detachEvents: () => void;
39+
updateEvents: (prevProps: Record<string, unknown>) => void;
40+
};
41+
3242
let Reanimated:
3343
| {
3444
default: {
@@ -38,6 +48,7 @@ let Reanimated:
3848
options?: unknown
3949
): ComponentClass<P>;
4050
};
51+
NativeEventsManager: NativeEventsManager;
4152
useHandler: <THandlerData>(
4253
handlers: GestureCallbacks<THandlerData>
4354
) => ReanimatedHandler<THandlerData>;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import RNGestureHandlerDetectorNativeComponent from '../../specs/RNGestureHandlerDetectorNativeComponent';
2+
export { NativeProps as RNGestureHandlerDetectorNativeComponentProps } from '../../specs/RNGestureHandlerDetectorNativeComponent';
23
const HostGestureDetector = RNGestureHandlerDetectorNativeComponent;
34
export default HostGestureDetector;

packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,27 @@ import {
77
NativeDetectorProps,
88
nativeDetectorStyles,
99
} from './common';
10-
import { useReanimatedEventsManager } from './useReanimatedEventsManager';
10+
import { ReanimatedNativeDetector } from './ReanimatedNativeDetector';
1111

1212
export function NativeDetector<THandlerData, TConfig>({
1313
gesture,
1414
children,
1515
}: NativeDetectorProps<THandlerData, TConfig>) {
16-
// TODO: is it possible with useReanimatedEventsManager to handle both Animated and Reanimated at the same time?
17-
1816
const NativeDetectorComponent = gesture.config.dispatchesAnimatedEvents
1917
? AnimatedNativeDetector
20-
: HostGestureDetector;
18+
: gesture.config.shouldUseReanimatedDetector
19+
? ReanimatedNativeDetector
20+
: HostGestureDetector;
2121

2222
ensureNativeDetectorComponent(NativeDetectorComponent);
2323
configureRelations(gesture);
2424

25-
// TODO: call useReanimatedEventsManager only when using Reanimated
26-
const viewRef = useReanimatedEventsManager(gesture);
2725
const handlerTags = useMemo(() => {
2826
return isComposedGesture(gesture) ? gesture.tags : [gesture.tag];
2927
}, [gesture]);
3028

3129
return (
3230
<NativeDetectorComponent
33-
ref={viewRef}
3431
pointerEvents={'box-none'}
3532
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
3633
onGestureHandlerStateChange={
@@ -43,6 +40,18 @@ export function NativeDetector<THandlerData, TConfig>({
4340
gesture.detectorCallbacks.onGestureHandlerTouchEvent
4441
}
4542
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
43+
onGestureHandlerReanimatedStateChange={
44+
gesture.detectorCallbacks.onReanimatedStateChange
45+
}
46+
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
47+
onGestureHandlerReanimatedEvent={
48+
gesture.detectorCallbacks.onReanimatedUpdateEvent
49+
}
50+
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
51+
onGestureHandlerReanimatedTouchEvent={
52+
gesture.detectorCallbacks.onReanimatedTouchEvent
53+
}
54+
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
4655
onGestureHandlerAnimatedEvent={
4756
gesture.detectorCallbacks.onGestureHandlerAnimatedEvent
4857
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { useEffect, useMemo, useRef } from 'react';
2+
import {
3+
NativeEventsManager,
4+
Reanimated,
5+
} from '../../handlers/gestures/reanimatedWrapper';
6+
import HostGestureDetector, {
7+
type RNGestureHandlerDetectorNativeComponentProps,
8+
} from './HostGestureDetector';
9+
import { findNodeHandle } from 'react-native';
10+
11+
let NativeEventsManagerImpl = Reanimated?.NativeEventsManager;
12+
13+
if (!NativeEventsManagerImpl) {
14+
// Fallback to empty object when Reanimated or NativeEventsManager is not available
15+
try {
16+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
17+
NativeEventsManagerImpl =
18+
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
19+
require('react-native-reanimated/src/createAnimatedComponent/NativeEventsManager').NativeEventsManager;
20+
} catch {
21+
// fail silently
22+
}
23+
}
24+
25+
type WorkletProps = Pick<
26+
RNGestureHandlerDetectorNativeComponentProps,
27+
| 'onGestureHandlerReanimatedStateChange'
28+
| 'onGestureHandlerReanimatedEvent'
29+
| 'onGestureHandlerReanimatedTouchEvent'
30+
>;
31+
32+
function LeanReanimatedNativeDetector(
33+
props: RNGestureHandlerDetectorNativeComponentProps
34+
) {
35+
const prevProps = useRef<WorkletProps>(null);
36+
const eventManager = useRef<InstanceType<NativeEventsManager> | null>(null);
37+
const viewRef = useRef<any>(null);
38+
39+
const {
40+
onGestureHandlerReanimatedStateChange,
41+
onGestureHandlerReanimatedEvent,
42+
onGestureHandlerReanimatedTouchEvent,
43+
...restProps
44+
} = props;
45+
46+
const reaProps: WorkletProps = useMemo(
47+
() => ({
48+
onGestureHandlerReanimatedStateChange,
49+
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
50+
onGestureHandlerReanimatedEvent,
51+
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
52+
onGestureHandlerReanimatedTouchEvent,
53+
}),
54+
[
55+
onGestureHandlerReanimatedEvent,
56+
onGestureHandlerReanimatedStateChange,
57+
onGestureHandlerReanimatedTouchEvent,
58+
]
59+
);
60+
61+
useEffect(() => {
62+
const nativeTag = findNodeHandle(viewRef.current) ?? -1;
63+
// @ts-expect-error Reanimated expects __nativeTag to be present on the ref
64+
viewRef.__nativeTag = nativeTag;
65+
// @ts-expect-error NativeEventsManager should be defined here, if it isn't, we should
66+
// go the fallback way and use Reanimated's createAnimatedComponent
67+
eventManager.current = new NativeEventsManagerImpl({
68+
props: reaProps,
69+
_componentRef: viewRef,
70+
getComponentViewTag: () => {
71+
return nativeTag;
72+
},
73+
});
74+
eventManager.current.attachEvents();
75+
76+
return () => {
77+
eventManager.current?.detachEvents();
78+
};
79+
}, []);
80+
81+
useEffect(() => {
82+
if (prevProps.current) {
83+
eventManager.current?.updateEvents(prevProps.current);
84+
}
85+
prevProps.current = reaProps;
86+
}, [reaProps]);
87+
88+
return <HostGestureDetector ref={viewRef} {...restProps} />;
89+
}
90+
91+
export const ReanimatedNativeDetector = NativeEventsManagerImpl
92+
? LeanReanimatedNativeDetector
93+
: Reanimated?.default.createAnimatedComponent(HostGestureDetector);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Reanimated } from '../../handlers/gestures/reanimatedWrapper';
2+
import HostGestureDetector from './HostGestureDetector';
3+
4+
export const ReanimatedNativeDetector =
5+
Reanimated?.default.createAnimatedComponent(HostGestureDetector);

packages/react-native-gesture-handler/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ import {
1717
AnimatedNativeDetector,
1818
InterceptingGestureDetectorProps,
1919
nativeDetectorStyles,
20-
ReanimatedNativeDetector,
2120
} from '../common';
2221
import { tagMessage } from '../../../utils';
2322
import { useEnsureGestureHandlerRootView } from '../useEnsureGestureHandlerRootView';
23+
import { ReanimatedNativeDetector } from '../ReanimatedNativeDetector';
2424

2525
interface VirtualChildrenForNative {
2626
viewTag: number;

packages/react-native-gesture-handler/src/v3/detectors/common.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react';
22
import { Gesture } from '../types';
3-
import { Reanimated } from '../../handlers/gestures/reanimatedWrapper';
43
import { Animated, StyleSheet } from 'react-native';
54
import HostGestureDetector from './HostGestureDetector';
65
import { GestureDetectorProps as LegacyDetectorProps } from '../../handlers/gestures/GestureDetector';
@@ -23,9 +22,6 @@ export type GestureDetectorProps<THandlerData, TConfig> =
2322
export const AnimatedNativeDetector =
2423
Animated.createAnimatedComponent(HostGestureDetector);
2524

26-
export const ReanimatedNativeDetector =
27-
Reanimated?.default.createAnimatedComponent(HostGestureDetector);
28-
2925
export const nativeDetectorStyles = StyleSheet.create({
3026
detector: {
3127
display: 'contents',

packages/react-native-gesture-handler/src/v3/detectors/useReanimatedEventsManager.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)