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
This commit is contained in:
austinried
2026-10-04 00:30:02 +00:00
parent adcdc442e4
commit a4149690e5
7 changed files with 116 additions and 14 deletions
@@ -58,6 +58,24 @@ class UserPreferencesTest {
file.delete()
}
@Test
fun syncConcurrencyDefaultsAndClampsToAtLeastOne() =
runTest {
val file = File.createTempFile("user-prefs", ".preferences_pb").apply { delete() }
val store = PreferenceDataStoreFactory.create(scope = backgroundScope) { file }
val prefs = UserPreferences(store)
assertEquals(DEFAULT_SYNC_CONCURRENCY, prefs.syncConcurrency().first())
prefs.setSyncConcurrency(8)
assertEquals(8, prefs.syncConcurrency().first())
prefs.setSyncConcurrency(0)
assertEquals(1, prefs.syncConcurrency().first())
file.delete()
}
@Test
fun lastSeedRoundTripsWithAndWithoutASecondary() =
runTest {
@@ -306,10 +306,12 @@ class AppScreenshotTest {
activeSourceId = 1,
wifiQuality = StreamQuality(),
mobileQuality = StreamQuality(192, "mp3"),
syncConcurrency = 4,
onSelectSource = {},
onDeleteSource = {},
onWifiQualityChange = {},
onMobileQualityChange = {},
onSyncConcurrencyChange = {},
onAddServer = {},
onBack = {},
)