mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 12:30:12 +02:00
add long press to card controls for shuffle
This commit is contained in:
@@ -1,3 +1,104 @@
|
||||
import { useLongPress as useMantineLongPress } from '@mantine/hooks';
|
||||
import { useCallback, useRef } from 'react';
|
||||
|
||||
export const useLongPress = useMantineLongPress;
|
||||
interface UseLongPressOptions<T extends HTMLElement = HTMLElement> {
|
||||
delay?: number;
|
||||
onClick?: (event: React.MouseEvent<T> | React.TouchEvent<T>) => void;
|
||||
onLongPress?: (event: React.MouseEvent<T> | React.TouchEvent<T>) => void;
|
||||
}
|
||||
|
||||
interface UseLongPressReturn {
|
||||
onMouseDown: (event: React.MouseEvent) => void;
|
||||
onMouseLeave: (event: React.MouseEvent) => void;
|
||||
onMouseUp: (event: React.MouseEvent) => void;
|
||||
onTouchCancel: (event: React.TouchEvent) => void;
|
||||
onTouchEnd: (event: React.TouchEvent) => void;
|
||||
onTouchStart: (event: React.TouchEvent) => void;
|
||||
}
|
||||
|
||||
export const useLongPress = <T extends HTMLElement = HTMLElement>({
|
||||
delay = 500,
|
||||
onClick,
|
||||
onLongPress,
|
||||
}: UseLongPressOptions<T>): UseLongPressReturn => {
|
||||
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const targetRef = useRef<EventTarget | null>(null);
|
||||
const longPressTriggeredRef = useRef(false);
|
||||
const eventRef = useRef<null | React.MouseEvent<T> | React.TouchEvent<T>>(null);
|
||||
|
||||
const start = useCallback(
|
||||
(event: React.MouseEvent<T> | React.TouchEvent<T>) => {
|
||||
longPressTriggeredRef.current = false;
|
||||
targetRef.current = event.target;
|
||||
eventRef.current = event;
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
longPressTriggeredRef.current = true;
|
||||
if (eventRef.current) {
|
||||
onLongPress?.(eventRef.current);
|
||||
}
|
||||
}, delay);
|
||||
},
|
||||
[onLongPress, delay],
|
||||
);
|
||||
|
||||
const clear = useCallback(() => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleMouseDown = useCallback(
|
||||
(event: React.MouseEvent) => {
|
||||
event.preventDefault();
|
||||
start(event as React.MouseEvent<T>);
|
||||
},
|
||||
[start],
|
||||
);
|
||||
|
||||
const handleMouseUp = useCallback(() => {
|
||||
clear();
|
||||
if (!longPressTriggeredRef.current && onClick && eventRef.current) {
|
||||
onClick(eventRef.current);
|
||||
}
|
||||
longPressTriggeredRef.current = false;
|
||||
eventRef.current = null;
|
||||
}, [clear, onClick]);
|
||||
|
||||
const handleMouseLeave = useCallback(() => {
|
||||
clear();
|
||||
longPressTriggeredRef.current = false;
|
||||
eventRef.current = null;
|
||||
}, [clear]);
|
||||
|
||||
const handleTouchStart = useCallback(
|
||||
(event: React.TouchEvent) => {
|
||||
start(event as React.TouchEvent<T>);
|
||||
},
|
||||
[start],
|
||||
);
|
||||
|
||||
const handleTouchEnd = useCallback(() => {
|
||||
clear();
|
||||
if (!longPressTriggeredRef.current && onClick && eventRef.current) {
|
||||
onClick(eventRef.current);
|
||||
}
|
||||
longPressTriggeredRef.current = false;
|
||||
eventRef.current = null;
|
||||
}, [clear, onClick]);
|
||||
|
||||
const handleTouchCancel = useCallback(() => {
|
||||
clear();
|
||||
longPressTriggeredRef.current = false;
|
||||
eventRef.current = null;
|
||||
}, [clear]);
|
||||
|
||||
return {
|
||||
onMouseDown: handleMouseDown,
|
||||
onMouseLeave: handleMouseLeave,
|
||||
onMouseUp: handleMouseUp,
|
||||
onTouchCancel: handleTouchCancel,
|
||||
onTouchEnd: handleTouchEnd,
|
||||
onTouchStart: handleTouchStart,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user