feat(discovery): Discovery settings section (enable + tuning knobs)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan
2026-07-12 00:47:18 +02:00
parent 3de7461245
commit b9ebd18c2c
+55
View File
@@ -24,6 +24,8 @@ export function SettingsForm() {
const [saved, setSaved] = useState(false); const [saved, setSaved] = useState(false);
const [scanResult, setScanResult] = useState<string | null>(null); const [scanResult, setScanResult] = useState<string | null>(null);
const [scanRequested, setScanRequested] = useState(false); const [scanRequested, setScanRequested] = useState(false);
const [discoverCfg, setDiscoverCfg] = useState<Record<string, string>>({});
const [discoverSaved, setDiscoverSaved] = useState(false);
useEffect(() => { useEffect(() => {
fetch("/api/scan") fetch("/api/scan")
@@ -62,6 +64,12 @@ export function SettingsForm() {
}); });
}, []); }, []);
useEffect(() => {
fetch("/api/discover/config")
.then((r) => r.json())
.then((c: Record<string, string>) => setDiscoverCfg(c));
}, []);
async function submit(e: React.FormEvent) { async function submit(e: React.FormEvent) {
e.preventDefault(); e.preventDefault();
await fetch("/api/config", { await fetch("/api/config", {
@@ -78,6 +86,21 @@ export function SettingsForm() {
setKeySet(keySet || slskdApiKey !== ""); setKeySet(keySet || slskdApiKey !== "");
} }
function setCfg(key: string, value: string) {
setDiscoverCfg((c) => ({ ...c, [key]: value }));
}
async function saveDiscovery(e: React.FormEvent) {
e.preventDefault();
await fetch("/api/discover/config", {
method: "PATCH",
headers: { "content-type": "application/json" },
body: JSON.stringify(discoverCfg),
});
setDiscoverSaved(true);
setTimeout(() => setDiscoverSaved(false), 1500);
}
return ( return (
<> <>
<form onSubmit={submit}> <form onSubmit={submit}>
@@ -107,6 +130,38 @@ export function SettingsForm() {
</button> </button>
{scanResult ? <p aria-label="scan result">Last scan: {scanResult}</p> : null} {scanResult ? <p aria-label="scan result">Last scan: {scanResult}</p> : null}
</section> </section>
<form onSubmit={saveDiscovery}>
<h2>Discovery</h2>
<label>
<input
type="checkbox"
checked={discoverCfg["discover.enabled"] === "true"}
onChange={(e) => setCfg("discover.enabled", e.target.checked ? "true" : "false")}
/>{" "}
Enable scheduled discovery sweep
</label>
{[
["discover.intervalHours", "Interval (hours)"],
["discover.maxSeeds", "Max seeds per sweep"],
["discover.similarPerSeed", "Similar per seed"],
["discover.albumsPerArtist", "Albums per artist"],
["discover.minScore", "Min score"],
].map(([key, label]) => (
<p key={key}>
<label>
{label}:{" "}
<input
type="number"
step="any"
value={discoverCfg[key] ?? ""}
onChange={(e) => setCfg(key, e.target.value)}
/>
</label>
</p>
))}
<button type="submit">Save discovery settings</button>
{discoverSaved && <span> Saved.</span>}
</form>
</> </>
); );
} }