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:
@@ -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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user