import { MutableRefObject } from 'react'; import { WorkletFunction } from '../commonTypes'; import { isWeb } from '../PlatformChecker'; import WorkletEventHandler from '../WorkletEventHandler'; import { Context, DependencyList } from './commonTypes'; import { useEvent, useHandler } from './Hooks'; interface Handler extends WorkletFunction { (event: T, context: TContext, isCanceledOrFailed?: boolean): void; } export interface GestureHandlers { [key: string]: Handler | undefined; onStart?: Handler; onActive?: Handler; onEnd?: Handler; onFail?: Handler; onCancel?: Handler; onFinish?: Handler; } export enum EventType { UNDETERMINED = 0, FAILED, BEGAN, CANCELLED, ACTIVE, END, } export interface GestureHandlerStateChangeNativeEvent { handlerTag: number; numberOfPointers: number; state: EventType; oldState: EventType; } export interface GestureHandlerEvent extends GestureHandlerStateChangeNativeEvent { nativeEvent: T; } export function useAnimatedGestureHandler< T extends GestureHandlerEvent, TContext extends Context >( handlers: GestureHandlers, dependencies?: DependencyList ): MutableRefObject | null> | ((e: T) => void) { const { context, doDependenciesDiffer, useWeb } = useHandler( handlers, dependencies ); const handler = (e: T) => { 'worklet'; const event = useWeb ? e.nativeEvent : e; if (event.state === EventType.BEGAN && handlers.onStart) { handlers.onStart(event, context); } if (event.state === EventType.ACTIVE && handlers.onActive) { handlers.onActive(event, context); } if ( event.oldState === EventType.ACTIVE && event.state === EventType.END && handlers.onEnd ) { handlers.onEnd(event, context); } if ( event.oldState === EventType.BEGAN && event.state === EventType.FAILED && handlers.onFail ) { handlers.onFail(event, context); } if ( event.oldState === EventType.ACTIVE && event.state === EventType.CANCELLED && handlers.onCancel ) { handlers.onCancel(event, context); } if ( (event.oldState === EventType.BEGAN || event.oldState === EventType.ACTIVE) && event.state !== EventType.BEGAN && event.state !== EventType.ACTIVE && handlers.onFinish ) { handlers.onFinish( event, context, event.state === EventType.CANCELLED || event.state === EventType.FAILED ); } }; if (isWeb()) { return handler; } return useEvent( handler, ['onGestureHandlerStateChange', 'onGestureHandlerEvent'], doDependenciesDiffer ); }