New
- Inline Reauth on Session Expiry — When your session expires mid-use, a reauth sheet now slides up over your current screen so you can sign back in without losing your place. No more getting bounced back to the login screen and forgetting where you were
- Sign Out and Export Logs on the Library Selection Screen — A new menu in the top-right of the library selection screen exposes Sign Out and Export Diagnostic Logs, so you can recover even when you've signed in but library load is failing
- Re-Download Flow for Corrupted Files — When iOS's AVFoundation reports a playback error on a downloaded file, FableFrog flags the file as corrupted, shows a persistent banner with a one-tap Re-download button, and falls back to streaming so you can keep listening in the meantime
Improved
- Persistent Reauth Banner — When the server has rejected your current session, a reauth banner stays visible across screens until you sign back in, gated behind a new
serverAvailableenvironment value so views can adapt their UI when the server is offline or rejecting requests - Per-Server Session State — Auth state and server reachability are now tracked per-server via a new
ServerSessionStateactor, so signing into one server doesn't muddle scheduling, caches, or sync state for another - Reachability Short-Circuit — Outbound auth and refresh calls fail fast when the network is offline, instead of spinning a request that's guaranteed to time out
- Offline-Aware Cover Cache — While offline, the cover cache stops trying to refresh and serves what it already has on disk, so browsing stays smooth and there are no retry storms eating battery
- Queued Progress Replays on Reconnect — Listening progress that piled up locally while your session was rejected now replays to the server automatically once you reconnect and sign back in, instead of being silently dropped
- Lazy Pure Refresh — The auth token refresh path is now pure-lazy and reachability-gated, which makes the refresh story noticeably less prone to wedging during background wakes
Fixed
- Library Browse
UserDefaultsWiring —LibraryBrowseViewModelnow takes itsUserDefaultsthrough dependency injection, fixing a subtle ordering issue where browse state could read stale defaults during cold start