Fix page transitions when reading with volume keys
This commit is contained in:
1 parent
2531fa289b
commit
28279cc671
5 files changed
+69
-46
No files matched your search
@@ -1,7 +1,5 @@
|
||||
package com.hippo.ehviewer.ui.reader
|
||||
|
||||
import androidx.compose.foundation.gestures.animateScrollBy
|
||||
import androidx.compose.foundation.gestures.scrollBy
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -177,11 +175,10 @@ fun GalleryPager(
|
||||
val size = lazyListState.layoutInfo.viewportSize
|
||||
val x = it.x / size.width
|
||||
val y = it.y / size.height
|
||||
val distance = size.height * 0.75f
|
||||
when (navigatorState.value.getAction(x, y)) {
|
||||
NavigationRegion.MENU -> onMenuRegionClick()
|
||||
NavigationRegion.NEXT, NavigationRegion.RIGHT -> performScrollBy(distance)
|
||||
NavigationRegion.PREV, NavigationRegion.LEFT -> performScrollBy(-distance)
|
||||
NavigationRegion.NEXT, NavigationRegion.RIGHT -> scrollDown()
|
||||
NavigationRegion.PREV, NavigationRegion.LEFT -> scrollUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,36 +350,6 @@ suspend fun ZoomableState.panRight(distance: Float): Boolean {
|
||||
return canPan
|
||||
}
|
||||
|
||||
suspend fun PagerState.performScrollToPage(page: Int) {
|
||||
if (Settings.pageTransitions.value) {
|
||||
animateScrollToPage(page)
|
||||
} else {
|
||||
scrollToPage(page)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun PagerState.moveToPrevious() {
|
||||
val target = currentPage - 1
|
||||
if (target >= 0) {
|
||||
performScrollToPage(target)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun PagerState.moveToNext() {
|
||||
val target = currentPage + 1
|
||||
if (target < pageCount) {
|
||||
performScrollToPage(target)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun LazyListState.performScrollBy(value: Float) {
|
||||
if (Settings.pageTransitions.value) {
|
||||
animateScrollBy(value)
|
||||
} else {
|
||||
scrollBy(value)
|
||||
}
|
||||
}
|
||||
|
||||
object DoubleTapZoom : DoubleClickToZoomListener {
|
||||
override suspend fun onDoubleClick(state: ZoomableState, centroid: Offset) {
|
||||
if (Settings.doubleTapToZoom.value) {
|
||||
|
||||
@@ -36,6 +36,7 @@ import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -160,7 +161,8 @@ fun AnimatedVisibilityScope.ReaderScreen(pageLoader: PageLoader2, info: BaseGall
|
||||
Box {
|
||||
var appbarVisible by remember { mutableStateOf(false) }
|
||||
val bgColor by collectBackgroundColorAsState()
|
||||
syncState.Sync(ReadingModeType.isWebtoon(readingMode)) { appbarVisible = false }
|
||||
val isWebtoon by rememberUpdatedState(ReadingModeType.isWebtoon(readingMode))
|
||||
syncState.Sync(isWebtoon, appbarVisible) { appbarVisible = false }
|
||||
if (fullscreen) {
|
||||
LaunchedEffect(Unit) {
|
||||
snapshotFlow { appbarVisible }.collect {
|
||||
@@ -170,8 +172,12 @@ fun AnimatedVisibilityScope.ReaderScreen(pageLoader: PageLoader2, info: BaseGall
|
||||
}
|
||||
VolumeKeysHandler(
|
||||
enabled = { volumeKeysEnabled && !appbarVisible },
|
||||
movePrevious = { syncState.sliderScrollTo(syncState.sliderValue - 1) },
|
||||
moveNext = { syncState.sliderScrollTo(syncState.sliderValue + 1) },
|
||||
movePrevious = {
|
||||
if (isWebtoon) lazyListState.scrollUp() else pagerState.moveToPrevious()
|
||||
},
|
||||
moveNext = {
|
||||
if (isWebtoon) lazyListState.scrollDown() else pagerState.moveToNext()
|
||||
},
|
||||
)
|
||||
GalleryPager(
|
||||
type = readingMode,
|
||||
|
||||
@@ -32,10 +32,10 @@ class SliderPagerDoubleSync(
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Sync(webtoon: Boolean, onPageSelected: () -> Unit) {
|
||||
fun Sync(webtoon: Boolean, appbarVisible: Boolean, onPageSelected: () -> Unit) {
|
||||
val fling by lazyListState.interactionSource.collectIsDraggedAsState()
|
||||
val pagerFling by pagerState.interactionSource.collectIsDraggedAsState()
|
||||
if (fling || pagerFling) sliderFollowPager = true
|
||||
if (fling || pagerFling || !appbarVisible) sliderFollowPager = true
|
||||
val currentIndexFlow = remember(webtoon) {
|
||||
val initialIndex = sliderValue - 1
|
||||
if (webtoon) {
|
||||
|
||||
@@ -3,6 +3,10 @@ package com.hippo.ehviewer.ui.reader
|
||||
import android.app.Activity
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.compose.foundation.gestures.animateScrollBy
|
||||
import androidx.compose.foundation.gestures.scrollBy
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.pager.PagerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
@@ -82,3 +86,44 @@ fun ContentScale.Companion.fromPreferences(value: Int, srcSize: Size, dstSize: S
|
||||
6 -> if (srcSize.width > srcSize.height) FillHeight else FillWidth
|
||||
else -> Fit
|
||||
}
|
||||
|
||||
suspend fun PagerState.performScrollToPage(page: Int) {
|
||||
if (Settings.pageTransitions.value) {
|
||||
animateScrollToPage(page)
|
||||
} else {
|
||||
scrollToPage(page)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun PagerState.moveToPrevious() {
|
||||
val target = currentPage - 1
|
||||
if (target >= 0) {
|
||||
performScrollToPage(target)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun PagerState.moveToNext() {
|
||||
val target = currentPage + 1
|
||||
if (target < pageCount) {
|
||||
performScrollToPage(target)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun LazyListState.performScrollBy(value: Float) {
|
||||
if (Settings.pageTransitions.value) {
|
||||
animateScrollBy(value)
|
||||
} else {
|
||||
scrollBy(value)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun LazyListState.scrollUp() {
|
||||
performScrollBy(-scrollDistance)
|
||||
}
|
||||
|
||||
suspend fun LazyListState.scrollDown() {
|
||||
performScrollBy(scrollDistance)
|
||||
}
|
||||
|
||||
private val LazyListState.scrollDistance
|
||||
get() = layoutInfo.viewportSize.height * 0.75f
|
||||
@@ -8,12 +8,15 @@ import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.hippo.ehviewer.Settings
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
context(CoroutineScope)
|
||||
@Composable
|
||||
fun VolumeKeysHandler(
|
||||
enabled: () -> Boolean,
|
||||
movePrevious: () -> Unit,
|
||||
moveNext: () -> Unit,
|
||||
movePrevious: suspend () -> Unit,
|
||||
moveNext: suspend () -> Unit,
|
||||
) {
|
||||
val view = LocalView.current
|
||||
DisposableEffect(view) {
|
||||
@@ -24,10 +27,12 @@ fun VolumeKeysHandler(
|
||||
val interval = Settings.readWithVolumeKeysInterval.value + 1
|
||||
val inverted = Settings.readWithVolumeKeysInverted.value
|
||||
if (event.action == ACTION_DOWN && event.repeatCount % interval == 0) {
|
||||
if (inverted.xor(keyCode == KEYCODE_VOLUME_UP)) {
|
||||
movePrevious()
|
||||
} else {
|
||||
moveNext()
|
||||
launch {
|
||||
if (inverted.xor(keyCode == KEYCODE_VOLUME_UP)) {
|
||||
movePrevious()
|
||||
} else {
|
||||
moveNext()
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
|
||||
Reference in new issue
Block a user