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 //show sync icon for synced directories as well, since we don't know for sure if everything is downloaded in them
46 if (progress === undefined || (progress === "SyncedFile" && !props.isOffline() && "files" in props.item)) {
47 return (
48 <button title="Sync this file/directory to your browser for offline use">
49 <SyncSVG />
50 </button>
51 );
52 }
53 if (progress === "DirectoryProgress") return <LoadingSpinner center={true} />;
54 if (progress === "SyncedFile") {
55 if (props.isOffline()) {
56 return (
57 <button title="Purge this file/these files from local sync storage">
58 <DeleteSVG />
59 </button>
60 );
61 }
62 return (
63 <button title="Re-sync this file">
64 <RefreshSVG />
65 </button>
66 );
67 }
68
69 if ("bytes" in progress) return <span>{formatProgress(progress.bytes)}</span>;
70 console.error("Unexpected", progress);
71 })()}
72 </div>
73 );
74}
75