Commit Graph
18 Commits
Author SHA1 Message Date
austinried 7d04125f58 add the Downloaded filter to the library tabs
One toggle per tab, persisted with the rest of the list query, narrowing to
entities that have at least one completed download. It rides the existing filter
SQL: every album, artist and playlist paging query takes a flag and the shared
filter constant adds an EXISTS over song_downloads, so it composes with the
sort, search and starred filter rather than being a separate mode.

The filters sheet now renders on every tab, since playlists support Downloaded
but not Starred.
2026-10-04 00:30:03 +00:00
austinried 5ade5073f8 address review: test the source wiring, one default, clamp the stored value
- Add a `SourceRepositoryTest` that sets the preference to 1 and proves the
  active source fetches sequentially; removing the `maxConcurrentFetches`
  wiring now fails it.
- `playlistSongsRespectsASmallerFetchBound` now holds the first `bound`
  fetches and asserts no `(bound + 1)`th starts, instead of timing an
  overlap; it fails when the semaphore ignores the bound.
- One `DEFAULT_FETCH_CONCURRENCY` (in `data.source`) backs both the source
  default and the preference default, so they cannot drift.
- Clamp the stored preference in `syncConcurrency()` too, so a bad stored
  value can't make `SubsonicSource` throw on construction.
2026-10-04 00:30:02 +00:00
austinried a4149690e5 wire the sync fetch concurrency to a Settings option
The bound was only a constructor default with no production consumer. Add a
"Sync concurrency" preference (Settings -> Network, default 4) and pass it
through SourceRepository to SubsonicSource, so sync parallelism is tunable
without a rebuild. Both the app-scoped source and the on-demand
`activeMusicSource()` used by sync read the preference.

- UserPreferences.syncConcurrency()/setSyncConcurrency() (clamped >= 1)
- SourceRepository combines the preference into toMusicSource
- Settings row + dialog; SettingsViewModel state and setter
- Preferences test for default/round-trip/clamp
2026-10-04 00:30:02 +00:00
austinried ea09f24844 skip the startup reveal animation and seed the first colour
The mini player and tab bar no longer expand or animate their inset when playback is
restored at launch, and the first artwork colour lands without a 600ms fade from the
base scheme. The last active artwork seed is persisted and read back synchronously so
the mini player can paint with it on its first frame.
2026-10-04 00:30:00 +00:00
austinried d21b646858 drop the legacy stream-quality fallback
No need to migrate the old max_bitrate/stream_format keys.
2026-10-04 00:30:00 +00:00
austinried ebaa486126 clip transcoded tracks to their real duration
The declared upper-bound length stopped the stall where Media3 saw no seek map duration, but it also made the track look longer than the audio: the player reached the last sample still short of the declared end and waited for data that never came, so it never advanced. Clip each transcoded item to the library duration, which Media3 applies through ClippingMediaSource, so the timeline ends where the audio ends and the next track advances. The declared length still makes the stream on-demand (seekable) and never bounds reads below the real size.
2026-10-04 00:30:00 +00:00
austinried 95216143dc polish stream quality settings
- label the rows 'Stream quality: Wi-Fi' / 'Stream quality: Mobile'
- default mobile to 192kbps/mp3 while Wi-Fi stays unlimited/server default
- apply the selection only when Done is pressed, cancelling discards the draft
- fade the bottom of the dialog list so the remaining options are visible as scrollable
2026-10-04 00:29:59 +00:00
austinried 9e25a971e6 address network quality review findings
- fall back to the legacy max_bitrate/stream_format keys so existing settings survive the upgrade
- keep the last network mode when there is no active network instead of reporting mobile, so a connectivity gap does not flip modes and cause spurious reloads
- skip the quality reload when the player has ended or advanced mid-read
- keep the reload collector alive across transient failures
- edit stream quality from a local dialog draft so a fast second tap is not lost
- cover the mode mapping, migration, paused reload and equal-quality no-op with tests
2026-10-04 00:29:59 +00:00
austinried 117e8a69fb add network-dependent stream quality
Combine max bitrate and transcode format into one StreamQuality and store a separate value per network mode (Wi-Fi vs mobile data). NetworkMonitor reports metered vs unmetered via ConnectivityManager, SourceRepository selects and exposes the active quality, and PlaybackController reloads the window at the current position when it changes, so a network switch re-issues stream URLs with the new settings. Reset Coil's singleton in SubtracksApp.onCreate alongside Koin, since ArtworkSeedCache's background scope can call get() across Robolectric tests and poison the next Application.
2026-10-04 00:29:59 +00:00
austinried e3af5ed0ac drop the songs tab and the whole-library song queue 2026-10-04 00:29:59 +00:00
austinried bf3afb9c17 drop the speculative legacy album sort migration 2026-10-04 00:29:56 +00:00
austinried f5948812bb address review round 3: keep the search bar across recomposition, fix tab landing, page the queried songs queue 2026-10-04 00:29:56 +00:00
austinried e99ed1dc45 song added sort, robust scroll reset, restyled search and filter controls 2026-10-04 00:29:55 +00:00
austinried 63f0549181 tristate starred filter, filter-aware empty state, keyboard-safe search bar 2026-10-04 00:29:55 +00:00
austinried a2d42f7957 rework the library lists: inline filter, playlist updated, starred sort, clearer controls 2026-10-04 00:29:55 +00:00
austinried 9a99977342 add sort, filters and search to the library 2026-10-04 00:29:55 +00:00
austinried 659df47c14 choose the stream bitrate and format from settings 2026-10-04 00:29:51 +00:00
austinried 3f91a29850 add preferences, paging reads, repositories and sync status 2026-10-04 00:29:51 +00:00