Skip to content

feat(images): add larger TV image variants#336

Open
raiden202 wants to merge 2 commits into
Silo-Server:mainfrom
raiden202:pr/tv-image-variants
Open

feat(images): add larger TV image variants#336
raiden202 wants to merge 2 commits into
Silo-Server:mainfrom
raiden202:pr/tv-image-variants

Conversation

@raiden202

@raiden202 raiden202 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

feat(images): add larger TV image variants

Problem

Large TV detail surfaces can upscale the existing small still/logo variants, which is especially noticeable on 4K displays. Episode stills also reuse a smaller card thumbnail path where a TV-sized still variant is more appropriate.

Approach

Add larger generated variants for TV-sized still and logo surfaces, use a still-specific episode image variant where needed, and preserve fallback behavior for cached images whose larger variants have not been generated yet. Fallback presigned URLs are cached only for the short missing-variant window, so a refresh-generated larger object is picked up promptly. Focused tests cover variant selection, generated variant ladders, and S3 resolver fallback from new keys to older cached variants.

Verification

go test ./internal/api/handlers ./internal/catalog ./internal/imagecache ./internal/metadata
git diff --check

Risks & follow-up

Moderate risk. The change is additive and keeps existing small card surfaces on smaller variants, but operators should expect extra S3/storage and cache-warm bandwidth once images refresh: logos add w1280 alongside existing logo variants, and stills add w780 alongside existing still variants. Existing cached media can continue to fall back when larger variants are unavailable, and missing larger variants are filled only when refresh/upload runs.

AI-use disclosure

Implemented with a combination of Claude Code and Codex assistance, with human oversight.

Summary by CodeRabbit

  • New Features

    • Added improved image variant handling for episodes and logos, including larger episode still (w780) and logo (w1280) variants.
    • Introduced safer S3-based fallback URL generation for missing variants, with quicker refresh for fallback results.
  • Bug Fixes

    • Corrected episode image sizing for episode still, backdrop, and poster URLs, including proper variant clamping for “continue watching” and “featured” sections.
    • Updated cached image URL rewriting to consistently select supported variants and avoid unsupported combinations.
  • Tests

    • Added coverage for episode image variant suffixes and S3 fallback/presign caching behavior.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds w780 episode still variants, updates API path resolution and catalog clamping, expands cached image generation, and adds cached S3 existence checks with fallback presigning for missing new variants.

Changes

Episode still w780 variant support

Layer / File(s) Summary
Episode response still path resolution
internal/api/handlers/items.go, internal/api/handlers/episode_image_variant_test.go, internal/api/handlers/sections_test.go
Episode responses use w780 for episode-owned stills while fallback artwork retains card variants; tests cover the resulting suffixes.
Catalog variant clamping updates
internal/catalog/detail.go, internal/catalog/image_variants_test.go
Cached still requests clamp to w780, and logo requests now clamp to w1280, with corresponding test updates.
Image cache width generation
internal/imagecache/imagecache.go, internal/imagecache/imagecache_test.go
Still variants now include w780; logo variants include w1280 and w500, with updated cache assertions.
S3 presign fallback for missing new variants
internal/metadata/image_resolver.go, internal/metadata/image_resolver_test.go
S3 resolution checks and caches new variant existence, falls back to lower-size variants when missing, adjusts fallback expiry, and covers success, error, and cache reuse paths.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PluginImageResolver
  participant variantExistsCache
  participant S3Presigner

  PluginImageResolver->>variantExistsCache: check requested variant
  alt cache miss
    PluginImageResolver->>S3Presigner: ObjectExists(requested key)
    S3Presigner-->>PluginImageResolver: existence result
    PluginImageResolver->>variantExistsCache: cache result
  end
  alt variant missing
    PluginImageResolver->>S3Presigner: PresignGetURL(fallback key)
  else variant exists or check errors
    PluginImageResolver->>S3Presigner: PresignGetURL(requested key)
  end
  S3Presigner-->>PluginImageResolver: presigned URL
Loading

Possibly related PRs

Suggested labels: v1

Suggested reviewers: quick104, coffeeknyte

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding larger TV-focused image variants.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66f8ab4cc9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread internal/metadata/image_resolver.go Outdated
@raiden202
raiden202 force-pushed the pr/tv-image-variants branch from 66f8ab4 to c2f220a Compare July 8, 2026 18:03
@raiden202

Copy link
Copy Markdown
Contributor Author

Addressed the fallback caching review in c2f220a. Missing new-variant S3 fallbacks now cap their resolved-URL cache window to the same short missing-variant TTL, so refreshed w780/w1280 objects are picked up promptly instead of waiting on the full presign cache window. Added a regression test for the fallback URL cache TTL and reran the relevant Go package tests.

