mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 07:29:14 +01:00
feat: auto-sync the library on a timer while the app is open
While the app is in the foreground a timer checks the auto-sync setting and syncs when due (default every 24h; the interval is selectable from 15 minutes to 24 hours). It stops when the app is backgrounded. "Sync automatically" is one setting: Off, Wi-Fi only (default) or Always. A running sync is shown by a silent, dismissible notification and a small spinner on the library tab bar's settings button. A manual pull-to-refresh still holds the pull spinner; only an automatic sync does not. The library and Home sync actions no-op while a sync is running, and SyncManager coalesces a request that arrives mid-run into a single follow-up, so repeated pull-to-refresh cannot pile up runs while adding a server still syncs it. The time of the last sync attempt is recorded, so a failing server is retried once per interval rather than every poll. The sync consumer and the auto-sync loop both survive an unexpected failure instead of silently disabling syncing for the rest of the process. The poll sleeps for the interval (capped at 15 minutes) instead of a fixed minute, the network mode is collected once rather than re-registering a connectivity callback each poll, and the decision is logged at DEBUG (visible with Verbose logging) rather than writing to the log file every poll.
This commit is contained in:
@@ -48,6 +48,7 @@ Everything comes from the Nix flake devshell; do not install toolchains by hand.
|
||||
- Networking uses OkHttp and DOM XML parsing; auth uses the Subsonic token scheme by default.
|
||||
- Use coroutines and `Flow`; library reads are exposed as `Flow` from Room. Large lists page with Paging 3 over Room `PagingSource` rather than loading the whole table.
|
||||
- The library is mirrored in full at sync and must work offline. Never fetch library metadata on demand for browsing, filtering or sorting; only media bytes (streams, downloads) and images are on-demand. A server-derived sort key must be synced into a local column, not requested lazily when the sort is selected.
|
||||
- Auto-sync is a foreground-only, in-process timer (`AutoSync`, driven by the Activity lifecycle), not a background worker: do not move it to WorkManager or an alarm. `SyncManager` coalesces a request that arrives while a sync is running into a single follow-up; the library and Home sync actions no-op while one is running.
|
||||
- Playback is Media3: `PlaybackService` is a `MediaSessionService` owning an `ExoPlayer`, and `PlaybackController` (app-scoped Koin singleton) is the only thing the UI talks to. The queue is a `queue_entries` list of references with optional ranges plus a `playback_cursor` row; keep only a bounded window in memory (never the whole queue, and never load a whole table to build one). Stream URLs are freshly salted per request, so attach artwork by `CoverArtRef` cache key, not by URL.
|
||||
- UI state lives in `androidx.lifecycle.ViewModel`, wired with Koin (`koinViewModel()`); screens split into a stateful `*Route` and a stateless `*Screen` for screenshot tests.
|
||||
- UI and playback preferences go in DataStore (`UserPreferences`), not Room.
|
||||
|
||||
Reference in New Issue
Block a user