File size: 1,582 Bytes
1f122c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client"

import { useEffect, useRef, useState } from "react"

export function useCountdown({
  isActive,
  timerId,
  durationInSec,
  onEnd = () => {},
}: {
  isActive: boolean
  timerId: string | number
  durationInSec: number
  onEnd: () => void
}) {
  const intervalRef = useRef<NodeJS.Timer>()
  const startedAt = useRef<Date>()
  const [elapsedTimeInMs, setElapsedTimeInMs] = useState<number>(0)

  const durationInMs = durationInSec * 1000

  useEffect(() => {
    clearInterval(intervalRef.current)
    setElapsedTimeInMs(0)
    startedAt.current = new Date()

    if (isActive) {
      intervalRef.current = setInterval(() => {
        const now = new Date()
        const newElapsedInMs = Math.min(durationInMs, now.getTime() - startedAt.current!.getTime())
        setElapsedTimeInMs(newElapsedInMs)
        if (elapsedTimeInMs > durationInMs) {
          // console.log("end of timer")
          clearInterval(intervalRef.current)
          onEnd()
        }
      }, 100)
    }

    return () => {
      // console.log("destruction of timer")
      clearInterval(intervalRef.current)
    }
  }, [isActive, timerId, durationInMs])

  const remainingTimeInMs = Math.max(0, durationInMs - elapsedTimeInMs)

  const progressRatio = elapsedTimeInMs / durationInMs
  const progressPercent = progressRatio * 100

  return {
    elapsedTimeInMs,
    remainingTimeInMs,
    elapsedTimeInSec: Math.round(elapsedTimeInMs / 1000),
    remainingTimeInSec: Math.round(remainingTimeInMs / 1000),
    progressRatio,
    progressPercent,
    timeIsUp: remainingTimeInMs <= 0,
  }
}