import "./DownloadButton.css"; import type { Directory, MediaFile } from "music-server-shared/types"; import { type Accessor, createMemo, type ResourceActions } from "solid-js"; import type { FlatFileListing } from "../App"; import { deleteFile, download, getDownloadStatus } from "../offline"; import type { AppOptions } from "../types"; import { formatBytes } from "../utils"; import { LoadingSpinner } from "./LoadingScreen"; import { DeleteSVG, RefreshSVG, SyncSVG } from "./SVG"; interface DownloadButtonProps { fullPath: string; item: MediaFile | Directory; fetchFiles: ResourceActions; isOffline: Accessor; currentDir: Accessor; options: AppOptions; } export function DownloadButton(props: DownloadButtonProps) { return (
{ event.stopPropagation(); //ignore clicks while this item is already downloading or a directory walk is still running: //the button shows a byte counter/spinner then, and a second click would start a duplicate download const progress = getDownloadStatus(props.fullPath); if (typeof progress === "object" && ("amount" in progress || typeof progress.status === "number")) return; if (!props.isOffline()) download(props.fullPath, props.item, props.options, props.fetchFiles, "metadata" in props.item); else deleteFile(props.fullPath, props.item, props.fetchFiles); }} > {(() => { //memo needed so progress amount doesn't cause rerenders type ButtonType = "Spinner" | "Delete" | "Sync" | "Refresh" | { status: number }; const progressMemo = createMemo(() => { const progress = getDownloadStatus(props.fullPath); if (typeof progress === "object" && "amount" in progress) return "Spinner"; if (props.isOffline()) return "Delete"; if (progress === "Synced") return "Refresh"; if (progress === undefined || ("status" in progress && typeof progress.status !== "number")) return "Sync"; if (typeof progress.status === "number") return { status: progress.status }; throw new Error(`Unexpected: ${progress}`); }); const progress = progressMemo(); if (progress === "Spinner") return ; if (progress === "Delete") { return ( ); } if (progress === "Sync") { return ( ); } if (progress === "Refresh") { return ( ); } if ("status" in progress) return {formatBytes(progress.status)}; console.error("Unexpected", progress); })()}
); }