All files / src/components/downloads DownloadProgressBar.tsx

100% Statements 4/4
100% Branches 14/14
100% Functions 1/1
100% Lines 4/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                        7x 8x 8x 8x                                        
// SPDX-License-Identifier: GPL-3.0-only
// Copyright (C) 2026 Max Boksem. See NOTICE for additional terms under GPLv3 section 7.
 
import { downloadPercent } from "@/lib/download-progress";
import type { DownloadRecord } from "@/lib/types";
import { cn } from "@/lib/utils";
 
/**
 * A thin bar for a download that is queued or running. A running download
 * whose size the server didn't give, such as an HLS stream, has nothing to
 * measure against, so the whole bar pulses instead.
 */
export const DownloadProgressBar = ({ download }: { download: DownloadRecord }) => {
	const percent = downloadPercent(download);
	const sizeUnknown = percent === null && download.status === "downloading";
	return (
		<div
			role="progressbar"
			aria-label={`Downloading ${download.title}`}
			aria-valuemin={0}
			aria-valuemax={100}
			aria-valuenow={sizeUnknown ? undefined : (percent ?? 0)}
			aria-valuetext={download.status === "queued" ? "Queued" : undefined}
			className="h-1 rounded-full bg-white/20 overflow-hidden"
		>
			<div
				className={cn(
					"h-full bg-blue-400",
					sizeUnknown && "opacity-60 animate-pulse motion-reduce:animate-none"
				)}
				style={{ width: `${sizeUnknown ? 100 : (percent ?? 0)}%` }}
			/>
		</div>
	);
};