| 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 |
| const frequency = 200 |
| const nbUpdatesPerSec = duration / frequency |
|
|
| |
| |
| const nbSeconds = 80 |
| const amountInPercent = 100 / (nbUpdatesPerSec * nbSeconds) |
|
|
| 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> |
| ) |
| } |