105 lines
2.7 KiB
TypeScript
105 lines
2.7 KiB
TypeScript
|
|
import { useEffect, useState } from "react";
|
||
|
|
|
||
|
|
export type UseLoadingOvertimeRefineContext = Omit<
|
||
|
|
UseLoadingOvertimeCoreProps,
|
||
|
|
"isPending" | "interval"
|
||
|
|
> &
|
||
|
|
Required<Pick<UseLoadingOvertimeCoreProps, "interval">>;
|
||
|
|
|
||
|
|
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<number | undefined>(undefined);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
let intervalFn: ReturnType<typeof setInterval>;
|
||
|
|
|
||
|
|
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,
|
||
|
|
};
|
||
|
|
};
|