soulsync 3.1.1 — dev → main
fixes-and-polish release: a stack of reported bugs on the music side, a continue-watching upgrade for the video detail pages, and the app makes way fewer http calls at idle.
music fixes
- re-releases showed as owned — owning the original of an album made every remaster/anniversary edition light up as owned too. album matching now respects the release year when both sides have one, and the canonical pin denies sibling editions from its own source. owning "Album" no longer claims "Album (2011 Remaster)".
- deep scan finally removes artists that left your library — switching plex to a smaller/empty library kept showing the old artists forever. deep scan reads the server fresh (not a stale cache) and cleans out artists that are really gone. it also refuses to mass-delete when the server call failed rather than returned empty, so a plex hiccup can't wipe your artist list.
- force download actually replaces the file (#1045) — "download again" used to import the new file next to the old one or skip it entirely. a forced re-download now really replaces what's on disk.
- playlist sync stops leaving tracks behind (#1047) — three stacked bugs: matches in the 0.70–0.79 confidence band were found and then thrown away, tracks whose plex ratingKey went stale (plex re-keys on metadata refresh) failed silently, and big playlist writes could partially land with nobody checking. all fixed — writes are chunked and verified against what the server actually stored.
- whole-library m3u note (#1041) — the library playlist m3u was generating fine but told nobody. the scan summary now says it ran and where the file landed.
- artists named with digits work again — clicking "311" did nothing (the router ate the name as a number). fixed.
- repeatedly-failing wishlist downloads are visible now — wishlist items that keep failing get an attempt counter and a "failing" badge, a filter to see only them, and a jump straight into manual search to fix them by hand. same badge system on the video wishlist.
video: the detail pages grew up
compared the movie/show pages against netflix/disney+ and closed the obvious gaps:
- continue watching — soulsync now scans per-episode watch state from plex/jellyfin (watched, resume position, last watched). episode lists get checkmarks, progress bars and a "next up" highlight; the hero button becomes "Resume S2 E4 on Plex" and deep-links the episode; shows open on the season you're actually in; movies know they're half-watched.
- mark watched / unwatched — a real toggle on movies and shows that also pushes played state to your server.
- facts we already had but never showed — the awards line (🏆 "Won 2 Oscars…"), an after-credits-scene tag, NEW badges on freshly-landed episodes, digital release date, and the ranked quality name of your file.
- format badges — owned movies show 4K · HDR10 · DV · Atmos · 7.1 style badges from real stream data (jellyfin) or the release name (plex).
- synchronize one show — a per-show deep scan button that reconciles episodes against the server right now, survives plex re-keys, and refreshes the episode schedule. paired with a hard rule from a painful bug: episodes that vanish from the server get demoted to "missing", never deleted.
- clickable metadata (#1042) — genres/keywords filter the library, and where-to-watch icons actually link per service.
- mass rename preview — no more dead button on big libraries: it runs in the background with a live count and shows loading/empty/error states.
- youtube episode numbering — yt-dlp's real upload date now overrides scan-estimated dates, so a video estimated as "1 month ago" can't collide into the wrong episode number.
performance: the request flood is gone
startup and idle used to hammer the backend (dozens of duplicate calls per page load, 14 widgets each polling enrichment status every 2s):
- identical api GET bursts are deduped client-side — one wire request per burst
- enrichment status hydrates once per side in a single bundled call instead of ~28 requests
- steady-state pollers slowed to sane intervals and skip entirely when the tab is hidden
also
- CI: the flaky mass-rename test now diagnoses itself instead of failing anonymously
- video schema v45→v46 (all column adds ride the migration list, upgrades are automatic)