Real-image posters of library titles: use the 500 px copy

Library titles fetched Radarr's/Sonarr's 250×375 poster copy, which
real images show at up to 640 pixels, so movie posters looked soft next
to series posters that came from the provider's full-size original
(Sonarr behind a login). With real images the 500×750 copy is used;
block-character posters keep the small one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019reK4DUGYqDUjniWYJvwUW
This commit is contained in:
2026-10-21 15:31:56 +02:00
co-authored by Claude Opus 5.5
parent b259e22458
commit 2798977867
7 changed files with 71 additions and 35 deletions
+3 -2
View File
@@ -468,7 +468,7 @@ func (c *coverView) build(cols, rows int) []styledCell {
// coverRef says where a poster comes from. The zero value means "no poster".
type coverRef struct {
key string // identifies the poster in the cache
fetch func(ctx context.Context) ([]byte, error)
fetch func(ctx context.Context, large bool) ([]byte, error) // large: for real images
}
// coverFor builds the poster reference of a title from its image list.
@@ -516,6 +516,7 @@ func (a *App) loadCover(ref coverRef, done func(*image.RGBA, error)) {
}
c.waiting[ref.key] = []func(*image.RGBA, error){done}
maxHeight := a.coverMaxHeight()
large := a.gfx != nil // real images show the poster at full resolution
go func() {
c.slots <- struct{}{}
@@ -523,7 +524,7 @@ func (a *App) loadCover(ref coverRef, done func(*image.RGBA, error)) {
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
defer cancel()
var img *image.RGBA
data, err := ref.fetch(ctx)
data, err := ref.fetch(ctx, large)
if err == nil {
img, err = decodeCover(data, maxHeight)
}
+2 -2
View File
@@ -165,7 +165,7 @@ func TestLoadCoverCachesAndDedupes(t *testing.T) {
var fetches atomic.Int32
var buf bytes.Buffer
png.Encode(&buf, stripes(10, 20))
ref := coverRef{key: "k", fetch: func(context.Context) ([]byte, error) {
ref := coverRef{key: "k", fetch: func(context.Context, bool) ([]byte, error) {
fetches.Add(1)
return buf.Bytes(), nil
}}
@@ -186,7 +186,7 @@ func TestLoadCoverRemembersFailures(t *testing.T) {
a := newTestApp(t)
a.coverCache.failed["bad"] = time.Now()
var gotErr error
a.loadCover(coverRef{key: "bad", fetch: func(context.Context) ([]byte, error) {
a.loadCover(coverRef{key: "bad", fetch: func(context.Context, bool) ([]byte, error) {
t.Error("a recent failure must not be retried")
return nil, nil
}}, func(_ *image.RGBA, err error) { gotErr = err })
+1 -1
View File
@@ -116,7 +116,7 @@ func TestPosterWaitsWhileTheSelectionMoves(t *testing.T) {
img := image.NewRGBA(image.Rect(0, 0, 20, 30))
a.coverCache.imgs["one"], a.coverCache.imgs["two"] = img, img
ref := func(key string) coverRef {
return coverRef{key: key, fetch: func(context.Context) ([]byte, error) { return nil, nil }}
return coverRef{key: key, fetch: func(context.Context, bool) ([]byte, error) { return nil, nil }}
}
d := newDetailPane(a)