- Spotify playlist, library, album and artist browsing with in-app playback - Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks - Electron desktop app (castLabs Widevine) with a permanent sidebar layout - Linux and Windows packaging scripts
39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import { Download, Loader2 } from "lucide-react";
|
|
import { Button } from "./Button";
|
|
import type { InputType as DownloadRequest } from "../endpoints/spotify-download_POST.schema";
|
|
import type { useSpotifyDownload } from "../helpers/useSpotifyDownload";
|
|
import styles from "./DownloadButton.module.css";
|
|
|
|
type Props = {
|
|
downloads: ReturnType<typeof useSpotifyDownload>;
|
|
busyKey: string;
|
|
label: string;
|
|
request: DownloadRequest;
|
|
text?: string;
|
|
size?: "sm" | "icon-sm";
|
|
variant?: "primary" | "outline" | "ghost";
|
|
};
|
|
|
|
export function DownloadButton({ downloads, busyKey, label, request, text, size = "icon-sm", variant = "ghost" }: Props) {
|
|
if (!downloads.canDownload) return null;
|
|
const busy = downloads.busyKeys.has(busyKey);
|
|
const Icon = busy ? Loader2 : Download;
|
|
return (
|
|
<Button
|
|
variant={variant}
|
|
size={size}
|
|
disabled={busy}
|
|
aria-label={text ? undefined : `Download ${label}`}
|
|
title={text ? undefined : "Download"}
|
|
onClick={(event) => {
|
|
event.stopPropagation();
|
|
downloads.startDownload(busyKey, label, request);
|
|
}}
|
|
onKeyDown={(event) => event.stopPropagation()}
|
|
>
|
|
<Icon size={14} className={busy ? styles.spin : undefined} />
|
|
{text}
|
|
</Button>
|
|
);
|
|
}
|