Commit graph

3174 commits

Author SHA1 Message Date
BoulderBadgeDad
c02cf15fdf
Merge pull request #644 from kettui/refactor/artist-detail-react-route
Centralize artist-detail page hand-off logic, make it URL-driven
2026-05-19 12:07:12 -07:00
Antti Kettunen
37f1adef4a
fix(stats): remove non-existent artist_source 2026-05-19 21:23:11 +03:00
Antti Kettunen
54efb85240
fix(webui): guard similar artist bubbles
- avoid calling buildArtistDetailPath when a similar artist has no usable id
- render a disabled bubble instead so empty MusicBrainz IDs do not crash the panel
2026-05-19 21:21:02 +03:00
Antti Kettunen
fa0ac4ced3
refactor(webui): simplify similar artists cleanup
- no need for a separate effect since we can use the existing one
- no need to cancel the similar artists query upon entering, since the
  unregister callback already does it
2026-05-19 10:40:41 +03:00
Antti Kettunen
0d683d87c0
refactor(webui): link artist detail navigation
- replace click-driven artist-detail hops with semantic links
- keep SPA transitions via shell bridge interception for /artist-detail/:source/:id
- drop legacy page helper wrappers and dead bridge plumbing
2026-05-19 10:22:59 +03:00
Antti Kettunen
30c687ae7b
refactor(webui): cancel similar-artists in route
- expose a shell-bridge cancel primitive for similar-artists loading
- stop stale similar-artists streams from the artist-detail route lifecycle
- keep the legacy loader abort-only and make abort logs page-agnostic
- update bridge and route tests for the new cleanup path
2026-05-19 09:28:05 +03:00
Antti Kettunen
5e39f1ee09
refactor(webui): centralize artist-detail handoff
- add a canonical TanStack route for artist-detail and keep the legacy page as the renderer target
- expose page-level artist-detail navigation on the shell bridge for legacy callers
- remove artist-detail-specific routing, origin stack, and back-label logic from the shared shell helpers
2026-05-19 09:26:10 +03:00
Antti Kettunen
728481db31
refactor(webui): route artist-detail handoff
- add canonical /artist-detail/:source/:id TanStack route
- hand the legacy page off through the shell bridge
- remove artist-detail branching from generic shell helpers
2026-05-19 08:14:13 +03:00
Broque Thomas
56eff933d4 Delete pr_description.md 2026-05-18 21:56:59 -07:00
Broque Thomas
e0e31079e6 Update test: get_release includes cover-art-archive 2026-05-18 21:20:57 -07:00
Broque Thomas
f7dfc3aab2 Fix MusicBrainz cover art using release-level CAA scope when available
Include cover-art-archive in the get_release call so _render_release_as_album
can check whether the representative release actually has front art before
building the URL. Prefer release-scope when confirmed present; fall back to
release-group scope otherwise. Prevents storing a release-group URL that CAA
reports as having no art.
2026-05-18 21:16:35 -07:00
Broque Thomas
19307630d1 Fix missing album art for non-Spotify sources + animate Downloads nav icon
- watchlist_scanner: fall back to album.image_url when album object has no
  images list (affects MusicBrainz CAA URLs, iTunes, Deezer — all use
  image_url on the Album dataclass, not the Spotify-style images array)
- Pulse Downloads nav icon while active downloads are in progress, same
  pattern as watchlist scan animation
2026-05-18 20:24:13 -07:00
Broque Thomas
8dd39dee65 Pulse watchlist nav icon during active watchlist scan 2026-05-18 20:13:50 -07:00
Broque Thomas
3ae0ac9d55 Fix musicbrainz test button 2026-05-18 20:08:24 -07:00
Broque Thomas
bbeec87f39 2.5.6 2026-05-18 20:06:48 -07:00
BoulderBadgeDad
801cd10134
Merge pull request #640 from Nezreka/codex/musicbrainz-metadata-source
Codex/musicbrainz metadata source
2026-05-18 19:36:21 -07:00
Broque Thomas
24d0482697 Update diagnose_itunes_discover.py 2026-05-18 19:31:36 -07:00
Broque Thomas
f3ad65de34 Complete MusicBrainz watchlist source parity
Add MusicBrainz watchlist artist ID storage, badges, linked-provider editing, and per-artist preferred source support.

Backfill watchlist MusicBrainz matches from already-enriched library artists so existing MusicBrainz worker matches appear in watchlist cards and settings.

Extend bulk watchlist add, liked artist matching, artist map source picking, and service status labels to recognize MusicBrainz, with regression tests for watchlist ID persistence and backfill.
2026-05-18 19:19:25 -07:00
Broque Thomas
5bc5fbb662 Add MusicBrainz as a metadata source
Register MusicBrainz as a first-class metadata source alongside Deezer, iTunes, Spotify, Discogs, and Hydrabase. Expose the shared client through metadata services, add the settings option, and expand the MusicBrainz search adapter with source-compatible artist, album, track, and detail methods.

