Spaces:
Running
Running
File size: 1,577 Bytes
450060f |
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>
)
} |