All files / src/hooks/common useCooldown.ts

58.82% Statements 10/17
50% Branches 1/2
66.66% Functions 4/6
58.82% Lines 10/17

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                              74x 1470x 1470x     1470x 320x           1470x                     1470x 320x 320x       1470x        
import { useState, useEffect, useCallback, useRef } from "react";
 
interface UseCooldownReturn {
  isInCooldown: boolean;
  startCooldown: () => void;
}
 
/**
 * Custom hook to manage a cooldown period. Ex: to be used for sidepanel headers to avoid frequent navigations between panels which can lead to rate limit error.
 *
 * @param cooldownDuration The duration of the cooldown in milliseconds. Ex: consider how many requests you make with an action, like panel header, and compare it to the allowed number of requests/minute.
 * @returns {UseCooldownReturn} An object containing:
 *  - `isInCooldown`: A boolean indicating if the cooldown is currently active.
 *  - `startCooldown`: A function to manually start or restart the cooldown.
 */
export const useCooldown = (cooldownDuration: number): UseCooldownReturn => {
  const [isInCooldown, setIsInCooldown] = useState(false);
  const cooldownTimerRef = useRef<NodeJS.Timeout | null>(null);
 
  // Function to clear the existing timer
  const clearCooldownTimer = useCallback(() => {
    Iif (cooldownTimerRef.current) {
      clearTimeout(cooldownTimerRef.current);
      cooldownTimerRef.current = null;
    }
  }, []);
 
  const startCooldown = useCallback(() => {
    clearCooldownTimer(); // Clear any existing timer before starting a new one
    setIsInCooldown(true);
 
    cooldownTimerRef.current = setTimeout(() => {
      setIsInCooldown(false);
      cooldownTimerRef.current = null; // Clear ref after timeout
    }, cooldownDuration);
  }, [cooldownDuration, clearCooldownTimer]);
 
  // Cleanup on unmount
  useEffect(() => {
    return () => {
      clearCooldownTimer();
    };
  }, [clearCooldownTimer]);
 
  return { isInCooldown, startCooldown };
};
 
export default useCooldown;