Skip to content

Persistent thumbnail color cache with ListRow pattern#245

Merged
chrisballinger merged 1 commit intomasterfrom
liquid-glass
Apr 12, 2026
Merged

Persistent thumbnail color cache with ListRow pattern#245
chrisballinger merged 1 commit intomasterfrom
liquid-glass

Conversation

@chrisballinger
Copy link
Copy Markdown
Member

Summary

  • Single-query list fetching: Replaces dual observations (items + favorites) with a single GRDB read transaction returning ListRow<T> that bundles the object + full ObjectMetadata + cached ThumbnailColors
  • Persistent color cache: New thumbnail_colors GRDB table stores extracted thumbnail colors across app restarts — no more re-extracting from images on every launch
  • Selective list row theming: Only Art and Mutant Vehicle rows use thumbnail-derived colors; Camp and Event rows use the default theme. Detail views use colors for all types.
  • Pre-loaded detail views: DetailPageItem threads metadata + colors from list → detail, so detail views render instantly with no async flicker

New files

File Description
ThumbnailColors.swift Codable GRDB model (16 RGBA doubles)
ListRow.swift Generic ListRow<T> — object + metadata + colors
ColorPrefetcher.swift Background batch color extraction at launch
ThumbnailColors+UIKit.swift Conversion helpers (↔ UIColor, ImageColors, BRCImageColors)
DetailPageItem Pairs DetailSubject with pre-loaded metadata + colors

Architecture changes

  • PlayaDB observation methods return [ListRow<T>] instead of [T]
  • ObjectListViewModel stores [ListRow<Object>], eliminates separate favorites observation
  • ObjectRowView accepts thumbnailColors param, gates on DisplayableObject.supportsColorTheming
  • Thumbnail downloaders return awaitable Task<Set<String>, Never> with corrupt file validation
  • DependencyContainer sequences: downloads → ColorPrefetcher.prefetchMissingColors()

Test plan

  • Scroll Art list — rows show thumbnail-derived colors
  • Scroll MV list — rows show thumbnail-derived colors
  • Scroll Camp/Event lists — rows use default/plain theme (no image colors)
  • Tap Art from list → detail view shows colors immediately (no flicker)
  • Tap Camp from map → detail view still loads colors from DB cache
  • Toggle favorite in list → instant optimistic update, persists correctly
  • Kill + restart app → Art/MV list colors appear immediately from DB
  • Swipe between detail pages → each shows correct colors + metadata

🤖 Generated with Claude Code

Replaces the dual-observation list architecture (items + separate favorites)
with a single GRDB read transaction that returns ListRow<T> containing the
object, full ObjectMetadata, and cached ThumbnailColors. This eliminates
redundant queries and provides instant color/metadata rendering.

Key changes:
- New thumbnail_colors GRDB table with Codable ThumbnailColors model
- New ListRow<T> generic wrapper (object + metadata + colors)
- Single annotated observation replaces dual items+favorites observations
- DisplayableObject.supportsColorTheming gates list row colors (Art/MV only)
- Detail views receive pre-loaded data via DetailPageItem pass-through
- ColorPrefetcher background batch extraction at app launch
- Thumbnail downloaders validate corrupt files and return awaitable Tasks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@chrisballinger chrisballinger merged commit 87bc08d into master Apr 12, 2026
0 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant