56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import React from "react";
|
|
import Button from "../buttons/Button.tsx";
|
|
import { kickerClass } from "../../utils/styles.ts";
|
|
|
|
type props = {
|
|
dataSend: React.MouseEventHandler<HTMLButtonElement>;
|
|
handleDownload: React.MouseEventHandler<HTMLButtonElement>;
|
|
downloadable: boolean;
|
|
progress: number;
|
|
uploading: boolean;
|
|
}
|
|
|
|
// queued → reading source → encoding → writing file → complete
|
|
const stageOf = (progress: number, uploading: boolean, downloadable: boolean): string => {
|
|
if (downloadable) return "complete";
|
|
if (!uploading) return "waiting";
|
|
if (progress < 0.05) return "reading source";
|
|
if (progress < 0.95) return "encoding";
|
|
return "writing file";
|
|
};
|
|
|
|
const ExportWidget = ({ dataSend, handleDownload, downloadable, progress, uploading }: props) => {
|
|
const pct = downloadable ? 100 : Math.round(Math.min(1, Math.max(0, progress)) * 100);
|
|
|
|
return (
|
|
<div className="flex flex-col gap-4">
|
|
<p className={kickerClass}>Export</p>
|
|
|
|
<Button onClick={dataSend} disabled={uploading} className="w-full py-3">
|
|
{uploading ? "Compressing…" : "Compress and save"}
|
|
</Button>
|
|
|
|
<div className="flex flex-col gap-1.5">
|
|
<div className="h-[3px] w-full rounded-full bg-chip overflow-hidden">
|
|
<div
|
|
className={`h-full rounded-full transition-[width] duration-500 ease-out ${downloadable ? "bg-olive-light" : "bg-accent-light"}`}
|
|
style={{ width: `${pct}%` }}
|
|
/>
|
|
</div>
|
|
<div className="flex items-baseline justify-between gap-3">
|
|
<p className="font-data text-[11px] text-muted">{stageOf(progress, uploading, downloadable)}</p>
|
|
<p className="font-data text-[11px] text-faint-mono">{downloadable ? "done" : `${pct}%`}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{downloadable && (
|
|
<Button variant="olive" className="w-full py-3" onClick={handleDownload}>
|
|
Download the file
|
|
</Button>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default ExportWidget;
|