import type { GestureTouchEvent } from '../../../handlers/gestureHandlerCommon'; import { tagMessage } from '../../../utils'; import type { AnimatedEvent, BaseGestureConfig, ChangeCalculatorType, DiffCalculatorType, GestureEvent, GestureHandlerEventWithHandlerData, GestureStateChangeEventWithHandlerData, GestureUpdateEventWithHandlerData, NativeEventWrapper, } from '../../types'; function isNativeEvent( event: GestureHandlerEventWithHandlerData ): event is | NativeEventWrapper> | NativeEventWrapper> | NativeEventWrapper { 'worklet'; return 'nativeEvent' in event; } export function maybeExtractNativeEvent< THandlerData, TExtendedHandlerData extends THandlerData, >( event: GestureHandlerEventWithHandlerData ): | GestureTouchEvent | GestureUpdateEventWithHandlerData | GestureStateChangeEventWithHandlerData { 'worklet'; return isNativeEvent(event) ? event.nativeEvent : event; } export function flattenAndFilterEvent( event: | GestureUpdateEventWithHandlerData | GestureStateChangeEventWithHandlerData ): GestureEvent { 'worklet'; return { handlerTag: event.handlerTag, ...event.handlerData }; } export function isEventForHandlerWithTag< THandlerData, TExtendedHandlerData extends THandlerData, >( handlerTag: number, event: | GestureStateChangeEventWithHandlerData | GestureUpdateEventWithHandlerData | GestureTouchEvent ) { 'worklet'; return event.handlerTag === handlerTag; } export function isNativeAnimatedEvent( callback: | ((event: GestureEvent) => void) | AnimatedEvent | undefined ): callback is AnimatedEvent { 'worklet'; return !!callback && '_argMapping' in callback; } export function checkMappingForChangeProperties(animatedEvent: AnimatedEvent) { for (const mapping of animatedEvent._argMapping) { if ( !mapping || !('nativeEvent' in mapping && 'handlerData' in mapping.nativeEvent) ) { continue; } for (const key in mapping.nativeEvent.handlerData) { if (key.startsWith('change')) { throw new Error( tagMessage(`${key} is not available when using Animated.Event.`) ); } } } } export function shouldHandleTouchEvents< TConfig, THandlerData, TExtendedHandlerData extends THandlerData, >(config: BaseGestureConfig) { return ( !!config.onTouchesDown || !!config.onTouchesMove || !!config.onTouchesUp || !!config.onTouchesCancel ); } export function getChangeEventCalculator( diffCalculator: DiffCalculatorType ): ChangeCalculatorType { 'worklet'; return ( current: GestureUpdateEventWithHandlerData, previous?: GestureUpdateEventWithHandlerData ) => { 'worklet'; const currentEventData = current.handlerData; // Guard against malformed events if (currentEventData === undefined) { return current; } const previousEventData = previous ? previous.handlerData : null; const changePayload = diffCalculator(currentEventData, previousEventData); current.handlerData = { ...currentEventData, ...changePayload }; return current; }; } export function isTouchEvent< THandlerData, TExtendedHandlerData extends THandlerData, >( event: | GestureStateChangeEventWithHandlerData | GestureUpdateEventWithHandlerData | GestureTouchEvent ): event is GestureTouchEvent { 'worklet'; return 'allTouches' in event; } export function isStateChangeEvent< THandlerData, TExtendedHandlerData extends THandlerData, >( event: | GestureStateChangeEventWithHandlerData | GestureUpdateEventWithHandlerData | GestureTouchEvent ): event is GestureStateChangeEventWithHandlerData { 'worklet'; return 'oldState' in event && event.oldState !== undefined; }