Skip to content

Commit b22a8ac

Browse files
AntsyLichcuong-tran
authored andcommitted
Make more sliders discrete and ensure they don't look out of place (mihonapp/mihon#1840)
Also cleanup the underlying code (cherry picked from commit 4f06c1cc09d15245b26b8a862738cb6a859fedcc)
1 parent 2c25f0c commit b22a8ac

File tree

12 files changed

+103
-66
lines changed

12 files changed

+103
-66
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
1313
## [Unreleased]
1414
### Added
1515
- Add option to always decode long strip images with SSIV
16-
- Change option label ([@AntsyLich](https://github.com/AntsyLich)) ([#1835](https://github.com/mihonapp/mihon/pull/1835))
16+
- Change option label ([@AntsyLich](https://github.com/AntsyLich)) ([#1835](https://github.com/mihonapp/mihon/pull/1835))
1717
- Added option to enable incognito per extension ([@sdaqo](https://github.com/sdaqo), [@AntsyLich](https://github.com/AntsyLich)) ([#157](https://github.com/mihonapp/mihon/pull/157))
1818
- Add button to favorite manga from history screen ([@Animeboynz](https://github.com/Animeboynz)) ([#1733](https://github.com/mihonapp/mihon/pull/1733))
1919
- Add Monochrome theme (made with e-ink displays in mind) ([@MajorTanya](https://github.com/MajorTanya)) ([#1752](https://github.com/mihonapp/mihon/pull/1752))
@@ -25,6 +25,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
2525
- Display staff information on Anilist tracker search results ([@NarwhalHorns](https://github.com/NarwhalHorns)) ([#1810](https://github.com/mihonapp/mihon/pull/1810))
2626

2727
### Changed
28+
- Sliders UI
2829
- Apply "Downloaded only" filter to all entries regardless of favourite status ([@NGB-Was-Taken](https://github.com/NGB-Was-Taken)) ([#1603](https://github.com/mihonapp/mihon/pull/1603))
2930
- Ignore hidden files/folders for Local Source chapter list ([@BrutuZ](https://github.com/BrutuZ)) ([#1763](https://github.com/mihonapp/mihon/pull/1763))
3031
- Migrate to newer Bangumi API ([@MajorTanya](https://github.com/MajorTanya)) ([#1748](https://github.com/mihonapp/mihon/pull/1748))

app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,9 @@ private fun ColumnScope.DisplayPage(
317317

318318
val columns by columnPreference.collectAsState()
319319
SliderItem(
320-
label = stringResource(MR.strings.pref_library_columns),
321-
max = 10,
322320
value = columns,
321+
valueRange = 0..10,
322+
label = stringResource(MR.strings.pref_library_columns),
323323
valueText = if (columns > 0) {
324324
columns.toString()
325325
} else {

app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package eu.kanade.presentation.more.settings
22

3+
import androidx.annotation.IntRange
34
import androidx.compose.runtime.Composable
45
import androidx.compose.runtime.remember
56
import androidx.compose.ui.graphics.vector.ImageVector
@@ -53,10 +54,9 @@ sealed class Preference {
5354
*/
5455
data class SliderPreference(
5556
val value: Int,
56-
val max: Int,
57-
val min: Int = 0,
58-
val steps: Int = 0,
5957
override val title: String,
58+
val valueRange: IntProgression = 0..1,
59+
@IntRange(from = 0) val steps: Int = with(valueRange) { (last - first) - 1 },
6060
override val subtitle: String? = null,
6161
override val enabled: Boolean = true,
6262
override val onValueChanged: suspend (value: Int) -> Boolean = { true },

app/src/main/java/eu/kanade/presentation/more/settings/PreferenceItem.kt

+14-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.compose.animation.expandVertically
55
import androidx.compose.animation.fadeIn
66
import androidx.compose.animation.fadeOut
77
import androidx.compose.animation.shrinkVertically
8+
import androidx.compose.foundation.layout.padding
89
import androidx.compose.material3.MaterialTheme
910
import androidx.compose.runtime.Composable
1011
import androidx.compose.runtime.CompositionLocalProvider
@@ -13,16 +14,20 @@ import androidx.compose.runtime.compositionLocalOf
1314
import androidx.compose.runtime.getValue
1415
import androidx.compose.runtime.rememberCoroutineScope
1516
import androidx.compose.runtime.structuralEqualityPolicy
17+
import androidx.compose.ui.Modifier
1618
import androidx.compose.ui.unit.dp
1719
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
1820
import eu.kanade.presentation.more.settings.widget.InfoWidget
1921
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
2022
import eu.kanade.presentation.more.settings.widget.MultiSelectListPreferenceWidget
23+
import eu.kanade.presentation.more.settings.widget.PrefsHorizontalPadding
24+
import eu.kanade.presentation.more.settings.widget.PrefsVerticalPadding
2125
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
2226
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
27+
import eu.kanade.presentation.more.settings.widget.TitleFontSize
2328
import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
2429
import kotlinx.coroutines.launch
25-
import tachiyomi.presentation.core.components.SliderItem
30+
import tachiyomi.presentation.core.components.BaseSliderItem
2631
import tachiyomi.presentation.core.util.collectAsState
2732

2833
val LocalPreferenceHighlighted = compositionLocalOf(structuralEqualityPolicy()) { false }
@@ -77,19 +82,22 @@ internal fun PreferenceItem(
7782
)
7883
}
7984
is Preference.PreferenceItem.SliderPreference -> {
80-
SliderItem(
85+
BaseSliderItem(
8186
label = item.title,
82-
min = item.min,
83-
max = item.max,
84-
steps = item.steps,
8587
value = item.value,
88+
valueRange = item.valueRange,
8689
valueText = item.subtitle.takeUnless { it.isNullOrEmpty() } ?: item.value.toString(),
90+
steps = item.steps,
91+
labelStyle = MaterialTheme.typography.titleLarge.copy(fontSize = TitleFontSize),
8792
onChange = {
8893
scope.launch {
8994
item.onValueChanged(it)
9095
}
9196
},
92-
labelStyle = MaterialTheme.typography.titleLarge,
97+
modifier = Modifier.padding(
98+
horizontal = PrefsHorizontalPadding,
99+
vertical = PrefsVerticalPadding,
100+
),
93101
)
94102
}
95103
is Preference.PreferenceItem.ListPreference<*> -> {

app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAppearanceScreen.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ object SettingsAppearanceScreen : SearchableSettings {
320320
),
321321
Preference.PreferenceItem.SliderPreference(
322322
value = previewsRowCount,
323+
valueRange = 0..10,
323324
title = stringResource(SYMR.strings.pref_previews_row_count),
324325
subtitle = if (previewsRowCount > 0) {
325326
pluralStringResource(
@@ -330,8 +331,6 @@ object SettingsAppearanceScreen : SearchableSettings {
330331
} else {
331332
stringResource(MR.strings.disabled)
332333
},
333-
min = 0,
334-
max = 10,
335334
onValueChanged = {
336335
uiPreferences.previewsRowCount().set(it)
337336
true

app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt

+5-8
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,7 @@ object SettingsReaderScreen : SearchableSettings {
176176
),
177177
Preference.PreferenceItem.SliderPreference(
178178
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
179-
max = 15,
180-
min = 1,
181-
steps = 13,
179+
valueRange = 1..15,
182180
title = stringResource(MR.strings.pref_flash_duration),
183181
subtitle = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
184182
enabled = flashPageState,
@@ -189,9 +187,7 @@ object SettingsReaderScreen : SearchableSettings {
189187
),
190188
Preference.PreferenceItem.SliderPreference(
191189
value = flashInterval,
192-
max = 10,
193-
min = 1,
194-
steps = 8,
190+
valueRange = 1..10,
195191
title = stringResource(MR.strings.pref_flash_page_interval),
196192
subtitle = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
197193
enabled = flashPageState,
@@ -390,8 +386,9 @@ object SettingsReaderScreen : SearchableSettings {
390386
),
391387
Preference.PreferenceItem.SliderPreference(
392388
value = webtoonSidePadding,
393-
max = ReaderPreferences.WEBTOON_PADDING_MAX,
394-
min = ReaderPreferences.WEBTOON_PADDING_MIN,
389+
valueRange = ReaderPreferences.let {
390+
it.WEBTOON_PADDING_MIN..it.WEBTOON_PADDING_MAX
391+
},
395392
title = stringResource(MR.strings.pref_webtoon_side_padding),
396393
subtitle = numberFormat.format(webtoonSidePadding / 100f),
397394
onValueChanged = {

app/src/main/java/eu/kanade/presentation/reader/components/ChapterNavigator.kt

+14
Original file line numberDiff line numberDiff line change
@@ -337,5 +337,19 @@ private fun ChapterNavigatorPreview() {
337337
isVerticalSlider = false,
338338
// SY <--
339339
)
340+
// KMK -->
341+
ChapterNavigator(
342+
isRtl = false,
343+
onNextChapter = {},
344+
enabledNext = true,
345+
onPreviousChapter = {},
346+
enabledPrevious = true,
347+
currentPage = currentPage,
348+
totalPages = 10,
349+
onPageIndexChange = { currentPage = (it + 1) },
350+
currentPageText = "1",
351+
isVerticalSlider = true,
352+
)
353+
// KMK <--
340354
}
341355
}

app/src/main/java/eu/kanade/presentation/reader/settings/ColorFilterPage.kt

+15-16
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
3737
if (customBrightness) {
3838
val customBrightnessValue by screenModel.preferences.customBrightnessValue().collectAsState()
3939
SliderItem(
40-
label = stringResource(MR.strings.pref_custom_brightness),
41-
min = -75,
42-
max = 100,
4340
value = customBrightnessValue,
44-
valueText = customBrightnessValue.toString(),
41+
valueRange = -75..100,
42+
steps = 0,
43+
label = stringResource(MR.strings.pref_custom_brightness),
4544
onChange = { screenModel.preferences.customBrightnessValue().set(it) },
4645
pillColor = MaterialTheme.colorScheme.surfaceContainerHighest,
4746
)
@@ -55,10 +54,10 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
5554
if (colorFilter) {
5655
val colorFilterValue by screenModel.preferences.colorFilterValue().collectAsState()
5756
SliderItem(
58-
label = stringResource(MR.strings.color_filter_r_value),
59-
max = 255,
6057
value = colorFilterValue.red,
61-
valueText = colorFilterValue.red.toString(),
58+
valueRange = 0..255,
59+
steps = 0,
60+
label = stringResource(MR.strings.color_filter_r_value),
6261
onChange = { newRValue ->
6362
screenModel.preferences.colorFilterValue().getAndSet {
6463
getColorValue(it, newRValue, RED_MASK, 16)
@@ -67,10 +66,10 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
6766
pillColor = MaterialTheme.colorScheme.surfaceContainerHighest,
6867
)
6968
SliderItem(
70-
label = stringResource(MR.strings.color_filter_g_value),
71-
max = 255,
7269
value = colorFilterValue.green,
73-
valueText = colorFilterValue.green.toString(),
70+
valueRange = 0..255,
71+
steps = 0,
72+
label = stringResource(MR.strings.color_filter_g_value),
7473
onChange = { newGValue ->
7574
screenModel.preferences.colorFilterValue().getAndSet {
7675
getColorValue(it, newGValue, GREEN_MASK, 8)
@@ -79,10 +78,10 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
7978
pillColor = MaterialTheme.colorScheme.surfaceContainerHighest,
8079
)
8180
SliderItem(
82-
label = stringResource(MR.strings.color_filter_b_value),
83-
max = 255,
8481
value = colorFilterValue.blue,
85-
valueText = colorFilterValue.blue.toString(),
82+
valueRange = 0..255,
83+
steps = 0,
84+
label = stringResource(MR.strings.color_filter_b_value),
8685
onChange = { newBValue ->
8786
screenModel.preferences.colorFilterValue().getAndSet {
8887
getColorValue(it, newBValue, BLUE_MASK, 0)
@@ -91,10 +90,10 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
9190
pillColor = MaterialTheme.colorScheme.surfaceContainerHighest,
9291
)
9392
SliderItem(
94-
label = stringResource(MR.strings.color_filter_a_value),
95-
max = 255,
9693
value = colorFilterValue.alpha,
97-
valueText = colorFilterValue.alpha.toString(),
94+
valueRange = 0..255,
95+
steps = 0,
96+
label = stringResource(MR.strings.color_filter_a_value),
9897
onChange = { newAValue ->
9998
screenModel.preferences.colorFilterValue().getAndSet {
10099
getColorValue(it, newAValue, ALPHA_MASK, 24)

app/src/main/java/eu/kanade/presentation/reader/settings/GeneralSettingsPage.kt

+2-6
Original file line numberDiff line numberDiff line change
@@ -122,24 +122,20 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
122122
if (flashPageState) {
123123
SliderItem(
124124
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
125+
valueRange = 1..15,
125126
label = stringResource(MR.strings.pref_flash_duration),
126127
valueText = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
127128
onChange = { flashMillisPref.set(it * ReaderPreferences.MILLI_CONVERSION) },
128-
min = 1,
129-
max = 15,
130-
steps = 13,
131129
pillColor = MaterialTheme.colorScheme.surfaceContainerHighest,
132130
)
133131
SliderItem(
134132
value = flashInterval,
133+
valueRange = 1..10,
135134
label = stringResource(MR.strings.pref_flash_page_interval),
136135
valueText = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
137136
onChange = {
138137
flashIntervalPref.set(it)
139138
},
140-
min = 1,
141-
max = 10,
142-
steps = 8,
143139
pillColor = MaterialTheme.colorScheme.surfaceContainerHighest,
144140
)
145141
SettingsChipRow(MR.strings.pref_flash_with) {

app/src/main/java/eu/kanade/presentation/reader/settings/ReadingModePage.kt

+2-3
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,9 @@ private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenM
193193

194194
val webtoonSidePadding by screenModel.preferences.webtoonSidePadding().collectAsState()
195195
SliderItem(
196-
label = stringResource(MR.strings.pref_webtoon_side_padding),
197-
min = ReaderPreferences.WEBTOON_PADDING_MIN,
198-
max = ReaderPreferences.WEBTOON_PADDING_MAX,
199196
value = webtoonSidePadding,
197+
valueRange = ReaderPreferences.let { it.WEBTOON_PADDING_MIN..it.WEBTOON_PADDING_MAX },
198+
label = stringResource(MR.strings.pref_webtoon_side_padding),
200199
valueText = numberFormat.format(webtoonSidePadding / 100f),
201200
onChange = {
202201
screenModel.preferences.webtoonSidePadding().set(it)

presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt

+40-16
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import androidx.compose.material3.darkColorScheme
3636
import androidx.compose.material3.lightColorScheme
3737
import androidx.compose.runtime.Composable
3838
import androidx.compose.runtime.getValue
39+
import androidx.compose.runtime.mutableIntStateOf
3940
import androidx.compose.runtime.mutableStateOf
4041
import androidx.compose.runtime.remember
4142
import androidx.compose.runtime.setValue
@@ -173,25 +174,49 @@ fun RadioItem(label: String, selected: Boolean, onClick: () -> Unit) {
173174

174175
@Composable
175176
fun SliderItem(
177+
value: Int,
178+
valueRange: IntProgression,
176179
label: String,
180+
onChange: (Int) -> Unit,
181+
steps: Int = with(valueRange) { (last - first) - 1 },
182+
valueText: String = value.toString(),
183+
labelStyle: TextStyle = MaterialTheme.typography.bodyMedium,
184+
pillColor: Color = MaterialTheme.colorScheme.surfaceContainerHigh,
185+
) {
186+
BaseSliderItem(
187+
value = value,
188+
valueRange = valueRange,
189+
steps = steps,
190+
label = label,
191+
valueText = valueText,
192+
onChange = onChange,
193+
labelStyle = labelStyle,
194+
pillColor = pillColor,
195+
modifier = Modifier.padding(
196+
horizontal = SettingsItemsPaddings.Horizontal,
197+
vertical = SettingsItemsPaddings.Vertical,
198+
),
199+
)
200+
}
201+
202+
@Composable
203+
fun BaseSliderItem(
177204
value: Int,
178-
valueText: String,
205+
valueRange: IntProgression,
206+
label: String,
179207
onChange: (Int) -> Unit,
180-
max: Int,
181-
min: Int = 0,
182-
steps: Int = 0,
208+
modifier: Modifier = Modifier,
209+
steps: Int = with(valueRange) { (last - first) - 1 },
210+
valueText: String = value.toString(),
183211
labelStyle: TextStyle = MaterialTheme.typography.bodyMedium,
184212
pillColor: Color = MaterialTheme.colorScheme.surfaceContainerHigh,
185213
) {
186214
val haptic = LocalHapticFeedback.current
187-
188215
Column(
189216
modifier = Modifier
190217
.fillMaxWidth()
191-
.padding(
192-
horizontal = SettingsItemsPaddings.Horizontal,
193-
vertical = SettingsItemsPaddings.Vertical,
194-
),
218+
.then(modifier),
219+
verticalArrangement = Arrangement.spacedBy(2.dp),
195220
) {
196221
Row(
197222
verticalAlignment = Alignment.CenterVertically,
@@ -215,7 +240,7 @@ fun SliderItem(
215240
onChange(it)
216241
haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove)
217242
},
218-
valueRange = min..max,
243+
valueRange = valueRange,
219244
steps = steps,
220245
)
221246
}
@@ -225,15 +250,14 @@ fun SliderItem(
225250
@PreviewLightDark
226251
fun SliderItemPreview() {
227252
MaterialTheme(if (isSystemInDarkTheme()) darkColorScheme() else lightColorScheme()) {
253+
var value by remember { mutableIntStateOf(0) }
228254
Surface {
229255
SliderItem(
256+
value = value,
257+
valueRange = 0..10,
230258
label = "Item per row",
231-
valueText = "Auto",
232-
value = 0,
233-
onChange = {},
234-
min = 0,
235-
max = 10,
236-
steps = 8,
259+
valueText = if (value == 0) "Auto" else value.toString(),
260+
onChange = { value = it },
237261
)
238262
}
239263
}

0 commit comments

Comments
 (0)