soulsync 3.4.6: dev → main
basic search and the search page rebuilt, per-profile listening history from listenbrainz or last.fm, a redesigned dashboard and your library tab, a one-modal my account, a wishlist fix that stops staged tracks vanishing, a sync that no longer freezes the app, dead tidal/deezer/amazon endpoints handled, and a big chat pass for phones and laptops. scope: the 56 commits since the 3.4.5 release merge (#1283).
search rebuilt
- basic search: one search field with the source inside it, quiet rows with a quality badge, one download button. download asks how the file comes in: as-is, enriched, or tag it yourself. stream is gone.
- every basic search download is a real batch now, one task per file pinned to the exact file you picked, so it shows on the downloads page with the monitor, verification and history. torrent/usenet/lidarr stay on the direct route. a failed pick doesn't get wishlisted.
- enriched download is a react modal: one metadata provider end to end, the server maps files to tracks with the import matcher, and an answer from a different provider is refused instead of quietly used. the old vanilla matching modal is gone.
- tag it yourself: for bootlegs, live sets, anything no service knows. tagged exactly as typed, no id lookups, and locked so a rescan or maintenance job can't renumber, rematch or delete it. unlock is a menu item on the album.
- search page: catalog / videos / files tabs, the source is a pill in the field, a pasted link or mbid goes straight to the id lookup. filter pills with counts, a top result, artist faces with library artists first, cover grids with download on the art, label tiles. results stay put on a stray click.
- a blocklisted download asks "download anyway?" instead of failing generic, and album downloads stop logging as "Unknown Album".
- two-character names like U2 and A1 search remote sources again (#1291).
- wishlist "search manually" lands with the track in the box (#1294).
- playlist preview scrolls again, the play buttons were escaping into invisible full-window overlays (#1296).
- musicbrainz: "gotye somebody that i used to know" in one box found a jazz act named after the song. now the artist the query splits on wins and the title is searched as a track (#1297).
per-profile listening history (#1293)
- a navidrome admin can't read anyone else's plays, so every profile's stats, recently played and recommendations were the admin's listening.
- a profile that connects its own listenbrainz or types its last.fm username gets its own history: imported right away, hourly after, and its web player plays land there too. stats, recently played, daily mixes, stations and listening recs all read it.
- everyone else, and the admin, reads the shared history exactly like before. the scrobbler only posts the shared history, and last.fm is read with the app's key, never the admin's session.
- my accounts and my settings are one modal now: one person icon, a card saying whose listening your stats read, your media server login, then spotify, tidal, listenbrainz and last.fm. a running history import shows its progress in the row.
wishlist and downloads (@mandos21, #1288)
- atomic album publishing made a track visible only when the whole album finished, but the wishlist dropped it as soon as that one track staged. a crash or restart in between lost the track from both places, and a force-errored batch could have its staged audio swept five minutes later.
- a wishlist row is only removed now when the file really exists outside staging. staged tracks settle when the album publishes. staging trees carry a manifest and startup publishes any orphaned one, so an interrupted album shows up instead of vanishing. nothing staged is deleted except by an explicit cancel.
- every removal (and refusal) writes an audit row, so "where did this track go?" is a query.
- follow-ups: a track two profiles both wanted no longer gets refused as ambiguous, a deluxe-vs-plain release match no longer strands the track, a half-written manifest can't be published into the library root, and tasks point at the published files after publish.
- torrent rips and compilations claim their staged files: untagged "Artist_-_Title" rips and tagged compilations read as "Various Artists" both failed to match. replayed over 1500 real albums, zero lost matches, 461 new ones.
- music videos: each video is its own batch with a real phase, clears after 5 minutes, and keeps a history row. matching needs both artist and title to agree, live cuts and covers keep their bracket, no more "()" in the path, mp4s get tags, and cancel stops yt-dlp and removes partials.
app freezes
- a playlist sync held the one shared event loop for the whole sync, so search, downloads, slskd status and chat all queued behind it. the matcher, playlist write and wishlist step run on worker threads now.
- amazon search and its connection check were blocking http inline on that same loop, up to ~90s on a slow proxy. they run on the slow io executor now.
dead endpoints
- tidal retired
/searchResults/{query}, so every enrichment search 400'd and got recorded as not found. searches sendfilter[query]now and a one-time pass requeues the tidal not_found rows (#1290). failed tidal searches also log what tidal objected to, and "AC/DC" stops 400ing on its slash. - deezer's
artist:"X"filter returns nothing, so enrichment marked every track not found. artist goes in as plain words and the right artist's track is picked (#1295). - the public t2tunes amazon proxy is gone. amazon enrichment starts paused unless you point it at a self-hosted instance, and amazon is no longer offered as a download source (#1300).
library and imports
- your library tab redesigned: one row of source dots on the artist, one column of bigger album art, a "N missing" pill, one action row led by play with the rest in a ⋯ menu, and a "4/8" match meter per track instead of nine chips. applying a reassign no longer pops a delete confirmation.
- delete an artist from the artist detail page (admin, library artists). database only, no files touched, and the toast says when a media server will bring them back on the next scan.
- same-named releases stay separate: two musicbrainz releases that differ only by disambiguation ("baby punk version") no longer merge into one album with every song twice. the disambiguation goes on the folder, there's a new
$disambiguationvariable, and it's tagged as MUSICBRAINZ_ALBUMCOMMENT (#1299). - a compilation belongs to various artists: every soundtrack with one don felder track was filed under don felder (45 albums). the album now goes to various artists and the track keeps its own credit. new imports only. the multi-artist compilation toggle is finally in settings.
- reorganize writes album artist from the source instead of the old tag, so wrong navidrome album artist variations stop coming back.
- genre cleanup sticks: a media server scan used to put the old genres back. fixed rows are locked like art.
- the auto-import scan read a different folder than the one you configured (relative paths, ~, windows drive letters under docker). it uses the shared resolver now, and a fallback warns loudly instead of silently reading ./Staging.
- "The Noose" no longer matches "The Doomed" on the import page, a shared "the" isn't enough (#1292).
- navidrome paths resolve to "Artist - Album - NN - Title" files, so the duplicate cleaner stops refusing every finding (#1298).
- the duplicate detector compares the track artist, so a compilation copy matches the song on the artist's own album (#1263).
- an artist's release list goes stale after 12 hours instead of 30 days, so a new single shows up.
- itunes album release dates no longer carry an iso timestamp (@sarab97, #1287).
discover and watchlist
- looking an artist up on the artist map no longer counts as a taste signal for discovery weekly, seasonal mix and the hero slider (#1284).
- download-context placeholders ("from_sync_modal") can no longer land on the watchlist as an artist id and seed 25 fake similar artists.
- clicking an album on the artist page opens the download modal with checkboxes, same as search (#1297).
dashboard and ui
- redesigned dashboard: hero with greeting, library size and one scan button, worker orbs on their own stage, a system rail with playlist sync health (sortable, running syncs on top), up next, watchlist and wishlist tiles. recently played folds repeats into one card with a count.
- the sidebar active sources panel shows the server and download chain as settings saved them, with status and one button into settings. it can't flip the media server mid-scan anymore; metadata still switches there (#1301).
- the primary metadata source dropdown is back in settings.
chat
- the page fits laptops and phones again: chat-overhaul.css was beating every breakpoint. phones get one row of room pucks, a usable composer, no ios zoom on the message box, and text sized a step under desktop.
- a playing video or loaded preview survives new messages: the list is patched in place instead of rebuilt.
- link previews can't be steered into the lan: every resolved address is checked and redirects are walked by hand with the guard on each hop. theme colours must be hex, so a page can't restyle the app.
- settings modal is tabs, lead dev and dev are separate tags, 144 more avatars.
misc
- readme rewritten from a full review of the app.
- ten failing vitest cases were stale tests, fixed to match the code, and five slow ones sped up.