Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 19x 19x 19x 19x | import { useCancellablePromises } from "hooks";
import { wait } from "utils";
interface IRejectedPromiseInfo {
error: Error;
isCanceled: boolean;
}
export const cancellablePromise = (
promise: Promise<unknown>
): { promise: Promise<unknown>; cancel: () => boolean } => {
let isCanceled = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise.then(
(value) => (isCanceled ? reject({ isCanceled, value }) : resolve(value)),
(error) => reject({ isCanceled, error: error as Error })
);
});
return {
promise: wrappedPromise,
cancel: () => (isCanceled = true),
};
};
export const useClickPreventionOnDoubleClick = (
onClick: () => void,
onDoubleClick: () => void
): (() => void)[] => {
const api = useCancellablePromises();
const handleClick = () => {
api.clearPendingPromises();
const waitForClick = cancellablePromise(wait(300));
api.appendPendingPromise(waitForClick);
return waitForClick.promise
.then(() => {
api.removePendingPromise(waitForClick);
onClick();
})
.catch((errorInfo: IRejectedPromiseInfo) => {
api.removePendingPromise(waitForClick);
Iif (!errorInfo.isCanceled) {
throw errorInfo.error;
}
});
};
const handleDoubleClick = () => {
api.clearPendingPromises();
onDoubleClick();
};
return [handleClick, handleDoubleClick];
};
|