Spaces:
Sleeping
Sleeping
File size: 2,052 Bytes
95a2dcc 14c6f28 95a2dcc 14c6f28 95a2dcc 14c6f28 95a2dcc 14c6f28 95a2dcc | 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 | import { useProgress } from "@/lib/progress";
function fmt(s: number): string {
const m = Math.floor(s / 60);
const sec = Math.floor(s % 60);
return `${m}:${sec.toString().padStart(2, "0")}`;
}
export default function ProgressBar() {
const state = useProgress();
if (state.phase === "idle") return null;
if (state.phase === "error") {
return (
<div className="sticky top-0 z-40 border-b border-red-900/40 bg-red-950/80 backdrop-blur-md px-4 sm:px-8 py-2.5">
<span className="label-mono text-red-400">progress error</span>
<span className="ml-3 text-sm text-red-300/90 break-words">{state.message}</span>
</div>
);
}
const isRunning = state.phase === "running";
const isDialog = isRunning && state.kind === "dialog";
const fill =
state.phase === "done"
? 1
: isDialog && state.total > 0
? state.turn / state.total
: null;
const elapsedS = state.phase === "running" ? state.elapsedS : state.phase === "done" ? state.elapsedS : 0;
const label =
state.phase === "done"
? `done 路 ${fmt(elapsedS)}`
: isDialog
? `Turn ${state.turn} of ${state.total} 路 ${fmt(elapsedS)}`
: `Generating 路 ${fmt(elapsedS)}`;
return (
<div className="sticky top-0 z-40 border-b border-[hsl(var(--ember))]/30 bg-[hsl(var(--ember))]/15 backdrop-blur-md px-4 sm:px-8 py-2">
<div className="flex items-center gap-3 sm:gap-4">
<span className="label-mono text-[hsl(var(--ember))] whitespace-nowrap text-[10px] sm:text-[10.5px]">
{label}
</span>
<div className="flex-1 min-w-0 h-1 bg-[hsl(var(--ember))]/20 rounded-sm overflow-hidden">
{fill === null ? (
<div className="h-full w-1/3 bg-[hsl(var(--ember))] animate-progress-stripe" />
) : (
<div
className="h-full bg-[hsl(var(--ember))] transition-[width] duration-200 ease-linear"
style={{ width: `${fill * 100}%` }}
/>
)}
</div>
</div>
</div>
);
}
|