import { batch, createEffect, createMemo, createSignal, For, Show, type Accessor, type Setter } from "solid-js"; import "./DownloadManager.css"; import "./Dialog.css"; import "toastify-js/src/toastify.css"; import { formatBytes } from "../utils"; import { ClearSVG, RefreshSVG, StopSVG } from "./SVG"; import { type DownloadStatus, downloadStatusMap, setDownloadStatusMap, type Progress } from "../offline"; interface DownloadManagerProps { showDownloadManager: Accessor; setShowDownloadManager: Setter; } export default function DownloadManager(props: DownloadManagerProps) { let dialogElement!: HTMLDialogElement; createEffect(() => { if (props.showDownloadManager()) { dialogElement.showModal(); } }); function handleClose() { dialogElement.close(); props.setShowDownloadManager(false); } const downloadKeys = createMemo(() => { const keys = Object.keys(downloadStatusMap); const progressKeys = keys.filter((key) => isProgress(downloadStatusMap[key])); // Sort the keys: Running first (by path), then Failed (by path), then Aborted (by path) progressKeys.sort((pathA, pathB) => { const statusA = downloadStatusMap[pathA] as Progress; const statusB = downloadStatusMap[pathB] as Progress; // 0: Running, 1: Failed, 2: Aborted const typeA = typeof statusA.status === "number" ? (statusA.status > 0 ? 0 : 3) : statusA.status === "Failed" ? 1 : 2; const typeB = typeof statusB.status === "number" ? (statusB.status > 0 ? 0 : 3) : statusB.status === "Failed" ? 1 : 2; if (typeA !== typeB) { return typeA - typeB; // Sort by type first } // If types are the same, sort by path numerically/alphabetically return pathA.localeCompare(pathB, undefined, { numeric: true }); }); return progressKeys; }); function isProgress(status: DownloadStatus | undefined): status is Progress { return status !== undefined && typeof status === "object" && "status" in status; } return ( e.target.nodeName === "DIALOG" && handleClose()} >
Download

{(path) => { const [showReason, setShowReason] = createSignal(false); const status = downloadStatusMap[path] as Progress; return (
{path}
{status && typeof status.status === "number" ? ( <> {formatBytes(status.status)} ) : ( <> {(status.status === "Failed" && ( )) || "Aborted"} )}
{"reason" in status && status.reason}
); }}
); }