import { useEffect, useState } from "react"; export type UseLoadingOvertimeRefineContext = Omit< UseLoadingOvertimeCoreProps, "isPending" | "interval" > & Required>; export type UseLoadingOvertimeOptionsProps = { overtimeOptions?: UseLoadingOvertimeCoreOptions; }; export type UseLoadingOvertimeReturnType = { overtime: { elapsedTime?: number; }; }; type UseLoadingOvertimeCoreOptions = Omit< UseLoadingOvertimeCoreProps, "isPending" >; type UseLoadingOvertimeCoreReturnType = { elapsedTime?: number; }; export type UseLoadingOvertimeCoreProps = { /** * The pengind state. If true, the elapsed time will be calculated. */ isPending: boolean; /** * The interval in milliseconds. If the pending time exceeds this time, the `onInterval` callback will be called. * If not specified, the `interval` value from the `overtime` option of the `RefineProvider` will be used. * * @default: 1000 (1 second) */ interval?: number; /** * The callback function that will be called when the pending time exceeds the specified time. * If not specified, the `onInterval` value from the `overtime` option of the `RefineProvider` will be used. * * @param elapsedInterval The elapsed time in milliseconds. */ onInterval?: (elapsedInterval: number) => void; }; /** * if you need to do something when the loading time exceeds the specified time, refine provides the `useLoadingOvertime` hook. * It returns the elapsed time in milliseconds. * * @example * const { elapsedTime } = useLoadingOvertime({ * isLoading, * interval: 1000, * onInterval(elapsedInterval) { * console.log("loading overtime", elapsedInterval); * }, * }); */ export const useLoadingOvertime = ({ isPending, interval = 1000, onInterval, }: UseLoadingOvertimeCoreProps): UseLoadingOvertimeCoreReturnType => { const [elapsedTime, setElapsedTime] = useState(undefined); useEffect(() => { let intervalFn: ReturnType; if (isPending) { intervalFn = setInterval(() => { // increase elapsed time setElapsedTime((prevElapsedTime) => { if (prevElapsedTime === undefined) { return interval; } return prevElapsedTime + interval; }); }, interval); } return () => { clearInterval(intervalFn); // reset elapsed time setElapsedTime(undefined); }; }, [isPending, interval]); useEffect(() => { // call onInterval callback if (onInterval && elapsedTime) { onInterval(elapsedTime); } }, [elapsedTime]); return { elapsedTime, }; };