DownloadButton.tsx
⎇
Raw
1import "./DownloadButton.css";
2import type { MediaFile, Directory, FileListing } from "music-server-shared/types";
3import { deleteFile, download, downloadStatusMap } from "../offline";
4import type { Accessor, ResourceActions } from "solid-js";
5import type { AppOptions } from "../types";
6import { joinPath } from "../utils";
7import { DeleteSVG, RefreshSVG, SyncSVG } from "./SVG";
8import { LoadingSpinner } from "./LoadingScreen";
9
10interface DownloadButtonProps {
11 fileName: string;
12 item: MediaFile | Directory;
13 fetchFiles: ResourceActions<FileListing>;
14 isOffline: Accessor<boolean>;
15 currentDir: Accessor<string>;
16 options: AppOptions;
17}
18
19function formatProgress(bytes: number): string {
20 if (bytes === 0) return "Queued...";
21
22 const k = 1024;
23 const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
24 const i = Math.floor(Math.log(bytes) / Math.log(k));
25 const value = bytes / k ** i;
26
27 return `${value.toFixed(2)} ${sizes[i]}`;
28}
29
30export function DownloadButton(props: DownloadButtonProps) {
31 const fullPath = joinPath(props.currentDir(), props.fileName);
32
33 return (
34 <div
35 class="download-item"
36 onClick={(event) => {
37 event.stopPropagation();
38 if (!props.isOffline())
39 download(props.fileName, props.item, props.currentDir(), props.currentDir, props.options, props.fetchFiles);
40 else deleteFile(props.fileName, props.item, props.currentDir(), props.fetchFiles);
41 }}
42 >
43 {(() => {
44 const progress = downloadStatusMap[fullPath];
45 if (props.isOffline()) {
46 return (
47 <button title="Purge this file/these files from local sync storage">
48 <DeleteSVG />
49 </button>
50 );
51 }
52 if (progress === undefined) {
53 return (
54 <button title="Sync this file/directory to your browser for offline use">
55 <SyncSVG />
56 </button>
57 );
58 }
59 if (progress === "DirectoryProgress") return <LoadingSpinner center={true} />;
60 if (progress === "Synced") {
61 return (
62 <button title="Re-sync this file">
63 <RefreshSVG />
64 </button>
65 );
66 }
67
68 if ("bytes" in progress) return <span>{formatProgress(progress.bytes)}</span>;
69 console.error("Unexpected", progress);
70 })()}
71 </div>
72 );
73}
74