github superuser404notfound/Sodalite v0.3.2-beta
v0.3.2 — Filter caching that actually caches

latest releases: 1.0.0, 0.13.0, 0.12.0...
pre-release6 months ago

Filter caching, end to end

The first tap on a genre, streaming provider or studio tile now lands instantly. The previous build was supposed to cache results to UserDefaults but tvOS' 1 MB CFPreferences cap was crashing the app the moment the cache filled up. The whole pipeline got rebuilt around file-based persistence with stale-while-revalidate, plus background pre-warming so the cache is already populated by the time you reach for it.

Stability

  • No more SIGABRT on filter loads. Moved FilterCache from UserDefaults to file-based JSON in Library/Caches/FilterCache/. UserDefaults' 1 MB cap couldn't hold a fully-populated provider tile and was crashing the entire app on the first big write.
  • Catalog empty-grid quit fix. Tapping a streaming-service tile that resolved to zero results dropped the user into a grid with no focusable elements, and pressing Menu on the Siri Remote escaped the navigation stack and quit the app instead of popping back. Empty / error / loading states now have proper focusable Back buttons.

Cache + performance

  • Cache hydrates from init(), not .task. Filter grids now paint their cached items in the very first render frame instead of flashing the loading spinner for one tick.
  • Bottom-spinner flicker on revalidation gone. Background refresh runs silently behind the cached grid; only real pagination shows the loading hint.
  • Wholesale-replace flicker gone. When a refresh returns the same id list as the cache, the items aren't reassigned, so SwiftUI doesn't re-diff every cell.
  • Home-page genre tiles now cache. They were missing a cacheKey and re-fetched from scratch on every tap.
  • Pre-warm on home + catalog load. The genre and streaming-provider grids are populated in the background as soon as the home / catalog screen mounts, so the first tap renders straight from disk.

Streaming providers

  • Reordered into popularity tiers. Top globals first (Netflix, Prime, Disney+, HBO, Apple TV+), then second-tier SVOD, international, niche, premium cable, free AVOD, broadcast, kids/animation. Same list feeds the home row and catalog row.
  • Empty tiles auto-hide. TMDB watch-provider data is region-specific, so Hulu / Peacock outside US, Hotstar outside India etc. now drop out of the row on the first catalog render instead of teasing a tile that opens to nothing.
  • Crunchyroll added. Anime catalogue support.
  • Nine international providers added. MUBI (global arthouse), Sky (DACH + UK), Viaplay (Nordic), BBC iPlayer (UK), Canal+ (France), Hotstar (India), U-NEXT (Japan), Tubi + Pluto TV (free AVOD).
  • Real TMDB logo paths. The 10 newly-added providers shipped with hallucinated logo paths in 0.3.1 — every single one returned 404 from image.tmdb.org and the tiles fell back to a plain text-name placeholder. All replaced with verified paths.

Refactor

  • One source of truth for filter cache keys — every key format moved to FilterCacheKey.
  • Centralised focus-defer pattern as deferOnMain(by:_:) — the project's documented workaround for the @focusstate commit race finally has a name.
  • HomeViewModel precompute task lifecycle — handles are held now and cancelled on re-entry, so a rapid profile switch can't stack two fan-outs writing into the same cache.
  • Watch-provider ID resolver lives once on SeerrDiscoverServiceProtocol instead of once each in FilteredGridView and HomeViewModel.

Don't miss a new Sodalite release

NewReleases is sending notifications on new releases.