Let SliderPreference collect its own preference

Closes #3958

Assisted-by: Claude:claude-opus-5-5
This commit is contained in:
AntsyLich
2026-10-02 10:23:07 +06:00
parent 38e93086c8
commit 9409740d7e
4 changed files with 22 additions and 37 deletions
@@ -49,15 +49,15 @@ sealed class Preference {
* A [PreferenceItem] that provides a slider to select an integer number.
*/
data class SliderPreference(
val value: Int,
val preference: PreferenceData<Int>,
override val title: String,
override val subtitle: String? = null,
val valueString: String? = null,
val valueText: @Composable (Int) -> String = { it.toString() },
val valueRange: IntProgression = 0..1,
@IntRange(from = 0) val steps: Int = with(valueRange) { (last - first) - 1 },
@IntRange(from = 0) val steps: Int = with(valueRange) { ((last - first) / step) - 1 },
override val enabled: Boolean = true,
override val onValueChanged: suspend (value: Int) -> Unit = {},
) : PreferenceItem<Int, Unit>() {
override val onValueChanged: suspend (value: Int) -> Boolean = { true },
) : PreferenceItem<Int, Boolean>() {
override val icon: ImageVector? = null
}
@@ -88,16 +88,19 @@ internal fun PreferenceItem(
)
}
is Preference.PreferenceItem.SliderPreference -> {
val value by item.preference.collectAsState()
BaseSliderItem(
value = item.value,
value = value,
valueRange = item.valueRange,
steps = item.steps,
title = item.title,
subtitle = item.subtitle,
valueString = item.valueString.takeUnless { it.isNullOrEmpty() } ?: item.value.toString(),
onChange = {
valueString = item.valueText(value),
onChange = { newValue ->
scope.launch {
item.onValueChanged(it)
if (item.onValueChanged(newValue)) {
item.preference.set(newValue)
}
}
},
titleStyle = MaterialTheme.typography.titleLarge.copy(fontSize = TitleFontSize),
@@ -34,8 +34,6 @@ object SettingsDownloadScreen : SearchableSettings {
val allCategories by getCategories.subscribe().collectAsState(initial = emptyList())
val downloadPreferences = remember { context.appGraph.downloadPreferences }
val parallelSourceLimit by downloadPreferences.parallelSourceLimit.collectAsState()
val parallelPageLimit by downloadPreferences.parallelPageLimit.collectAsState()
return listOf(
Preference.PreferenceItem.SwitchPreference(
preference = downloadPreferences.downloadOnlyOverWifi,
@@ -51,17 +49,15 @@ object SettingsDownloadScreen : SearchableSettings {
subtitle = stringResource(MR.strings.split_tall_images_summary),
),
Preference.PreferenceItem.SliderPreference(
value = parallelSourceLimit,
preference = downloadPreferences.parallelSourceLimit,
valueRange = 1..10,
title = stringResource(MR.strings.pref_download_concurrent_sources),
onValueChanged = { downloadPreferences.parallelSourceLimit.set(it) },
),
Preference.PreferenceItem.SliderPreference(
value = parallelPageLimit,
preference = downloadPreferences.parallelPageLimit,
valueRange = 1..15,
title = stringResource(MR.strings.pref_download_concurrent_pages),
subtitle = stringResource(MR.strings.pref_download_concurrent_pages_summary),
onValueChanged = { downloadPreferences.parallelPageLimit.set(it) },
),
getDeleteChaptersGroup(
downloadPreferences = downloadPreferences,
@@ -116,12 +116,6 @@ object SettingsReaderScreen : SearchableSettings {
private fun getEInkGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
val flashPageState by readerPreferences.flashOnPageChange.collectAsState()
val flashMillisPref = readerPreferences.flashDurationMillis
val flashMillis by flashMillisPref.collectAsState()
val flashIntervalPref = readerPreferences.flashPageInterval
val flashInterval by flashIntervalPref.collectAsState()
val flashColorPref = readerPreferences.flashColor
return Preference.PreferenceGroup(
@@ -133,20 +127,18 @@ object SettingsReaderScreen : SearchableSettings {
subtitle = stringResource(MR.strings.pref_flash_page_summ),
),
Preference.PreferenceItem.SliderPreference(
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
valueRange = 1..15,
preference = readerPreferences.flashDurationMillis,
valueRange = ReaderPreferences.MILLI_CONVERSION.let { it..it * 15 step it },
title = stringResource(MR.strings.pref_flash_duration),
valueString = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
valueText = { stringResource(MR.strings.pref_flash_duration_summary, it) },
enabled = flashPageState,
onValueChanged = { flashMillisPref.set(it * ReaderPreferences.MILLI_CONVERSION) },
),
Preference.PreferenceItem.SliderPreference(
value = flashInterval,
preference = readerPreferences.flashPageInterval,
valueRange = 1..10,
title = stringResource(MR.strings.pref_flash_page_interval),
valueString = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
valueText = { pluralStringResource(MR.plurals.pref_pages, it, it) },
enabled = flashPageState,
onValueChanged = { flashIntervalPref.set(it) },
),
Preference.PreferenceItem.ListPreference(
preference = flashColorPref,
@@ -288,12 +280,10 @@ object SettingsReaderScreen : SearchableSettings {
val navModePref = readerPreferences.navigationModeWebtoon
val dualPageSplitPref = readerPreferences.dualPageSplitWebtoon
val rotateToFitPref = readerPreferences.dualPageRotateToFitWebtoon
val webtoonSidePaddingPref = readerPreferences.webtoonSidePadding
val navMode by navModePref.collectAsState()
val dualPageSplit by dualPageSplitPref.collectAsState()
val rotateToFit by rotateToFitPref.collectAsState()
val webtoonSidePadding by webtoonSidePaddingPref.collectAsState()
return Preference.PreferenceGroup(
title = stringResource(MR.strings.webtoon_viewer),
@@ -318,13 +308,12 @@ object SettingsReaderScreen : SearchableSettings {
enabled = navMode != 5,
),
Preference.PreferenceItem.SliderPreference(
value = webtoonSidePadding,
preference = readerPreferences.webtoonSidePadding,
valueRange = ReaderPreferences.let {
it.WEBTOON_PADDING_MIN..it.WEBTOON_PADDING_MAX
},
title = stringResource(MR.strings.pref_webtoon_side_padding),
valueString = numberFormat.format(webtoonSidePadding / 100f),
onValueChanged = { webtoonSidePaddingPref.set(it) },
valueText = { numberFormat.format(it / 100f) },
),
Preference.PreferenceItem.ListPreference(
preference = readerPreferences.readerHideThreshold,
@@ -385,8 +374,6 @@ object SettingsReaderScreen : SearchableSettings {
val readWithVolumeKeys by readWithVolumeKeysPref.collectAsState()
val verticalNavigator by readerPreferences.verticalNavigator.collectAsState()
val verticalNavigatorHeightPref = readerPreferences.verticalNavigatorHeight
val verticalNavigatorHeight by verticalNavigatorHeightPref.collectAsState()
return Preference.PreferenceGroup(
title = stringResource(MR.strings.pref_reader_navigation),
@@ -412,11 +399,10 @@ object SettingsReaderScreen : SearchableSettings {
enabled = verticalNavigator.isNotEmpty(),
),
Preference.PreferenceItem.SliderPreference(
value = verticalNavigatorHeight,
preference = readerPreferences.verticalNavigatorHeight,
valueRange = 65..100,
steps = 6,
title = stringResource(MR.strings.pref_vertical_navigator_height),
onValueChanged = { verticalNavigatorHeightPref.set(it) },
enabled = verticalNavigator.isNotEmpty(),
),
),