File size: 1,964 Bytes
246d201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
59
60
61
62
63
64
65
66
67
68
import React from "react";

interface UseRateProps {
  threshold: number;
}

const DEFAULT_CONFIG: UseRateProps = { threshold: 1000 };

export const useRate = (config = DEFAULT_CONFIG) => {
  const [items, setItems] = React.useState<number[]>([]);
  const [rate, setRate] = React.useState<number | null>(null);
  const [lastUpdated, setLastUpdated] = React.useState<number | null>(null);
  const [isUnderThreshold, setIsUnderThreshold] = React.useState(true);

  /**

   * Record an entry in order to calculate the rate

   * @param entry Entry to record

   *

   * @example

   * record(new Date().getTime());

   */
  const record = (entry: number) => {
    setItems((prev) => [...prev, entry]);
    setLastUpdated(new Date().getTime());
  };

  /**

   * Update the rate based on the last two entries (if available)

   */
  const updateRate = () => {
    if (items.length > 1) {
      const newRate = items[items.length - 1] - items[items.length - 2];
      setRate(newRate);

      if (newRate <= config.threshold) setIsUnderThreshold(true);
      else setIsUnderThreshold(false);
    }
  };

  React.useEffect(() => {
    updateRate();
  }, [items]);

  React.useEffect(() => {
    // Set up an interval to check if the time since the last update exceeds the threshold
    // If it does, set isUnderThreshold to false, otherwise set it to true
    // This ensures that the component can react to periods of inactivity
    const intervalId = setInterval(() => {
      if (lastUpdated !== null) {
        const timeSinceLastUpdate = new Date().getTime() - lastUpdated;
        setIsUnderThreshold(timeSinceLastUpdate <= config.threshold);
      } else {
        setIsUnderThreshold(false);
      }
    }, config.threshold);

    return () => clearInterval(intervalId);
  }, [lastUpdated, config.threshold]);

  return {
    items,
    rate,
    lastUpdated,
    isUnderThreshold,
    record,
  };
};