Skip to content

Transparent caching with pull-to-refresh#115

Closed
docmeth02 wants to merge 6 commits intokepelet:developfrom
docmeth02:feat/stream-cache
Closed

Transparent caching with pull-to-refresh#115
docmeth02 wants to merge 6 commits intokepelet:developfrom
docmeth02:feat/stream-cache

Conversation

@docmeth02
Copy link
Copy Markdown
Contributor

This is just a proposal, i am working on a standalone watchOs app based on flo, implementing this cache is necessary on watchOs to save on battery and cellular data. I felt like it could also benefit the other platforms?

PR adds optional (defaults to off for now) transparent pre caching that silently prefetches the next song to disk for instant play/replay on subsequent plays — similar to Spotify's caching behavior.

Cached files are stored in Library/Caches/StreamCache/ (separate from explicit downloads) with LRU eviction when the user-defined cache limit is reached (default 1 GB).

Key Changes

Playback pipeline (AlbumService.swift, PlayerViewModel.swift):

  • getStreamUrl() now resolves in 3 tiers: explicit download → stream cache → remote URL
  • After 10 seconds of confirmed playback, a silent background download is triggered for the next queued song
  • On song skip, in-flight cache downloads are cancelled
  • Live radio and locally-stored tracks are excluded from caching

Storage (StreamCacheManager.swift, CacheEntity):

  • New StreamCacheManager singleton manages the full cache lifecycle: download, lookup, eviction, cleanup
  • New CacheEntity CoreData entity tracks cached files with LRU metadata (lastAccessedAt)
  • Cache uses Library/Caches/ directory — iOS can purge under storage pressure, reconcile() on app startup handles orphans
  • Cache key includes bitrate setting so quality changes don't serve wrong files

Settings (PreferencesView.swift):

  • Cache size display, configurable limit (Off / 500 MB / 1 GB / 2 GB / 5 GB), and "Clear streaming cache" button to release storage
image

@docmeth02
Copy link
Copy Markdown
Contributor Author

added "Cached" playlist to downloads view so the user can still listen to the cached files in case they are offline
image
image

@faultables
Copy link
Copy Markdown
Member

related #43

@faultables faultables mentioned this pull request Mar 20, 2026
faultables and others added 6 commits March 24, 2026 17:58
…t images so lists and artwork load instantly from disk while refreshing from the network in the background. Includes pull-to-refresh on Library, Artists, Songs, and Playlists views.
@docmeth02 docmeth02 changed the title Feat/stream cache feat: transparent caching layers with pull-to-refresh Mar 24, 2026
@docmeth02
Copy link
Copy Markdown
Contributor Author

Update: Rebased onto develop and expanded scope beyond stream caching. Since the original PR, I've been building out additional caching layers for the standalone watchOS
app and felt they would benefit the main app as well.

What's new in this update:

Library cache (LibraryCacheManager.swift):

  • Albums, artists, playlists, and songs are cached as JSON files in Library/Caches/LibraryCache/
  • Views load instantly from cache on launch while refreshing from the network in the background
  • Generic fetchCached/refreshCached helpers in AlbumViewModel replace all duplicated fetch logic

Cover art cache (CoverArtCacheManager.swift):

  • Album artwork is cached to disk in Library/Caches/CoverArtCache/ keyed by album ID
  • AlbumService.getAlbumCover() checks the disk cache before falling back to remote URL
  • Immune to auth token rotation since it's keyed by stable album ID, not the full URL

Pull-to-refresh:

  • Library, Artists, Songs, and Playlists views now support native pull-to-refresh via .refreshable
  • Refreshes the network data and updates the cache

Other:

  • Renamed CachedSongsPlayable → generic SongCollection with parameterized id and name
  • Guarded CacheEntity init with #if os(iOS) for watch target compatibility

All original stream caching functionality from the initial PR is unchanged.

@docmeth02 docmeth02 marked this pull request as ready for review March 24, 2026 17:53
@docmeth02 docmeth02 changed the title feat: transparent caching layers with pull-to-refresh Transparent caching with pull-to-refresh Mar 24, 2026
faultables added a commit that referenced this pull request Apr 11, 2026
Co-authored-by: faultables <faultables@users.noreply.github.com>
docmeth02 added a commit to docmeth02/flo that referenced this pull request Apr 12, 2026
Shows stream-cached songs as a browsable playlist in the Downloads
tab with Play All, Shuffle, and individual track playback. Follow-up to kepelet#115.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
faultables pushed a commit that referenced this pull request Apr 21, 2026
Shows stream-cached songs as a browsable playlist in the Downloads
tab with Play All, Shuffle, and individual track playback. Follow-up to #115.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@faultables
Copy link
Copy Markdown
Member

closing this PR since the commit has already been cherry-picked into #127

@faultables faultables closed this Apr 26, 2026
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.

2 participants