Carry MusicBrainz IDs through similar-artist discovery, recommended artists, artist map serialization, and personalized playlist selection. Update DB migrations and lookup filters so similar_artist_musicbrainz_id is preserved on older schemas and used for source requirements and library exclusion.

Normalize MusicBrainz album adapter output for import context and add regression coverage for registry mapping, typed album conversion, and similar-artist filtering. Verified by user with 120 focused tests passing.
2026-05-18 18:47:13 -07:00
Broque Thomas
aaf312cd34 Honor manual library matches across source labels
Manual matches can be created from sync history as mirrored while wishlist and download flows later see the same track as wishlist or a provider source. Add a shared track-level lookup that falls back from exact source/id to source_track_id and title/artist, then use it for wishlist adds, cleanup, and download analysis so mapped tracks are not re-added or redownloaded.

Add coverage for mirrored-source matches being honored by wishlist cleanup and download batches, including the internal wishlist force-download path.
2026-05-18 16:32:38 -07:00
Broque Thomas
52dcdbe0f7 Harden Amazon worker schema migration
Ensure the Amazon enrichment worker verifies its required columns before querying pending work or progress, preventing upgraded installs from spamming no-such-column errors when amazon_match_status is missing.

Add regression coverage for legacy databases without Amazon enrichment columns.
2026-05-18 15:47:04 -07:00
BoulderBadgeDad
33673a6e3a
Merge pull request #636 from Nezreka/feat/artist-detail-deep-link
Feat/artist detail deep link
2026-05-18 15:38:22 -07:00
Broque Thomas
098c787861 Add release art fallback for artist detail hero
Use the first available album, EP, or single artwork when an artist portrait is missing or fails to load, keeping artist detail pages visually populated across library and source-only artists.

Refresh the PR description for the artist detail deep-link branch.
2026-05-18 15:07:09 -07:00
Broque Thomas
a6282b3009 Fix source artist detail navigation from discover modals
Preserve source metadata for seasonal and cached discover album modals so artist links use real provider IDs instead of falling back to library/name routes.

Treat source-only artist detail discographies as clickable missing releases and skip library-only ownership/enhancement checks.
2026-05-18 13:50:10 -07:00
Broque Thomas
3a4017ea2b feat: artist-detail deep linking — /artist-detail/:source/:id
Artist detail pages previously always pushed /artist-detail to the URL,
so refreshing the page or sharing a link would drop users on a broken
empty page with no artist loaded.

URL format is now /artist-detail/:source/:id (e.g.
/artist-detail/spotify/4tZwfgrHOc3mvqsCAfo4LT or
/artist-detail/library/42). The source segment lets the backend
synthesize a response from the right metadata client without a DB hit.

Changes:

Client routing (legacy shell + TanStack bridge)
- buildArtistDetailPath / _getDeepLinkArtistDetail added to init.js;
  parse both new :source/:id and legacy bare :id formats so old
  bookmarks still work
- navigateToPage passes artistId + artistSource through to the router
  bridge, which builds the dynamic href instead of hardcoding route.path
