diff --git a/src/components/Chooser.svelte b/src/components/Chooser.svelte
new file mode 100644
index 0000000..4fda85a
--- /dev/null
+++ b/src/components/Chooser.svelte
@@ -0,0 +1,149 @@
+
+
+
+
+{#if open}
+
+{/if}
+
+
diff --git a/src/views/Settings.svelte b/src/views/Settings.svelte
index 758b504..e04efe8 100644
--- a/src/views/Settings.svelte
+++ b/src/views/Settings.svelte
@@ -10,6 +10,7 @@
import { applyGlass } from "../lib/glass.js";
import * as api from "../lib/api.js";
import Icon from "../components/Icon.svelte";
+ import Chooser from "../components/Chooser.svelte";
import {
community,
refreshFreenet,
@@ -311,6 +312,19 @@
return d.toLocaleDateString([], { month: "short", day: "numeric" });
}
+ // ---- the long lists, as [value, label] for the chooser -------------------
+ const RETENTION = [["1", "1 day"], ["3", "3 days"], ["7", "1 week"], ["14", "2 weeks"], ["30", "1 month (recommended)"], ["90", "3 months"], ["forever", "Forever — save to library"]];
+ const CACHE = [["512", "512 MB"], ["1024", "1 GB"], ["2048", "2 GB (recommended)"], ["5120", "5 GB"], ["10240", "10 GB"], ["20480", "20 GB"], ["0", "Unlimited"]];
+ const MIN_QUALITY = [["any", "Any quality"], ["kbps192", "192 kbps and up"], ["kbps256", "256 kbps and up"], ["kbps320", "320 kbps and up"], ["lossless", "Lossless only"]];
+ const audioOutputs = $derived.by(() => {
+ if (!settings) return [];
+ const out = [["", "System default (recommended)"]];
+ const cur = settings.audio_output_device;
+ if (cur && !settings.audio_output_devices.includes(cur)) out.push([cur, `${cur} (unavailable)`]);
+ for (const d of settings.audio_output_devices) out.push([d, d]);
+ return out;
+ });
+
// ---- the index ---------------------------------------------------------
const SECTIONS = [
{ id: "account", title: "Account", group: "You" },
@@ -533,17 +547,7 @@
Audio output
System default follows Windows when headphones or speakers change.
-
-
-
+ setAudioOutput(v)} disabled={saving} />
@@ -611,34 +615,14 @@
Keep streamed tracks
Streamed songs stay in a private cache for instant replay — not in your library. Forever adds everything you stream to the library instead.
-
-
-
+
setStreamRetention(v)} disabled={saving} />
Cache size limit
Oldest streamed tracks are removed first once the cache passes this size. Saved and downloaded music is never touched.
-
-
-
+
setStreamCacheMax(v)} disabled={saving} />
@@ -721,15 +705,7 @@
Minimum
Reject files below this floor. Lossy files must report a bitrate to qualify.
-
-
-
+ setSourcePref(mode.key, "min", v)} disabled={saving} />
@@ -876,13 +852,6 @@
.seg button.on { background: var(--accent); color: #000; }
.seg button:hover:not(.on):not(:disabled) { color: #fff; }
.seg button:disabled { opacity: 0.6; cursor: default; }
- /* a long list stays a real