@raiden202
raiden202 force-pushed the pr/tv-image-variants branch from c2f220a to e0b6247 Compare July 9, 2026 13:47
@coderabbitai coderabbitai Bot added the v1 Silo v1 scope - auto-adds to the Silo v1 project label Jul 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/metadata/image_resolver_test.go (1)

379-424: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider covering the exists and ObjectExists error branches.

The tests validate the missing-variant fallback and its TTL well, but existingVariantKey has two untested branches: object-exists (presign w780 directly, cache true for 24h) and the optimistic error path (presign requested key, no caching). Adding cases via existing[...]=true and an ObjectExists error would lock in the no-fallback behavior and prevent regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/metadata/image_resolver_test.go` around lines 379 - 424, Add tests
in TestPluginImageResolverS3... to cover the remaining existingVariantKey
branches: one where fakeS3ImagePresigner reports ObjectExists true for the
requested w780 key so ResolveImageURLWithExpiry returns the direct w780 presign
and caches it with the existing-variant TTL, and another where ObjectExists
returns an error so the resolver still presigns the requested key but does not
cache the existence result. Use the existing PluginImageResolver,
SetS3Presigner, and fakeS3ImagePresigner helpers to assert both the returned URL
and the presigner call counts/keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/metadata/image_resolver_test.go`:
- Around line 379-424: Add tests in TestPluginImageResolverS3... to cover the
remaining existingVariantKey branches: one where fakeS3ImagePresigner reports
ObjectExists true for the requested w780 key so ResolveImageURLWithExpiry
returns the direct w780 presign and caches it with the existing-variant TTL, and
another where ObjectExists returns an error so the resolver still presigns the
requested key but does not cache the existence result. Use the existing
PluginImageResolver, SetS3Presigner, and fakeS3ImagePresigner helpers to assert
both the returned URL and the presigner call counts/keys.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2fa57f2c-1aa6-4b72-937a-861b0fb44ba5

📥 Commits

Reviewing files that changed from the base of the PR and between 581f39b and e0b6247.

📒 Files selected for processing (9)
  • internal/api/handlers/episode_image_variant_test.go
  • internal/api/handlers/items.go
  • internal/api/handlers/sections_test.go
  • internal/catalog/detail.go
  • internal/catalog/image_variants_test.go
  • internal/imagecache/imagecache.go
  • internal/imagecache/imagecache_test.go
  • internal/metadata/image_resolver.go
  • internal/metadata/image_resolver_test.go

@raiden202
raiden202 force-pushed the pr/tv-image-variants branch 2 times, most recently from db61955 to e019603 Compare July 9, 2026 19:01
@raiden202
raiden202 force-pushed the pr/tv-image-variants branch from e019603 to 0849a58 Compare July 10, 2026 16:52
Silo Contributor and others added 2 commits July 16, 2026 04:11
Add larger generated variants for TV-sized still and logo surfaces, while preserving existing fallbacks for cached images that have not yet been refreshed. Episode still responses use a still-specific variant path instead of the small card thumbnail path.
@raiden202
raiden202 force-pushed the pr/tv-image-variants branch from 0849a58 to cdc62dd Compare July 16, 2026 08:23

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/catalog/detail.go (1)

3691-3701: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove redundant poster case.

The poster case is identical in behavior to the default case. It can be removed to simplify the switch statement.

♻️ Proposed refactor
-	case "poster":
-		if size == "small" {
-			return "w300"
-		}
-		return "w500"
 	default:
 		if size == "small" {
 			return "w300"
 		}
 		return "w500"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/catalog/detail.go` around lines 3691 - 3701, Remove the redundant
"poster" branch from the switch, leaving the existing default branch to handle
it and preserve the current size-to-dimension behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/catalog/detail.go`:
- Around line 3691-3701: Remove the redundant "poster" branch from the switch,
leaving the existing default branch to handle it and preserve the current
size-to-dimension behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a83db50a-bbaf-459d-871d-66026cc6ebb3

📥 Commits

Reviewing files that changed from the base of the PR and between db61955 and cdc62dd.

📒 Files selected for processing (5)
  • internal/api/handlers/episode_image_variant_test.go
  • internal/api/handlers/items.go
  • internal/api/handlers/sections_test.go
  • internal/catalog/detail.go
  • internal/catalog/image_variants_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/api/handlers/episode_image_variant_test.go
  • internal/catalog/image_variants_test.go
  • internal/api/handlers/sections_test.go
  • internal/api/handlers/items.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v1 Silo v1 scope - auto-adds to the Silo v1 project

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant