Skip to content

Commit 6f45a33

Browse files
committed
worklets fix
1 parent a3256d4 commit 6f45a33

File tree

5 files changed

+89
-84
lines changed

5 files changed

+89
-84
lines changed

packages/react-native-gesture-handler/src/utils.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,68 @@ export function deepEqual(obj1: any, obj2: any) {
105105
return true;
106106
}
107107

108+
export function invokeNullableMethod(
109+
method:
110+
| ((event: any) => void)
111+
| { __getHandler: () => (event: any) => void }
112+
| { __nodeConfig: { argMapping: unknown[] } }
113+
| { workletEventHandler: { worklet: (event: any) => void } }
114+
| null
115+
| undefined,
116+
event: any
117+
): void {
118+
if (!method) {
119+
return;
120+
}
121+
122+
if (typeof method === 'function') {
123+
method(event);
124+
return;
125+
}
126+
127+
if ('__getHandler' in method && typeof method.__getHandler === 'function') {
128+
const handler = method.__getHandler();
129+
invokeNullableMethod(handler, event);
130+
return;
131+
}
132+
133+
if ('workletEventHandler' in method) {
134+
const we = method.workletEventHandler;
135+
if ('worklet' in we) {
136+
invokeNullableMethod(we.worklet, event);
137+
}
138+
return;
139+
}
140+
141+
if (!('__nodeConfig' in method)) {
142+
return;
143+
}
144+
145+
const { argMapping }: { argMapping: unknown } = method.__nodeConfig;
146+
if (!Array.isArray(argMapping)) {
147+
return;
148+
}
149+
150+
for (const [index, [key, value]] of argMapping.entries()) {
151+
if (!(key in event.nativeEvent)) {
152+
continue;
153+
}
154+
155+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
156+
const nativeValue = event.nativeEvent[key];
157+
158+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
159+
if (value?.setValue) {
160+
// Reanimated API
161+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
162+
value.setValue(nativeValue);
163+
} else {
164+
// RN Animated API
165+
method.__nodeConfig.argMapping[index] = [key, nativeValue];
166+
}
167+
}
168+
169+
return;
170+
}
171+
108172
export const INT32_MAX = 2 ** 31 - 1;

packages/react-native-gesture-handler/src/v3/LogicDetector.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ export const LogicDetector = (props: NativeDetectorProps) => {
1616
const logicMethods = {
1717
onGestureHandlerStateChange:
1818
props.gesture.gestureEvents.onGestureHandlerStateChange,
19-
onGestureHandlerEvent: props.gesture.gestureEvents.onGestureHandlerEvent!,
20-
onGestureHandlerAnimatedEvent:
21-
props.gesture.gestureEvents.onGestureHandlerAnimatedEvent,
19+
onGestureHandlerEvent: props.gesture.gestureEvents.onGestureHandlerEvent,
2220
onGestureHandlerTouchEvent:
2321
props.gesture.gestureEvents.onGestureHandlerTouchEvent,
2422
};

packages/react-native-gesture-handler/src/v3/LogicDetector.web.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { RefObject, useEffect, useRef, useState } from 'react';
22
import { NativeDetectorProps, useDetectorContext } from './NativeDetector';
3-
import { Wrap } from '../handlers/gestures/GestureDetector/Wrap';
43

4+
import { Wrap } from '../handlers/gestures/GestureDetector/Wrap';
55
export interface LogicDetectorProps {
66
viewTag: number;
77
viewRef: RefObject<Element | null>;
@@ -16,9 +16,7 @@ export const LogicDetector = (props: NativeDetectorProps) => {
1616
const logicMethods = {
1717
onGestureHandlerStateChange:
1818
props.gesture.gestureEvents.onGestureHandlerStateChange,
19-
onGestureHandlerEvent: props.gesture.gestureEvents.onGestureHandlerEvent!,
20-
onGestureHandlerAnimatedEvent:
21-
props.gesture.gestureEvents.onGestureHandlerAnimatedEvent,
19+
onGestureHandlerEvent: props.gesture.gestureEvents.onGestureHandlerEvent,
2220
onGestureHandlerTouchEvent:
2321
props.gesture.gestureEvents.onGestureHandlerTouchEvent,
2422
};
@@ -42,5 +40,6 @@ export const LogicDetector = (props: NativeDetectorProps) => {
4240
};
4341
}, [viewTag, props.gesture.tag, register, unregister]);
4442

43+
// fallback: still wrap if it's not a valid element
4544
return <Wrap ref={viewRef}>{props.children}</Wrap>;
4645
};

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

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@ import { Reanimated } from '../handlers/gestures/reanimatedWrapper';
1111

1212
import { Animated, StyleSheet } from 'react-native';
1313
import HostGestureDetector from './HostGestureDetector';
14-
import { tagMessage } from '../utils';
14+
import { invokeNullableMethod, tagMessage } from '../utils';
1515
import { LogicDetectorProps } from './LogicDetector';
16-
import { runOnJS } from 'react-native-reanimated';
1716

