From 08fc77d16b09f5e039c4157800b96c672e02bf03 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Thu, 18 Dec 2025 12:01:36 +0100 Subject: [PATCH] Move end flag to event --- .../src/components/switchAndInput/index.tsx | 9 +-- .../src/v3/components/GestureButtons.tsx | 9 +-- .../src/v3/hooks/callbacks/eventHandler.ts | 24 ++++--- .../v3/hooks/callbacks/stateChangeHandler.ts | 65 ------------------- .../v3/hooks/callbacks/touchEventHandler.ts | 32 --------- .../src/v3/hooks/callbacks/updateHandler.ts | 53 --------------- .../src/v3/hooks/utils/eventHandlersUtils.ts | 14 ++-- .../src/v3/types/ConfigTypes.ts | 10 +-- .../src/v3/types/EventTypes.ts | 4 ++ .../src/v3/types/index.ts | 2 +- 10 files changed, 33 insertions(+), 189 deletions(-) delete mode 100644 packages/react-native-gesture-handler/src/v3/hooks/callbacks/stateChangeHandler.ts delete mode 100644 packages/react-native-gesture-handler/src/v3/hooks/callbacks/touchEventHandler.ts delete mode 100644 packages/react-native-gesture-handler/src/v3/hooks/callbacks/updateHandler.ts diff --git a/apps/common-app/src/components/switchAndInput/index.tsx b/apps/common-app/src/components/switchAndInput/index.tsx index e5a114f7d2..63f3129c5c 100644 --- a/apps/common-app/src/components/switchAndInput/index.tsx +++ b/apps/common-app/src/components/switchAndInput/index.tsx @@ -1,6 +1,5 @@ import React, { useState } from 'react'; import { StyleSheet, Text, View } from 'react-native'; -import type { NativeGestureEvent } from 'react-native-gesture-handler'; import { TextInput, LegacyTextInput, @@ -22,8 +21,8 @@ export default function SwitchTextInputExample() { console.log('[TextInput] onBegin')} onActivate={() => console.log('[TextInput] onActivate')} - onFinalize={(_: NativeGestureEvent, s: boolean) => - console.log('[TextInput] onFinalize', s) + onFinalize={(e) => + console.log('[TextInput] onFinalize', e.canceled) } style={styles.input} placeholder="Type here..." @@ -50,9 +49,7 @@ export default function SwitchTextInputExample() { console.log('[Switch] onBegin')} - onFinalize={(_: NativeGestureEvent, s: boolean) => - console.log('[Switch] onFinalize', s) - } + onFinalize={(e) => console.log('[Switch] onFinalize', e.canceled)} value={switchOn} onValueChange={(v: boolean) => { console.log('[Switch] onValueChange', v); diff --git a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx index 4da169ac42..894703179c 100644 --- a/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx +++ b/packages/react-native-gesture-handler/src/v3/components/GestureButtons.tsx @@ -8,10 +8,11 @@ import type { RectButtonProps, } from './GestureButtonsProps'; -import type { GestureEvent } from '../types'; +import type { GestureEndEvent, GestureEvent } from '../types'; import type { NativeViewHandlerData } from '../hooks/gestures/native/useNativeGesture'; type CallbackEventType = GestureEvent; +type EndCallbackEventType = GestureEndEvent; export const RawButton = createNativeWrapper(GestureHandlerButton, { shouldCancelWhenOutside: false, @@ -58,15 +59,15 @@ export const BaseButton = (props: BaseButtonProps) => { } }; - const onDeactivate = (e: CallbackEventType, success: boolean) => { + const onDeactivate = (e: EndCallbackEventType) => { onActiveStateChange?.(false); - if (success && !longPressDetected.current) { + if (!e.canceled && !longPressDetected.current) { onPress?.(e.pointerInside); } }; - const onFinalize = (_e: CallbackEventType) => { + const onFinalize = (_e: EndCallbackEventType) => { if (longPressTimeout.current !== undefined) { clearTimeout(longPressTimeout.current); longPressTimeout.current = undefined; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/eventHandler.ts b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/eventHandler.ts index b01b90fd84..91c911c3d6 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/eventHandler.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/eventHandler.ts @@ -10,6 +10,7 @@ import { ReanimatedContext } from '../../../handlers/gestures/reanimatedWrapper' import { ChangeCalculatorType, GestureCallbacks, + GestureEndEvent, GestureHandlerEventWithHandlerData, GestureStateChangeEventWithHandlerData, GestureUpdateEventWithHandlerData, @@ -35,23 +36,20 @@ function handleStateChangeEvent( state === State.ACTIVE ) { runCallback(CALLBACK_TYPE.START, callbacks, event); - } else if (oldState !== state && state === State.END) { - if (oldState === State.ACTIVE) { - runCallback(CALLBACK_TYPE.END, callbacks, event, true); - } - runCallback(CALLBACK_TYPE.FINALIZE, callbacks, event, true); - - if (context) { - context.lastUpdateEvent = undefined; - } } else if ( - (state === State.FAILED || state === State.CANCELLED) && - state !== oldState + oldState !== state && + (state === State.END || state === State.FAILED || state === State.CANCELLED) ) { + const canceled = state === State.FAILED || state === State.CANCELLED; + const endEvent: GestureEndEvent = { + ...event, + canceled, + }; + if (oldState === State.ACTIVE) { - runCallback(CALLBACK_TYPE.END, callbacks, event, false); + runCallback(CALLBACK_TYPE.END, callbacks, endEvent); } - runCallback(CALLBACK_TYPE.FINALIZE, callbacks, event, false); + runCallback(CALLBACK_TYPE.FINALIZE, callbacks, endEvent); if (context) { context.lastUpdateEvent = undefined; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/stateChangeHandler.ts b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/stateChangeHandler.ts deleted file mode 100644 index d5d93ed785..0000000000 --- a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/stateChangeHandler.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ReanimatedContext } from '../../../handlers/gestures/reanimatedWrapper'; -import { CALLBACK_TYPE } from '../../../handlers/gestures/gesture'; -import { State } from '../../../State'; -import { - GestureCallbacks, - GestureStateChangeEventWithHandlerData, - StateChangeEventWithHandlerData, -} from '../../types'; -import { - flattenAndFilterEvent, - isEventForHandlerWithTag, - maybeExtractNativeEvent, - runCallback, -} from '../utils'; - -export function getStateChangeHandler( - handlerTag: number, - callbacks: GestureCallbacks, - context?: ReanimatedContext -) { - return (sourceEvent: StateChangeEventWithHandlerData) => { - 'worklet'; - - const eventWithData = maybeExtractNativeEvent( - sourceEvent - ) as GestureStateChangeEventWithHandlerData; - const event = flattenAndFilterEvent(eventWithData); - - if (!isEventForHandlerWithTag(handlerTag, eventWithData)) { - return; - } - - const { state, oldState } = eventWithData; - - if (oldState === State.UNDETERMINED && state === State.BEGAN) { - runCallback(CALLBACK_TYPE.BEGAN, callbacks, event); - } else if ( - (oldState === State.BEGAN || oldState === State.UNDETERMINED) && - state === State.ACTIVE - ) { - runCallback(CALLBACK_TYPE.START, callbacks, event); - } else if (oldState !== state && state === State.END) { - if (oldState === State.ACTIVE) { - runCallback(CALLBACK_TYPE.END, callbacks, event, true); - } - runCallback(CALLBACK_TYPE.FINALIZE, callbacks, event, true); - - if (context) { - context.lastUpdateEvent = undefined; - } - } else if ( - (state === State.FAILED || state === State.CANCELLED) && - state !== oldState - ) { - if (oldState === State.ACTIVE) { - runCallback(CALLBACK_TYPE.END, callbacks, event, false); - } - runCallback(CALLBACK_TYPE.FINALIZE, callbacks, event, false); - - if (context) { - context.lastUpdateEvent = undefined; - } - } - }; -} diff --git a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/touchEventHandler.ts b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/touchEventHandler.ts deleted file mode 100644 index ef65483218..0000000000 --- a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/touchEventHandler.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { GestureCallbacks, TouchEvent } from '../../types'; -import { - isEventForHandlerWithTag, - maybeExtractNativeEvent, - runCallback, - touchEventTypeToCallbackType, -} from '../utils'; -import { TouchEventType } from '../../../TouchEventType'; -import { GestureTouchEvent } from '../../../handlers/gestureHandlerCommon'; - -export function getTouchEventHandler( - handlerTag: number, - callbacks: GestureCallbacks -) { - return (sourceEvent: TouchEvent) => { - 'worklet'; - - const event = maybeExtractNativeEvent(sourceEvent) as GestureTouchEvent; - - if (!isEventForHandlerWithTag(handlerTag, event)) { - return; - } - - if (event.eventType !== TouchEventType.UNDETERMINED) { - runCallback( - touchEventTypeToCallbackType(event.eventType), - callbacks, - event - ); - } - }; -} diff --git a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/updateHandler.ts b/packages/react-native-gesture-handler/src/v3/hooks/callbacks/updateHandler.ts deleted file mode 100644 index a59c9e3621..0000000000 --- a/packages/react-native-gesture-handler/src/v3/hooks/callbacks/updateHandler.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { CALLBACK_TYPE } from '../../../handlers/gestures/gesture'; -import { tagMessage } from '../../../utils'; -import { ReanimatedContext } from '../../../handlers/gestures/reanimatedWrapper'; -import { - ChangeCalculatorType, - GestureCallbacks, - GestureUpdateEventWithHandlerData, - UpdateEventWithHandlerData, -} from '../../types'; -import { - flattenAndFilterEvent, - isEventForHandlerWithTag, - maybeExtractNativeEvent, - runCallback, -} from '../utils'; - -export function getUpdateHandler( - handlerTag: number, - callbacks: GestureCallbacks, - context: ReanimatedContext | undefined, - changeEventCalculator?: ChangeCalculatorType -) { - return (sourceEvent: UpdateEventWithHandlerData) => { - 'worklet'; - - const eventWithData = maybeExtractNativeEvent( - sourceEvent - ) as GestureUpdateEventWithHandlerData; - - const eventWithChanges = changeEventCalculator - ? changeEventCalculator( - eventWithData, - context ? context.lastUpdateEvent : undefined - ) - : eventWithData; - - const event = flattenAndFilterEvent(eventWithChanges); - - if (!isEventForHandlerWithTag(handlerTag, eventWithData)) { - return; - } - - // This should never happen, but since we don't want to call hooks conditionally, we have to mark - // context as possibly undefined to make TypeScript happy. - if (!context) { - throw new Error(tagMessage('Event handler context is not defined')); - } - - runCallback(CALLBACK_TYPE.UPDATE, callbacks, event); - - context.lastUpdateEvent = eventWithData; - }; -} diff --git a/packages/react-native-gesture-handler/src/v3/hooks/utils/eventHandlersUtils.ts b/packages/react-native-gesture-handler/src/v3/hooks/utils/eventHandlersUtils.ts index 3c7da5c433..0d2263858e 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/utils/eventHandlersUtils.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/utils/eventHandlersUtils.ts @@ -4,10 +4,10 @@ import { CALLBACK_TYPE } from '../../../handlers/gestures/gesture'; import { GestureCallbacks, GestureEventCallback, - GestureEventCallbackWithDidSucceed, GestureTouchEventCallback, UnpackedGestureHandlerEvent, } from '../../types'; +import { GestureEndEventCallback } from '../../types/ConfigTypes'; export function useMemoizedGestureCallbacks( callbacks: GestureCallbacks @@ -51,7 +51,7 @@ function getHandler( callbacks: GestureCallbacks ): | GestureEventCallback - | GestureEventCallbackWithDidSucceed + | GestureEndEventCallback | GestureTouchEventCallback | undefined { 'worklet'; @@ -95,13 +95,11 @@ export function touchEventTypeToCallbackType( } type SingleParameterCallback = (event: T) => void; -type DoubleParameterCallback = (event: T, didSucceed: boolean) => void; export function runCallback( type: CALLBACK_TYPE, callbacks: GestureCallbacks, - event: UnpackedGestureHandlerEvent, - didSucceed?: boolean + event: UnpackedGestureHandlerEvent ) { 'worklet'; const handler = getHandler(type, callbacks); @@ -110,9 +108,5 @@ export function runCallback( return; } - if (didSucceed === undefined) { - (handler as SingleParameterCallback)(event); - } else { - (handler as DoubleParameterCallback)(event, didSucceed); - } + (handler as SingleParameterCallback)(event); } diff --git a/packages/react-native-gesture-handler/src/v3/types/ConfigTypes.ts b/packages/react-native-gesture-handler/src/v3/types/ConfigTypes.ts index fabcdb2bf3..3f6f0822d5 100644 --- a/packages/react-native-gesture-handler/src/v3/types/ConfigTypes.ts +++ b/packages/react-native-gesture-handler/src/v3/types/ConfigTypes.ts @@ -9,6 +9,7 @@ import { import { AnimatedEvent, ChangeCalculatorType, + GestureEndEvent, GestureEvent, } from './EventTypes'; import { WithSharedValue } from './ReanimatedTypes'; @@ -17,9 +18,8 @@ export type GestureEventCallback = ( event: GestureEvent ) => void; -export type GestureEventCallbackWithDidSucceed = ( - event: GestureEvent, - didSucceed: boolean +export type GestureEndEventCallback = ( + event: GestureEndEvent ) => void; export type GestureTouchEventCallback = (event: GestureTouchEvent) => void; @@ -27,8 +27,8 @@ export type GestureTouchEventCallback = (event: GestureTouchEvent) => void; export type GestureCallbacks = { onBegin?: GestureEventCallback; onActivate?: GestureEventCallback; - onDeactivate?: GestureEventCallbackWithDidSucceed; - onFinalize?: GestureEventCallbackWithDidSucceed; + onDeactivate?: GestureEndEventCallback; + onFinalize?: GestureEndEventCallback; onUpdate?: GestureEventCallback | AnimatedEvent; onTouchesDown?: GestureTouchEventCallback; onTouchesMove?: GestureTouchEventCallback; diff --git a/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts b/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts index 79d2643cd1..2ed81be3c3 100644 --- a/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts +++ b/packages/react-native-gesture-handler/src/v3/types/EventTypes.ts @@ -53,6 +53,10 @@ export type GestureEvent = { handlerTag: number; } & HandlerData; +export type GestureEndEvent = { + canceled: boolean; +} & GestureEvent; + export type UnpackedGestureHandlerEvent = | GestureEvent | GestureTouchEvent; diff --git a/packages/react-native-gesture-handler/src/v3/types/index.ts b/packages/react-native-gesture-handler/src/v3/types/index.ts index fc94570b41..7f6f9ae9c6 100644 --- a/packages/react-native-gesture-handler/src/v3/types/index.ts +++ b/packages/react-native-gesture-handler/src/v3/types/index.ts @@ -15,6 +15,7 @@ export type { StateChangeEventWithHandlerData, TouchEvent, GestureEvent, + GestureEndEvent, AnimatedEvent, ChangeCalculatorType, DiffCalculatorType, @@ -23,7 +24,6 @@ export type { export type { GestureCallbacks, GestureEventCallback, - GestureEventCallbackWithDidSucceed, GestureTouchEventCallback, GestureRelations, InternalConfigProps,