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
This commit is contained in:
austinried
2026-10-04 00:29:59 +00:00
parent 117e8a69fb
commit 9e25a971e6
9 changed files with 209 additions and 62 deletions
@@ -4,6 +4,7 @@ import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.subtracks.data.net.NetworkMode
@@ -54,7 +55,9 @@ class UserPreferences(
}
fun streamQuality(mode: NetworkMode): Flow<StreamQuality> =
store.data.map { prefs -> decodeStreamQuality(prefs[streamQualityKey(mode)]) }
store.data.map { prefs ->
prefs[streamQualityKey(mode)]?.let(::decodeStreamQuality) ?: legacyStreamQuality(prefs)
}
suspend fun setStreamQuality(
mode: NetworkMode,
@@ -71,14 +74,20 @@ class UserPreferences(
private fun encode(quality: StreamQuality) = "${quality.maxBitrate}|${quality.format.orEmpty()}"
private fun decodeStreamQuality(stored: String?): StreamQuality {
val parts = stored?.split("|") ?: return StreamQuality()
private fun decodeStreamQuality(stored: String): StreamQuality {
val parts = stored.split("|")
return StreamQuality(
maxBitrate = parts.getOrNull(0)?.toIntOrNull() ?: 0,
format = parts.getOrNull(1)?.takeIf { it.isNotEmpty() },
)
}
private fun legacyStreamQuality(prefs: Preferences): StreamQuality =
StreamQuality(
maxBitrate = prefs[LEGACY_BITRATE] ?: 0,
format = prefs[LEGACY_FORMAT]?.takeIf { it.isNotEmpty() },
)
private fun decode(
stored: String?,
defaultSort: String,
@@ -91,6 +100,11 @@ class UserPreferences(
starred = StarredFilter.entries.getOrElse(parts[2].toIntOrNull() ?: 0) { StarredFilter.Any },
)
}
private companion object {
val LEGACY_BITRATE = intPreferencesKey("max_bitrate")
val LEGACY_FORMAT = stringPreferencesKey("stream_format")
}
}
fun createUserPreferences(context: Context): UserPreferences = UserPreferences(context.preferences)