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]]
name = "app"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"audio-formats",
"base64 0.22.1",
@@ -243,7 +243,7 @@ dependencies = [
[[package]]
name = "audio-formats"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
[[package]]
name = "autocfg"
@@ -1410,7 +1410,7 @@ dependencies = [
[[package]]
name = "freenet-adapter"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"bs58",
"freenet-stdlib",
@@ -2535,7 +2535,7 @@ dependencies = [
[[package]]
name = "library"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"audio-formats",
"log",
@@ -2673,7 +2673,7 @@ dependencies = [
[[package]]
name = "metadata"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"futures",
"httpdate",
@@ -3292,7 +3292,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "persona-state"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"bincode",
"blake3",
@@ -3379,7 +3379,7 @@ checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548"
[[package]]
name = "player"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"audio-formats",
"env_logger",
@@ -4408,7 +4408,7 @@ dependencies = [
[[package]]
name = "soulseek-client"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"audio-formats",
"bytes",
@@ -4423,7 +4423,7 @@ dependencies = [
[[package]]
name = "soulseek-proto"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"bytes",
"flate2",
@@ -4823,7 +4823,7 @@ dependencies = [
[[package]]
name = "tagger"
version = "1.7.0-alpha"
version = "1.7.1-alpha"
dependencies = [
"lofty",
"log",
+1 -1
View File
@@ -14,7 +14,7 @@ members = [
]
[workspace.package]
version = "1.7.0-alpha"
version = "1.7.1-alpha"
edition = "2021"
rust-version = "1.77.2"
authors = ["Trifecta Solutions"]
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "soulstream",
"version": "1.7.0-alpha",
"version": "1.7.1-alpha",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "soulstream",
"version": "1.7.0-alpha",
"version": "1.7.1-alpha",
"license": "ISC",
"dependencies": {
"@tauri-apps/api": "^2"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "soulstream",
"version": "1.7.0-alpha",
"version": "1.7.1-alpha",
"type": "module",
"description": "SoulStream — music player, downloader and streamer for the Soulseek network",
"scripts": {
+58 -3
View File
@@ -87,10 +87,13 @@ fn key(username: &str) -> String {
// ---------------------------------------------------------------- names
/// Bracketed chunks go — "(2019)", "[FLAC]", "{web}" — then 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.
/// Bracketed chunks go — "(2019)", "[FLAC]", "{web}" — and so does a
/// dash-led edition tail — "Pinkerton - Deluxe Edition", "Foo - EP" — then
/// 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 {
let s = strip_edition_tail(s);
let mut out = String::with_capacity(s.len());
let mut depth = 0i32;
for c in s.chars() {
@@ -115,6 +118,41 @@ pub(crate) fn norm(s: &str) -> String {
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 {
let n: String = s.to_lowercase().chars().filter(|c| c.is_alphanumeric()).collect();
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!(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",
"productName": "SoulStream",
"version": "1.7.0-alpha",
"version": "1.7.1-alpha",
"identifier": "com.soulstream.app",
"build": {
"beforeDevCommand": "npm run dev",
Binary file not shown.
+16 -11
View File
@@ -3583,18 +3583,23 @@
/* ── dark glass ────────────────────────────────────────────────────────
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
compounding reasons, both measured on 2026-08-27 with a known-colour
ground substituted behind the window (research/scroll-diag/glassshot.mjs):
its own fill nets 0.82 + 0.7075x0.18 = 0.947 — a slab by alpha alone —
AND its backdrop-filter samples the see-through pane, which the
compositor flattens against black (the measurement lives in
Sidebar.svelte). Chroma of the shipped bar, blue-minus-red over a
#6b3fa8 ground: +2, i.e. dead. Fill alone got it to +12; dropping the
filter as well got it to +16, against +30 for the bare pane beside it.
Both halves were needed, so both are here. */
The toolbar was the loudest surface on the page, measured on 2026-08-27
with a known-colour ground substituted behind the window
(research/scroll-diag/glassshot.mjs): its 0.82 fill over the frost
netted 0.947 — a slab by alpha alone — and dropping fill and filter
made it the see-through card that shipped. It is SOLID again by
Kyle's word (2026-09-09: "just make it a solid bar"), and on purpose:
a backdrop-filter over the pane's frost cannot hide thin content —
Chromium paints the filtered backdrop OVER the original, so a title
on bare frost stays crisp under the haze (measured that day, chroma
+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 {
background: rgba(255, 255, 255, 0.06);
background: var(--bg-elevated);
backdrop-filter: none;
-webkit-backdrop-filter: none;
}