- resolveShellPageFromPath / resolveLegacyShellPageFromPath use a prefix
  match so /artist-detail/* resolves to artist-detail page-id
- globals.d.ts typed for artistId / artistSource options
- activateLegacyPath and syncActivePageFromLocation (popstate) both
  restore artist from URL using skipRouteChange:true to avoid a
  re-navigation loop back to /artist-detail
- loadInitialData restores artist from URL on page load (router not yet
  mounted at DOMContentLoaded so legacy path runs unconditionally)
- Same-artist guard in navigateToArtistDetail prevents double-fetch
  when the router fires activateLegacyPath after the initial navigation

Server
- artist_source_detail.build_source_only_artist_detail now resolves
  artist name from the source API when none is supplied, so deep-link
  restores with an empty name string still render correctly

Tests
- test_spa_deep_linking: /artist-detail/42 and /artist-detail/spotify/ID
  both serve index.html
- bridge.test.ts: source-aware URL building and library fallback
- route-manifest.test.ts: prefix path resolution
- artist_source_detail: name resolved from source when input is empty
2026-05-18 13:07:54 -07:00
Broque Thomas
e061f12a05 Filter owned artists from discovery recommendations 2026-05-18 11:40:12 -07:00
Broque Thomas
04adbf01e2 Update index.html 2026-05-18 09:56:39 -07:00
BoulderBadgeDad
25a3bcda62
Merge pull request #633 from Nezreka/codex/quarantine-followups
Harden quarantine approval flows
2026-05-18 08:44:16 -07:00
Broque Thomas
f25433ea57 Harden quarantine approval flows 2026-05-18 08:37:11 -07:00
BoulderBadgeDad
fc00d0311e
Merge pull request #632 from Nezreka/codex/source-aware-artist-detail-links
Preserve source when opening artist detail
2026-05-18 07:55:08 -07:00
Broque Thomas
cd715f8697 Preserve source when opening artist detail 2026-05-17 23:40:39 -07:00
Broque Thomas
6af5d191cd Release 2.5.5 — Manual Library Match
Bump version to 2.5.5. Collapse WHATS_NEW to 2.5.5 block (Manual Library
Match entry only). Remove subreddit link from README.
2026-05-17 23:18:59 -07:00
BoulderBadgeDad
ed01a1af8c
Merge pull request #626 from Nezreka/codex/full-release-date-tags
Preserve full release dates in audio tags
2026-05-17 23:11:10 -07:00
Broque Thomas
54dbd150cb Preserve full release dates in audio tags 2026-05-17 23:02:41 -07:00
BoulderBadgeDad
3e67ac6887
Merge pull request #625 from Nezreka/codex/artist-owned-album-matching
Tighten artist discography soundtrack matching
2026-05-17 22:59:40 -07:00
Broque Thomas
025007b97f Tighten artist discography soundtrack matching 2026-05-17 22:51:38 -07:00
BoulderBadgeDad
1cf85987dc
Merge pull request #624 from Nezreka/codex/quarantine-button-escaping
Fix quarantine action button escaping
2026-05-17 22:03:19 -07:00
Broque Thomas
52ee406a6c Fix quarantine action button escaping 2026-05-17 21:47:56 -07:00
BoulderBadgeDad
de560cac85
Merge pull request #623 from Nezreka/codex/manual-library-match
Codex/manual library match
2026-05-17 21:18:30 -07:00
Broque Thomas
0345478361 Skip wishlist adds for manual library matches 2026-05-17 20:50:55 -07:00
Broque Thomas
3e7eeb7c9c Honor manual matches in automatic wishlist cleanup 2026-05-17 20:43:04 -07:00
Broque Thomas
94f6c950cb Polish manual library match tool card 2026-05-17 20:32:18 -07:00
Broque Thomas
42f4aa5eac Add manual library track matching 2026-05-17 20:27:05 -07:00
BoulderBadgeDad
4d882180bb
Merge pull request #622 from Nezreka/codex/missing-track-import
Codex/missing track import
2026-05-17 14:27:12 -07:00
Broque Thomas
f3d5ef6528 Test missing-track existing file imports
Add service-level coverage for the Enhanced Library I Have This flow: copying an existing source file, writing the target album DB row, preserving source audio, inheriting album identity tags, and migrating older track tables that lack disc_number.
2026-05-17 14:18:17 -07:00
Broque Thomas
f9ae0e8d58 Extract missing-track import service
Move the existing-file missing-track import workflow out of web_server.py and into core/library/missing_track_import.py.

Keep the Flask route focused on request wiring and response formatting while the service handles staging copy, post-processing, album identity tag inheritance, DB upsert, and media-server sync.
2026-05-17 14:04:28 -07:00
Broque Thomas
3b62bcab0c Add missing-track import from existing library files
Show actionable missing album tracks in the enhanced library from canonical metadata, with a practical Manage flow for Add to Library or I Have This.

Implement I Have This as a non-destructive copy/import path: copy the chosen existing file, run normal post-processing with the missing track context, insert the real library row, and inherit album identity tags from target siblings so Navidrome does not split albums.

Improve the modal with selectable search results, visible import progress, disabled controls during import, and missing-track row styling.
2026-05-17 13:58:11 -07:00
BoulderBadgeDad
d734f92e19
Merge pull request #621 from Nezreka/codex/slskd-album-preflight
Improve Soulseek album source selection
2026-05-17 10:11:49 -07:00
Broque Thomas
076cf9e516 Improve Soulseek album source selection
Add a conservative Soulseek album preflight scorer so album downloads choose a coherent slskd folder before per-track enqueue. The scorer compares album title, artist, year, track count, tracklist coverage, peer quality, and penalizes unexpected deluxe/remix/live-style folders.

Preserve hybrid source priority by only running Soulseek album preflight when Soulseek is the selected source or first in the hybrid order. If Soulseek is only a fallback behind another source, the normal hybrid flow is left alone.

Reuse the richest wishlist album context across tracks in the same album group so release date, artwork, album type, and album artist stay consistent for path generation. Also preserve peer-quality tie breakers when attempting equal-confidence candidates.

Tests cover correct-folder selection over larger wrong editions, Soulseek primary vs fallback hybrid behavior, shared wishlist album context, and peer-quality candidate ordering.
2026-05-17 10:08:43 -07:00
Broque Thomas
57cbdc2ed4 Update docker-publish.yml 2026-05-16 23:10:44 -07:00