mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 23:35:44 +00:00
fix(artist): show fanart in the artist-detail hero, not the Navidrome cover (#1172)
* fix(cover): report a genuine miss for external artist surfaces When external artwork is enabled, the fanart/banner ensure fell through to the Navidrome cover and returned it as a hit on a fanart.tv miss. That made 'this artist has no banner' indistinguishable from a real hit, so the artist-detail hero short-circuited on the ND cover and never reached the fanart it actually had. Return hit=false on an external-surface miss instead; the Navidrome fallback is the caller's job, since each surface has its own chain (hero: banner->fanart->ND, fullscreen player: fanart->ND). * fix(artist): hero background banner->fanart->Navidrome with raised focal point The hero header background now steps through banner -> fanart -> Navidrome artist cover, resolving the ND cover the same way the fullscreen player does. Previously it had no Navidrome stage at all and, combined with the backend masking a banner miss as a hit, showed the ND cover where the fanart belonged. Also raise the focal point (background-position: center 30%) for the portrait-ish fanart/ND images so the band's heads stay in frame on wide (2K+) viewports, where 'cover' scales them up and overflows vertically. The wide banner strip keeps the shared center. Done via a scoped inline style; .album-detail-bg stays untouched for the album/playlist headers that share it. * docs(changelog): artist header external-background fallback fix (#1172)
This commit is contained in:
@@ -302,12 +302,18 @@ impl CoverCacheState {
|
||||
}
|
||||
|
||||
// For an external artist surface (`fanart` 16:9 background or `banner`
|
||||
// strip), try fanart.tv before the Navidrome fallback. On any miss it
|
||||
// falls through WITHOUT writing a `.fetch-failed` marker, so Navidrome
|
||||
// stays the display fallback (§28).
|
||||
// strip), resolve fanart.tv only. On a hit we return the external image;
|
||||
// on a miss we report a genuine `hit=false` (no `.fetch-failed` marker)
|
||||
// and DO NOT fall back to the Navidrome cover here. The fallback is the
|
||||
// caller's job, because each surface has its own chain: the artist-detail
|
||||
// hero wants banner → fanart → Navidrome, the fullscreen player wants
|
||||
// fanart → Navidrome. Falling back to Navidrome at this layer would mask
|
||||
// "this artist has no banner" as a hit and short-circuit the caller's
|
||||
// fanart step (the banner ensure would win the `||` with the ND cover and
|
||||
// the existing fanart would never show).
|
||||
if args.external_artwork_enabled && !args.library_bulk && args.cache_kind == "artist" {
|
||||
if let Some(surface) = external_ensure::external_surface(args.surface_kind.as_deref()) {
|
||||
if let Some(path) = external_ensure::try_external_fanart(
|
||||
let external = external_ensure::try_external_fanart(
|
||||
app,
|
||||
args,
|
||||
&dir,
|
||||
@@ -317,14 +323,19 @@ impl CoverCacheState {
|
||||
args.tier,
|
||||
surface,
|
||||
)
|
||||
.await
|
||||
{
|
||||
return Ok(CoverCacheEnsureResult {
|
||||
.await;
|
||||
return Ok(match external {
|
||||
Some(path) => CoverCacheEnsureResult {
|
||||
hit: true,
|
||||
path: path.to_string_lossy().into_owned(),
|
||||
tier: args.tier,
|
||||
});
|
||||
}
|
||||
},
|
||||
None => CoverCacheEnsureResult {
|
||||
hit: false,
|
||||
path: String::new(),
|
||||
tier: args.tier,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user