import { RefObject, useCallback, useMemo, useRef } from 'react' // According to https://reactnative.dev/docs/touchablewithoutfeedback#onlongpress const ReactNativeLongpressDelay = 370 export const useLongPressEvent = ( elementRef: RefObject, listener: (x: number, y: number) => void, delay = ReactNativeLongpressDelay, ) => { const longPressTimeout = useRef() const clearLongPressTimeout = useCallback(() => { if (longPressTimeout.current) { clearTimeout(longPressTimeout.current) } }, []) const createLongPressTimeout = useCallback( (event: PointerEvent) => { clearLongPressTimeout() longPressTimeout.current = window.setTimeout(() => { const x = event.clientX const y = event.clientY listener(x, y) }, delay) }, [clearLongPressTimeout, delay, listener], ) const attachEvents = useCallback(() => { if (!elementRef.current) { return } elementRef.current.addEventListener('pointerdown', createLongPressTimeout) elementRef.current.addEventListener('pointermove', clearLongPressTimeout) elementRef.current.addEventListener('pointercancel', clearLongPressTimeout) elementRef.current.addEventListener('pointerup', clearLongPressTimeout) }, [clearLongPressTimeout, createLongPressTimeout, elementRef]) const cleanupEvents = useCallback(() => { if (!elementRef.current) { return } elementRef.current.removeEventListener('pointerdown', createLongPressTimeout) elementRef.current.removeEventListener('pointermove', clearLongPressTimeout) elementRef.current.removeEventListener('pointercancel', clearLongPressTimeout) elementRef.current.removeEventListener('pointerup', clearLongPressTimeout) }, [clearLongPressTimeout, createLongPressTimeout, elementRef]) const memoizedReturn = useMemo( () => ({ attachEvents, cleanupEvents, }), [attachEvents, cleanupEvents], ) return memoizedReturn }