// Usage:
// const Button = () => {
// const { completion, ...bind } = useTimedEvent(() => { fire(); }, { duration: 1000 });
// return ;
// };
import { useEffect, useRef, useState } from "react";
const useTimedEvent = (
callback: (() => void) | (() => Promise),
options?: { refreshRate?: number; duration?: number }
) => {
const timerId = useRef(null);
const [progress, setProgress] = useState(0);
const refreshRate = options?.refreshRate ?? 10;
const triggerAt = (options?.duration ?? 1000) / refreshRate;
const completion = (progress / triggerAt) * 100;
useEffect(() => () => clearInterval(timerId.current), []);
useEffect(() => {
if (progress === triggerAt) {
endProgress();
callback();
}
}, [progress, triggerAt, callback]);
const startProgress = () => {
timerId.current = setInterval(
() => setProgress((val) => val + 1),
refreshRate
);
};
const endProgress = () => {
setProgress(0);
clearInterval(timerId.current);
};
const onMouseDown = () => {
startProgress();
};
const onTouchStart = () => {
startProgress();
};
const onMouseUp = () => {
endProgress();
};
const onMouseOut = () => {
endProgress();
};
const onTouchEnd = () => {
endProgress();
};
return {
completion,
onMouseDown,
onTouchStart,
onMouseUp,
onMouseOut,
onTouchEnd,
};
};
export default useTimedEvent;