62
common/resources/client/utils/hooks/use-spin-delay.ts
Executable file
62
common/resources/client/utils/hooks/use-spin-delay.ts
Executable file
@@ -0,0 +1,62 @@
|
||||
import {useEffect, useRef, useState} from 'react';
|
||||
|
||||
interface SpinDelayOptions {
|
||||
delay?: number;
|
||||
minDuration?: number;
|
||||
}
|
||||
|
||||
type State = 'IDLE' | 'DELAY' | 'DISPLAY' | 'EXPIRE';
|
||||
|
||||
export const defaultOptions = {
|
||||
delay: 500,
|
||||
minDuration: 200,
|
||||
};
|
||||
|
||||
export function useSpinDelay(
|
||||
loading: boolean,
|
||||
options?: SpinDelayOptions,
|
||||
): boolean {
|
||||
options = Object.assign({}, defaultOptions, options);
|
||||
|
||||
const [state, setState] = useState<State>('IDLE');
|
||||
const timeout = useRef<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (loading && state === 'IDLE') {
|
||||
clearTimeout(timeout.current);
|
||||
|
||||
timeout.current = setTimeout(
|
||||
() => {
|
||||
if (!loading) {
|
||||
return setState('IDLE');
|
||||
}
|
||||
|
||||
timeout.current = setTimeout(
|
||||
() => {
|
||||
setState('EXPIRE');
|
||||
},
|
||||
options?.minDuration,
|
||||
);
|
||||
|
||||
setState('DISPLAY');
|
||||
},
|
||||
options?.delay,
|
||||
);
|
||||
|
||||
setState('DELAY');
|
||||
}
|
||||
|
||||
if (!loading && state !== 'DISPLAY') {
|
||||
clearTimeout(timeout.current);
|
||||
setState('IDLE');
|
||||
}
|
||||
}, [loading, state, options.delay, options.minDuration]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => clearTimeout(timeout.current);
|
||||
}, []);
|
||||
|
||||
return state === 'DISPLAY' || state === 'EXPIRE';
|
||||
}
|
||||
|
||||
export default useSpinDelay;
|
||||
Reference in New Issue
Block a user