Files
streamrip-ui/frontend/app/DownloadDialog.tsx
T

91 lines
3.0 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
export type SearchItem = {
id: string;
media_type: string;
title: string;
artist: string;
cover?: string | null;
preview_url?: string | null;
desc?: string;
};
export default function DownloadDialog({ item, onClose }: { item: SearchItem; onClose: () => void }) {
const [quality, setQuality] = useState(2);
const [codec, setCodec] = useState("");
const [sending, setSending] = useState(false);
const [msg, setMsg] = useState("");
useEffect(() => {
fetch("/api/config/ui")
.then((r) => r.json())
.then((b) => {
if (typeof b?.deezer?.quality === "number") setQuality(b.deezer.quality);
if (b?.conversion?.enabled && typeof b.conversion.codec === "string") setCodec(b.conversion.codec);
})
.catch(() => {});
}, []);
async function start() {
setSending(true);
setMsg("");
try {
const r = await fetch("/api/downloads", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
source: "deezer",
media_type: item.media_type,
id: item.id,
quality,
codec,
}),
});
if (!r.ok) throw new Error(`Start fehlgeschlagen (${r.status}).`);
const body = await r.json();
setMsg(`Angelegt: ${body.job_id} — siehe Queue.`);
} catch (e: unknown) {
setMsg(e instanceof Error ? e.message : "Fehler.");
} finally {
setSending(false);
}
}
return (
<div
style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,.65)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 100 }}
onClick={onClose}
>
<div
className="card"
style={{ minWidth: 320, maxWidth: 420, width: "90%", padding: 20, background: "var(--surface-2)" }}
onClick={(e) => e.stopPropagation()}
>
<h3 style={{ marginTop: 0 }}>{item.title}</h3>
<p className="muted" style={{ marginTop: 0 }}>{item.artist}</p>
<label>
Qualität (0=MP3 128, 1=MP3 320, 2=FLAC)
<select value={quality} onChange={(e) => setQuality(Number(e.target.value))} className="select" style={{ margin: "6px 0 12px" }}>
<option value={0}>0 — MP3 128</option>
<option value={1}>1 — MP3 320</option>
<option value={2}>2 — FLAC</option>
</select>
</label>
<label>
Codec (optional, z. B. MP3/FLAC/OGG)
<input value={codec} onChange={(e) => setCodec(e.target.value)} placeholder="Leer = kein Convert" className="input" style={{ margin: "6px 0 12px" }} />
</label>
<div style={{ display: "flex", gap: 8 }}>
<button onClick={start} disabled={sending} className="btn btn-primary" style={{ flex: 1 }}>
{sending ? "…" : "Download starten"}
</button>
<button onClick={onClose} className="btn">Schließen</button>
</div>
{msg && <p>{msg}</p>}
</div>
</div>
);
}