android: your own Soulseek interests, and who the server says is like you

Community's fourth tab is Taste: the likes and hates this client
publishes to the Soulseek server (slsk_interests_mine, slsk_interest_set),
added and taken back as chips, and the people the server ranks as close to
them (slsk_similar_users) — a row each into the peer sheet the app already
has. Every declaration asks the server again and the chips stay quiet
until it has answered, the way the desktop does, because the ranking only
moves when its input does. The lists live in taste.svelte.js, read once
per account when the tab is opened; the mock walk declares a like, watches
the match grow, declares a hate and takes the like back.
This commit is contained in:
KeelrLeek committed 2026-09-13 22:52:03 -05:00
1 parent 7eae0ee945
commit e693dfb868
6 files changed
+195 -6

No files matched your search

+19
View File
@@ -570,6 +570,9 @@ const cacheSizes = new Map(); // path → the file's size, for stream_cache_le
const preloading = new Set();
let xfer = null; // the one fake transfer: { received, total, timer }
let posTimer = null; // the fake engine's position ticks
/* the interests this fake account has declared, and the server's match on
them — a declaration moves both, the way the real server does */
const MY_INTERESTS = { likes: ["Daft Punk", "french house", "Warp Records"], hates: ["loudness war"] };
function mockNet(cmd, args) {
if (cmd === "get_credentials") return Promise.resolve({ username: MOCK_USER, has_password: true });
if (cmd === "connect_stored" || cmd === "connect_and_login") {
@@ -676,6 +679,22 @@ function mockNet(cmd, args) {
return Promise.resolve(t);
}
if (cmd === "stop_search") return Promise.resolve();
if (cmd === "slsk_interests_mine") return Promise.resolve({ likes: MY_INTERESTS.likes.slice(), hates: MY_INTERESTS.hates.slice() });
if (cmd === "slsk_interest_set") {
const thing = String(args?.thing || "").trim();
if (!thing) return Promise.reject(new Error("nothing to declare"));
const list = args?.like ? MY_INTERESTS.likes : MY_INTERESTS.hates;
const at = list.findIndex((t) => t.toLowerCase() === thing.toLowerCase());
if (args?.on && at < 0) list.push(thing);
if (!args?.on && at >= 0) list.splice(at, 1);
return new Promise((r) => setTimeout(() => r({ likes: MY_INTERESTS.likes.slice(), hates: MY_INTERESTS.hates.slice() }), 200));
}
if (cmd === "slsk_similar_users") {
/* the server ranks on the likes we declared: one more name per like */
const pool = ["hifi_hank", "dusty_crates", "mp3_marge", "ada", "cy", "bo"];
const n = MY_INTERESTS.likes.length;
return new Promise((r) => setTimeout(() => r(pool.slice(0, Math.min(pool.length, n + 1)).map((username, i) => ({ username, rating: Math.max(1, n - i) }))), 300));
}
if (cmd === "player_state") return Promise.resolve({ status: "idle", position: 0 });
if (cmd === "preload_local") return Promise.resolve();
if (cmd === "waveform") {