Show cover thumbnail + chapter count in match search results

Backend: After the parallel search, fetch get_release_details for the
top-3 MusicBrainz hits in parallel. MB's search response carries
neither cover_url nor tracklist, so without this nothing useful
would show for MB results. Other sources already include cover in
their search response and don't have chapter data anyway.

Adds chapterCount to every result (0 when unknown). For MB matches
that resolve to a release with a tracklist, this is the actual count
that would be created as Chapters on apply.

UI: Match results now render as a row with a 48px cover thumbnail on
the left, title + metadata in the middle, Apply button on the right.
Metadata line shows author, year, source, confidence, and chapter
count (highlighted in green when present). Broken cover URLs hide
gracefully via onError.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Audiolib
2026-05-26 20:54:41 +02:00
parent edf057f36e
commit 7c8e98917d
2 changed files with 47 additions and 2 deletions

View File

@@ -373,6 +373,24 @@ async def search_for_item(title: str, author: str | None = None) -> list[dict]:
_search_source("dnb", search_dnb(search_title, author)),
)
# MusicBrainz: Search liefert weder Cover noch Tracklist.
# Für die Top-3 MB-Treffer Details holen, damit Cover + Kapitelzahl im UI sichtbar sind.
mb_top = sorted(mb, key=lambda r: r.confidence, reverse=True)[:3]
if mb_top:
async def _details(mb_result):
try:
return await get_release_details(mb_result.source_id)
except Exception as e:
logger.warning(f"MB-Details Fehler für {mb_result.source_id}: {e}")
return None
details = await asyncio.gather(*(_details(r) for r in mb_top))
for orig, detail in zip(mb_top, details):
if detail:
if detail.cover_url and not orig.cover_url:
orig.cover_url = detail.cover_url
if detail.chapters and not orig.chapters:
orig.chapters = detail.chapters
results = []
for r in mb + ol + gb + dnb:
results.append({
@@ -390,6 +408,7 @@ async def search_for_item(title: str, author: str | None = None) -> list[dict]:
"language": r.language,
"genres": r.genres,
"cover": r.cover_url,
"chapterCount": len(r.chapters or []),
"confidence": r.confidence,
})