File size: 1,577 Bytes
624088c
 
 
 
 
 
 
 
 
 
 
932a7fd
624088c
 
 
 
 
 
 
 
 
 
 
 
 
 
6b27fdb
624088c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
932a7fd
624088c
 
 
 
 
 
 
 
 
 
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
import { useEffect, useRef, useState } from "react"

import { ProgressBar } from "./progress-bar"
import { cn } from "@/lib/utils"

export function Progress({
  isLoading,
  resetKey = "", // when this key change, this will re-spawn the progress bar
  className = "",
}: {
  isLoading: boolean
  resetKey?: string
  className?: string
}) {
  const timeoutRef = useRef<any>()
  const [progressPercent, setProcessPercent] = useState(0)
  const progressRef = useRef(0)
  const isLoadingRef = useRef(isLoading)

  const updateProgressBar = () => {
    const duration = 1000 // 1 sec
    const frequency = 200 // 200ms
    const nbUpdatesPerSec = duration / frequency // 5x per second

    // normally it takes 45, and we will try to go below,
    // but to be safe let's set the counter a 1 min
    const nbSeconds = 80 // 1 min
    const amountInPercent =  100 / (nbUpdatesPerSec * nbSeconds) // 0.333

    progressRef.current = Math.min(100, progressRef.current + amountInPercent)
    setProcessPercent(progressRef.current)
  }

  useEffect(() => {
    clearInterval(timeoutRef.current)
    isLoadingRef.current = isLoading
    progressRef.current = 0
    setProcessPercent(0)
    if (isLoading) {
      timeoutRef.current = setInterval(updateProgressBar, 200)
    }
  }, [isLoading, resetKey])

  return (
    <div className={cn(
      `flex w-10 h-10`,
      `animation-all duration-300 text-md`,
      isLoading
        ? `scale-100 opacity-100`
        : `scale-0 opacity-0`,
      className
    )}>
      <ProgressBar progressPercentage={progressPercent} />
    </div>
  )
}