4 Commits
8 changed files with 89 additions and 29 deletions

No files matched your search

Generated
+10 -10
View File
@@ -160,7 +160,7 @@ checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]] [[package]]
name = "app" name = "app"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"audio-formats", "audio-formats",
"base64 0.22.1", "base64 0.22.1",
@@ -243,7 +243,7 @@ dependencies = [
[[package]] [[package]]
name = "audio-formats" name = "audio-formats"
version = "1.7.0-alpha" version = "1.7.1-alpha"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
@@ -1410,7 +1410,7 @@ dependencies = [
[[package]] [[package]]
name = "freenet-adapter" name = "freenet-adapter"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"bs58", "bs58",
"freenet-stdlib", "freenet-stdlib",
@@ -2535,7 +2535,7 @@ dependencies = [
[[package]] [[package]]
name = "library" name = "library"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"audio-formats", "audio-formats",
"log", "log",
@@ -2673,7 +2673,7 @@ dependencies = [
[[package]] [[package]]
name = "metadata" name = "metadata"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"futures", "futures",
"httpdate", "httpdate",
@@ -3292,7 +3292,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]] [[package]]
name = "persona-state" name = "persona-state"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"bincode", "bincode",
"blake3", "blake3",
@@ -3379,7 +3379,7 @@ checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548"
[[package]] [[package]]
name = "player" name = "player"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"audio-formats", "audio-formats",
"env_logger", "env_logger",
@@ -4408,7 +4408,7 @@ dependencies = [
[[package]] [[package]]
name = "soulseek-client" name = "soulseek-client"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"audio-formats", "audio-formats",
"bytes", "bytes",
@@ -4423,7 +4423,7 @@ dependencies = [
[[package]] [[package]]
name = "soulseek-proto" name = "soulseek-proto"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"bytes", "bytes",
"flate2", "flate2",
@@ -4823,7 +4823,7 @@ dependencies = [
[[package]] [[package]]
name = "tagger" name = "tagger"
version = "1.7.0-alpha" version = "1.7.1-alpha"
dependencies = [ dependencies = [
"lofty", "lofty",
"log", "log",
+1 -1
View File
@@ -14,7 +14,7 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "1.7.0-alpha" version = "1.7.1-alpha"
edition = "2021" edition = "2021"
rust-version = "1.77.2" rust-version = "1.77.2"
authors = ["Trifecta Solutions"] authors = ["Trifecta Solutions"]
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "soulstream", "name": "soulstream",
"version": "1.7.0-alpha", "version": "1.7.1-alpha",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "soulstream", "name": "soulstream",
"version": "1.7.0-alpha", "version": "1.7.1-alpha",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2" "@tauri-apps/api": "^2"
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "soulstream", "name": "soulstream",
"version": "1.7.0-alpha", "version": "1.7.1-alpha",
"type": "module", "type": "module",
"description": "SoulStream — music player, downloader and streamer for the Soulseek network", "description": "SoulStream — music player, downloader and streamer for the Soulseek network",
"scripts": { "scripts": {
+58 -3
View File
@@ -87,10 +87,13 @@ fn key(username: &str) -> String {
// ---------------------------------------------------------------- names // ---------------------------------------------------------------- names
/// Bracketed chunks go — "(2019)", "[FLAC]", "{web}" — then only letters and /// Bracketed chunks go — "(2019)", "[FLAC]", "{web}" — and so does a
/// digits remain, lowercased; a leading "the" goes too. "Sigur Rós" and /// dash-led edition tail — "Pinkerton - Deluxe Edition", "Foo - EP" — then
/// "sigur ros" are not the same string here, and that is a known miss. /// only letters and digits remain, lowercased; a leading "the" goes too.
/// "Sigur Rós" and "sigur ros" are not the same string here, and that is a
/// known miss.
pub(crate) fn norm(s: &str) -> String { pub(crate) fn norm(s: &str) -> String {
let s = strip_edition_tail(s);
let mut out = String::with_capacity(s.len()); let mut out = String::with_capacity(s.len());
let mut depth = 0i32; let mut depth = 0i32;
for c in s.chars() { for c in s.chars() {
@@ -115,6 +118,41 @@ pub(crate) fn norm(s: &str) -> String {
out out
} }
/// The catalogue spells an edition after a spaced dash where a folder would
/// bracket it — "Pinkerton - Deluxe Edition" is the gap card, "Pinkerton
/// (Deluxe Edition)" the folder — so a dash-led tail that reads as an
/// edition goes the way brackets do, and only that tail: "Boards of Canada -
/// Geogaddi" is a name with a dash in it and stays whole. Found 2026-09-09
/// when the deluxe card beside a marked Pinkerton carried no "has it".
fn strip_edition_tail(s: &str) -> &str {
let mut s = s.trim_end();
loop {
let Some((at, len)) = [" - ", " – ", " — "]
.iter()
.filter_map(|d| s.rfind(d).map(|i| (i, d.len())))
.max_by_key(|(i, _)| *i)
else {
return s;
};
let tail: String = s[at + len..]
.chars()
.filter(|c| c.is_alphanumeric())
.flat_map(|c| c.to_lowercase())
.collect();
if !is_edition_tail(&tail) {
return s;
}
s = s[..at].trim_end();
}
}
fn is_edition_tail(t: &str) -> bool {
matches!(t, "ep" | "single")
|| ["deluxe", "remaster", "edition", "expanded", "anniversary", "reissue", "bonus", "explicit"]
.iter()
.any(|w| t.contains(w))
}
fn is_disc_folder(s: &str) -> bool { fn is_disc_folder(s: &str) -> bool {
let n: String = s.to_lowercase().chars().filter(|c| c.is_alphanumeric()).collect(); let n: String = s.to_lowercase().chars().filter(|c| c.is_alphanumeric()).collect();
for p in ["cd", "disc", "disk", "vol", "volume", "side"] { for p in ["cd", "disc", "disk", "vol", "volume", "side"] {
@@ -352,4 +390,21 @@ mod tests {
assert_eq!(norm("2000 - Spirit They're Gone Spirit They've Vanished"), "spirittheyregonespirittheyvevanished"); assert_eq!(norm("2000 - Spirit They're Gone Spirit They've Vanished"), "spirittheyregonespirittheyvevanished");
assert!(is_disc_folder("Disc 2") && is_disc_folder("cd1") && !is_disc_folder("Discovery")); assert!(is_disc_folder("Disc 2") && is_disc_folder("cd1") && !is_disc_folder("Discovery"));
} }
#[test]
fn dash_led_editions_go_the_way_brackets_do() {
assert_eq!(norm("Pinkerton - Deluxe Edition"), "pinkerton");
assert_eq!(norm("Pinkerton – Deluxe Edition"), "pinkerton");
assert_eq!(norm("Pinkerton — Deluxe Edition"), "pinkerton");
assert_eq!(norm("Pinkerton - Deluxe Edition (2010)"), "pinkerton");
assert_eq!(norm("Album - Deluxe Edition - Remastered"), "album");
assert_eq!(norm("Kid A - 2019 Remaster"), "kida");
assert_eq!(norm("Foo - EP"), "foo");
assert_eq!(norm("Foo - Single"), "foo");
assert_eq!(norm("Pinkerton (Deluxe Edition) [2010]"), norm("Pinkerton - Deluxe Edition"));
// A dash inside a name is not an edition.
assert_eq!(norm("Boards of Canada - Geogaddi"), "boardsofcanadageogaddi");
assert_eq!(norm("Album - Live"), "albumlive");
assert_eq!(norm("1996 - Expert Knob Twiddlers"), "expertknobtwiddlers");
}
} }
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "SoulStream", "productName": "SoulStream",
"version": "1.7.0-alpha", "version": "1.7.1-alpha",
"identifier": "com.soulstream.app", "identifier": "com.soulstream.app",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",
Binary file not shown.
+16 -11
View File
@@ -3583,18 +3583,23 @@
/* ── dark glass ──────────────────────────────────────────────────────── /* ── dark glass ────────────────────────────────────────────────────────
The ladder lives in global.css. Solid mode sees none of this. The ladder lives in global.css. Solid mode sees none of this.
The toolbar was the loudest surface on the page and it was loud for two The toolbar was the loudest surface on the page, measured on 2026-08-27
compounding reasons, both measured on 2026-08-27 with a known-colour with a known-colour ground substituted behind the window
ground substituted behind the window (research/scroll-diag/glassshot.mjs): (research/scroll-diag/glassshot.mjs): its 0.82 fill over the frost
its own fill nets 0.82 + 0.7075x0.18 = 0.947 — a slab by alpha alone — netted 0.947 — a slab by alpha alone — and dropping fill and filter
AND its backdrop-filter samples the see-through pane, which the made it the see-through card that shipped. It is SOLID again by
compositor flattens against black (the measurement lives in Kyle's word (2026-09-09: "just make it a solid bar"), and on purpose:
Sidebar.svelte). Chroma of the shipped bar, blue-minus-red over a a backdrop-filter over the pane's frost cannot hide thin content —
#6b3fa8 ground: +2, i.e. dead. Fill alone got it to +12; dropping the Chromium paints the filtered backdrop OVER the original, so a title
filter as well got it to +16, against +30 for the bare pane beside it. on bare frost stays crisp under the haze (measured that day, chroma
Both halves were needed, so both are here. */ +11 with the filter vs +17 without) — and the periscope twin built
that afternoon (a pane-level copy of the bar over a deepened band
cut, fogged by a page clone, GlassBar's pattern) still read as
broken on his screen and went the same day. An opaque card floating
on the glass: the elevated surface at full strength, hairline and
shadow as before, nothing behind it to sample. */
:global(:root.glass) .lib-toolbar { :global(:root.glass) .lib-toolbar {
background: rgba(255, 255, 255, 0.06); background: var(--bg-elevated);
backdrop-filter: none; backdrop-filter: none;
-webkit-backdrop-filter: none; -webkit-backdrop-filter: none;
} }