1817
export interface NativeDetectorProps {
1918
children?: React.ReactNode;
2019
gesture: NativeGesture;
2120
}
2221

2322
interface LogicMethods {
24-
onGestureHandlerEvent: (e: unknown) => void;
25-
onGestureHandlerStateChange: (e: unknown) => void;
26-
onGestureHandlerTouchEvent?: (e: unknown) => void;
23+
onGestureHandlerEvent?: (e: any) => void;
24+
onGestureHandlerStateChange?: (e: any) => void;
25+
onGestureHandlerTouchEvent?: (e: any) => void;
2726
}
2827
const AnimatedNativeDetector =
2928
Animated.createAnimatedComponent(HostGestureDetector);
@@ -81,6 +80,7 @@ export function NativeDetector({ gesture, children }: NativeDetectorProps) {
8180
)
8281
);
8382
}
83+
8484
return (
8585
<DetectorContext.Provider value={{ register, unregister }}>
8686
<NativeDetectorComponent
@@ -95,28 +95,25 @@ export function NativeDetector({ gesture, children }: NativeDetectorProps) {
9595
gesture.gestureEvents.onGestureHandlerTouchEvent
9696
}
9797
onGestureHandlerLogicEvent={(e) => {
98-
const logicMethod = logicMethods.current.get(
99-
e.nativeEvent.childTag
100-
)?.onGestureHandlerEvent;
101-
if (logicMethod) {
102-
runOnJS(logicMethod);
103-
}
98+
invokeNullableMethod(
99+
logicMethods.current.get(e.nativeEvent.childTag)
100+
?.onGestureHandlerEvent,
101+
e
102+
);
104103
}}
105104
onGestureHandlerLogicStateChange={(e) => {
106-
const logicMethod = logicMethods.current.get(
107-
e.nativeEvent.childTag
108-
)?.onGestureHandlerStateChange;
109-
if (logicMethod) {
110-
runOnJS(logicMethod);
111-
}
105+
invokeNullableMethod(
106+
logicMethods.current.get(e.nativeEvent.childTag)
107+
?.onGestureHandlerStateChange,
108+
e
109+
);
112110
}}
113111
onGestureHandlerLogicTouchEvent={(e) => {
114-
const logicMethod = logicMethods.current.get(
115-
e.nativeEvent.childTag
116-
)?.onGestureHandlerTouchEvent;
117-
if (logicMethod) {
118-
runOnJS(logicMethod);
119-
}
112+
invokeNullableMethod(
113+
logicMethods.current.get(e.nativeEvent.childTag)
114+
?.onGestureHandlerTouchEvent,
115+
e
116+
);
120117
}}
121118
moduleId={globalThis._RNGH_MODULE_ID}
122119
handlerTags={[gesture.tag]}

packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
import { PointerType } from '../../PointerType';
2626
import { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
2727
import { ActionType } from '../../ActionType';
28-
import { tagMessage } from '../../utils';
28+
import { invokeNullableMethod, tagMessage } from '../../utils';
2929
import {
3030
GestureStateChangeEventWithData,
3131
GestureUpdateEventWithData,
@@ -1042,56 +1042,3 @@ export default abstract class GestureHandler implements IGestureHandler {
10421042
);
10431043
}
10441044
}
1045-
1046-
function invokeNullableMethod(
1047-
method:
1048-
| ((event: ResultEvent) => void)
1049-
| { __getHandler: () => (event: ResultEvent) => void }
1050-
| { __nodeConfig: { argMapping: unknown[] } },
1051-
event: ResultEvent
1052-
): void {
1053-
if (!method) {
1054-
return;
1055-
}
1056-
1057-
if (typeof method === 'function') {
1058-
method(event);
1059-
return;
1060-
}
1061-
1062-
if ('__getHandler' in method && typeof method.__getHandler === 'function') {
1063-
const handler = method.__getHandler();
1064-
invokeNullableMethod(handler, event);
1065-
return;
1066-
}
1067-
1068-
if (!('__nodeConfig' in method)) {
1069-
return;
1070-
}
1071-
1072-
const { argMapping }: { argMapping: unknown } = method.__nodeConfig;
1073-
if (!Array.isArray(argMapping)) {
1074-
return;
1075-
}
1076-
1077-
for (const [index, [key, value]] of argMapping.entries()) {
1078-
if (!(key in event.nativeEvent)) {
1079-
continue;
1080-
}
1081-
1082-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1083-
const nativeValue = (event.nativeEvent as any)[key];
1084-
1085-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1086-
if (value?.setValue) {
1087-
// Reanimated API
1088-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
1089-
value.setValue(nativeValue);
1090-
} else {
1091-
// RN Animated API
1092-
method.__nodeConfig.argMapping[index] = [key, nativeValue];
1093-
}
1094-
}
1095-
1096-
return;
1097-
}

0 commit comments

Comments
 (0)