diff --git a/app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderAppBars.kt b/app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderAppBars.kt index d4155cb3c..68e699d05 100644 --- a/app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderAppBars.kt +++ b/app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderAppBars.kt @@ -84,7 +84,7 @@ fun ReaderAppBars( enabledPrevious: Boolean, currentPage: Int, totalPages: Int, - onSliderValueChange: (Int) -> Unit, + onPageIndexChange: (Int) -> Unit, readingMode: ReadingMode, onClickReadingMode: () -> Unit, @@ -154,7 +154,7 @@ fun ReaderAppBars( enabledPrevious = enabledPrevious, currentPage = currentPage, totalPages = totalPages, - onSliderValueChange = onSliderValueChange, + onPageIndexChange = onPageIndexChange, isVerticalSlider = true, currentPageText = currentPageText, ) @@ -182,7 +182,7 @@ fun ReaderAppBars( enabledPrevious = enabledPrevious, currentPage = currentPage, totalPages = totalPages, - onSliderValueChange = onSliderValueChange, + onPageIndexChange = onPageIndexChange, isVerticalSlider = true, currentPageText = currentPageText, ) @@ -311,12 +311,11 @@ fun ReaderAppBars( enabledPrevious = enabledPrevious, currentPage = currentPage, totalPages = totalPages, - onSliderValueChange = onSliderValueChange, + onPageIndexChange = onPageIndexChange, isVerticalSlider = false, currentPageText = currentPageText, ) } - BottomReaderBar( // SY --> enabledButtons = enabledButtons, diff --git a/app/src/main/java/eu/kanade/presentation/reader/components/ChapterNavigator.kt b/app/src/main/java/eu/kanade/presentation/reader/components/ChapterNavigator.kt index 71d5463de..3dd42640d 100644 --- a/app/src/main/java/eu/kanade/presentation/reader/components/ChapterNavigator.kt +++ b/app/src/main/java/eu/kanade/presentation/reader/components/ChapterNavigator.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsDraggedAsState import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -18,7 +19,6 @@ import androidx.compose.material3.FilledIconButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable @@ -32,6 +32,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.rotate +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.hapticfeedback.HapticFeedbackType @@ -45,8 +46,8 @@ import androidx.compose.ui.unit.dp import eu.kanade.presentation.theme.TachiyomiPreviewTheme import eu.kanade.presentation.util.isTabletUi import tachiyomi.i18n.MR +import tachiyomi.presentation.core.components.material.Slider import tachiyomi.presentation.core.i18n.stringResource -import kotlin.math.roundToInt @Composable fun ChapterNavigator( @@ -61,7 +62,7 @@ fun ChapterNavigator( currentPageText: String, // SY <-- totalPages: Int, - onSliderValueChange: (Int) -> Unit, + onPageIndexChange: (Int) -> Unit, ) { // SY --> if (isVerticalSlider) { @@ -73,7 +74,7 @@ fun ChapterNavigator( currentPage = currentPage, currentPageText = currentPageText, totalPages = totalPages, - onSliderValueChange = onSliderValueChange, + onPageIndexChange = onPageIndexChange, ) return } @@ -87,7 +88,6 @@ fun ChapterNavigator( val backgroundColor = MaterialTheme.colorScheme .surfaceColorAtElevation(3.dp) .copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f) - val textColor = MaterialTheme.colorScheme.onSurface val buttonColor = IconButtonDefaults.filledIconButtonColors( containerColor = backgroundColor, disabledContainerColor = backgroundColor, @@ -95,6 +95,7 @@ fun ChapterNavigator( contentColor = MaterialTheme.colorScheme.primary, // KMK <-- ) + val textColor = MaterialTheme.colorScheme.onSurface // We explicitly handle direction based on the reader viewer rather than the system direction CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) { @@ -127,14 +128,18 @@ fun ChapterNavigator( .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically, ) { - // SY --> - Text( - text = currentPageText, - // KMK --> - color = textColor, - // KMK <-- - ) - // SY <-- + Box(contentAlignment = Alignment.CenterEnd) { + Text( + // SY --> + text = currentPageText, + // SY <-- + // KMK --> + color = textColor, + // KMK <-- + ) + // Taking up full length so the slider doesn't shift when 'currentPage' length changes + Text(text = totalPages.toString(), color = Color.Transparent) + } val interactionSource = remember { MutableInteractionSource() } val sliderDragged by interactionSource.collectIsDraggedAsState() @@ -147,14 +152,11 @@ fun ChapterNavigator( modifier = Modifier .weight(1f) .padding(horizontal = 8.dp), - value = currentPage.toFloat(), - valueRange = 1f..totalPages.toFloat(), - steps = totalPages - 2, - onValueChange = { - val new = it.roundToInt() - 1 - if (new != currentPage) { - onSliderValueChange(new) - } + value = currentPage, + valueRange = 1..totalPages, + onValueChange = f@{ + if (it == currentPage) return@f + onPageIndexChange(it - 1) }, interactionSource = interactionSource, ) @@ -198,7 +200,7 @@ fun ChapterNavigatorVert( currentPageText: String, // SY <-- totalPages: Int, - onSliderValueChange: (Int) -> Unit, + onPageIndexChange: (Int) -> Unit, ) { val isTabletUi = isTabletUi() val verticalPadding = if (isTabletUi) 24.dp else 8.dp @@ -215,7 +217,6 @@ fun ChapterNavigatorVert( val backgroundColor = MaterialTheme.colorScheme .surfaceColorAtElevation(3.dp) .copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f) - val buttonColor = IconButtonDefaults.filledIconButtonColors( containerColor = backgroundColor, disabledContainerColor = backgroundColor, @@ -223,6 +224,8 @@ fun ChapterNavigatorVert( contentColor = MaterialTheme.colorScheme.primary, // KMK <-- ) + val textColor = MaterialTheme.colorScheme.onSurface + FilledIconButton( enabled = enabledPrevious, onClick = onPreviousChapter, @@ -244,9 +247,14 @@ fun ChapterNavigatorVert( .padding(vertical = 16.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - // SY --> - Text(text = currentPageText) - // SY <-- + Text( + // SY --> + text = currentPageText, + // SY <-- + // KMK --> + color = textColor, + // KMK <-- + ) val interactionSource = remember { MutableInteractionSource() } val sliderDragged by interactionSource.collectIsDraggedAsState() @@ -276,16 +284,21 @@ fun ChapterNavigatorVert( } } .weight(1f), - value = currentPage.toFloat(), - valueRange = 1f..totalPages.toFloat(), - steps = totalPages, - onValueChange = { - onSliderValueChange(it.roundToInt() - 1) + value = currentPage, + valueRange = 1..totalPages, + onValueChange = f@{ + if (it == currentPage) return@f + onPageIndexChange(it - 1) }, interactionSource = interactionSource, ) - Text(text = totalPages.toString()) + Text( + text = totalPages.toString(), + // KMK --> + color = textColor, + // KMK <-- + ) } } else { Spacer(Modifier.weight(1f)) @@ -318,7 +331,7 @@ private fun ChapterNavigatorPreview() { enabledPrevious = true, currentPage = currentPage, totalPages = 10, - onSliderValueChange = { currentPage = it }, + onPageIndexChange = { currentPage = (it + 1) }, // SY --> currentPageText = "1", isVerticalSlider = false, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index eab2206f3..b2f34a64e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -530,7 +530,7 @@ class ReaderActivity : BaseActivity() { enabledPrevious = state.viewerChapters?.prevChapter != null, currentPage = state.currentPage, totalPages = state.totalPages, - onSliderValueChange = { + onPageIndexChange = { isScrollingThroughPages = true moveToPageIndex(it) }, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt index c18163cc0..82bac0933 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt @@ -1338,6 +1338,7 @@ class ReaderViewModel @JvmOverloads constructor( @IntRange(from = -100, to = 100) val brightnessOverlayValue: Int = 0, // SY --> + /** for display page number in double-page mode */ val currentPageText: String = "", val meta: RaisedSearchMetadata? = null, val mergedManga: Map? = null, diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt index c9d4603e4..540d49175 100644 --- a/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt @@ -29,7 +29,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.RadioButton -import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -48,6 +47,7 @@ import tachiyomi.core.common.preference.Preference import tachiyomi.core.common.preference.TriState import tachiyomi.core.common.preference.toggle import tachiyomi.presentation.core.components.material.DISABLED_ALPHA +import tachiyomi.presentation.core.components.material.Slider import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.theme.header @@ -194,17 +194,14 @@ fun SliderItem( } Slider( - value = value.toFloat(), - onValueChange = { - val newValue = it.toInt() - if (newValue != value) { - onChange(newValue) - haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) - } - }, modifier = Modifier.weight(1.5f), - valueRange = min.toFloat()..max.toFloat(), - steps = max - min - 1, + value = value, + onValueChange = f@{ + if (it == value) return@f + onChange(it) + haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) + }, + valueRange = min..max, ) } } diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Slider.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Slider.kt new file mode 100644 index 000000000..aa562ab32 --- /dev/null +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/material/Slider.kt @@ -0,0 +1,48 @@ +package tachiyomi.presentation.core.components.material + +import androidx.annotation.IntRange +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.Slider +import androidx.compose.material3.SliderColors +import androidx.compose.material3.SliderDefaults +import androidx.compose.material3.SliderState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier + +@Composable +fun Slider( + value: Int, + onValueChange: (Int) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + valueRange: ClosedRange = 0..1, + @IntRange(from = 0) steps: Int = with(valueRange) { (endInclusive - start) - 1 }, + onValueChangeFinished: (() -> Unit)? = null, + colors: SliderColors = SliderDefaults.colors(), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + thumb: @Composable (SliderState) -> Unit = { + SliderDefaults.Thumb( + interactionSource = interactionSource, + colors = colors, + enabled = enabled, + ) + }, + track: @Composable (SliderState) -> Unit = { sliderState -> + SliderDefaults.Track(colors = colors, enabled = enabled, sliderState = sliderState) + }, +) { + Slider( + value = value.toFloat(), + onValueChange = { onValueChange(it.toInt()) }, + modifier = modifier, + enabled = enabled, + valueRange = with(valueRange) { start.toFloat()..endInclusive.toFloat() }, + steps = steps, + onValueChangeFinished = onValueChangeFinished, + colors = colors, + interactionSource = interactionSource, + thumb = thumb, + track = track, + ) +}