[New Reader] Implement landscape zoom
This commit is contained in:
1 parent
7b1f94cf5a
commit
53a1bd9959
3 files changed
+53
-10
No files matched your search
@@ -70,6 +70,14 @@ inline fun <R, T> PrefDelegate<T>.collectAsState(crossinline transform: @Disallo
|
||||
return flow.collectAsState(transform(init))
|
||||
}
|
||||
|
||||
@Stable
|
||||
@Composable
|
||||
inline fun <R, T> PrefDelegate<T>.collectAsState(key1: Any?, crossinline transform: @DisallowComposableCalls (T) -> R): State<R> {
|
||||
val flow = remember(key1) { valueFlow().map { transform(it) } }
|
||||
val init = getValue()
|
||||
return flow.collectAsState(transform(init))
|
||||
}
|
||||
|
||||
@Stable
|
||||
@Composable
|
||||
fun <T> PrefDelegate<T>.collectAsState(): State<T> {
|
||||
|
||||
@@ -31,6 +31,8 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.FixedScale
|
||||
import androidx.compose.ui.layout.times
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.toSize
|
||||
import com.hippo.ehviewer.Settings
|
||||
@@ -50,6 +52,7 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType.WEBTOON
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
||||
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import me.saket.telephoto.zoomable.DoubleClickToZoomListener
|
||||
import me.saket.telephoto.zoomable.ZoomSpec
|
||||
@@ -75,10 +78,11 @@ fun GalleryPager(
|
||||
DEFAULT, LEFT_TO_RIGHT, RIGHT_TO_LEFT, VERTICAL -> {
|
||||
val isVertical = type == VERTICAL
|
||||
val scaleType by Settings.imageScaleType.collectAsState()
|
||||
val alignment by Settings.zoomStart.collectAsState {
|
||||
Alignment.fromPreferences(it, isVertical)
|
||||
val landscapeZoom by Settings.landscapeZoom.collectAsState()
|
||||
val alignment by Settings.zoomStart.collectAsState(type) {
|
||||
Alignment.fromPreferences(it, type)
|
||||
}
|
||||
val navigatorState = Settings.readerPagerNav.collectAsState {
|
||||
val navigatorState = Settings.readerPagerNav.collectAsState(isVertical) {
|
||||
ViewerNavigation.fromPreference(it, isVertical)
|
||||
}
|
||||
val invertMode by Settings.readerPagerNavInverted.collectAsState {
|
||||
@@ -105,6 +109,7 @@ fun GalleryPager(
|
||||
pageLoader = pageLoader,
|
||||
isRtl = false,
|
||||
scaleType = scaleType,
|
||||
landscapeZoom = landscapeZoom,
|
||||
alignment = alignment,
|
||||
layoutSize = layoutSize,
|
||||
navigatorState = navigatorState,
|
||||
@@ -116,11 +121,12 @@ fun GalleryPager(
|
||||
}
|
||||
} else {
|
||||
val isRtl = type == RIGHT_TO_LEFT
|
||||
val isRtlLayout = LocalLayoutDirection.current == LayoutDirection.Rtl
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
modifier = modifier,
|
||||
contentPadding = contentPadding,
|
||||
reverseLayout = isRtl,
|
||||
reverseLayout = isRtl xor isRtlLayout,
|
||||
key = { it },
|
||||
) { index ->
|
||||
val page = items[index]
|
||||
@@ -129,6 +135,7 @@ fun GalleryPager(
|
||||
pageLoader = pageLoader,
|
||||
isRtl = isRtl,
|
||||
scaleType = scaleType,
|
||||
landscapeZoom = landscapeZoom,
|
||||
alignment = alignment,
|
||||
layoutSize = layoutSize,
|
||||
navigatorState = navigatorState,
|
||||
@@ -212,6 +219,7 @@ private fun PageContainer(
|
||||
pageLoader: PageLoader2,
|
||||
isRtl: Boolean,
|
||||
scaleType: Int,
|
||||
landscapeZoom: Boolean,
|
||||
alignment: Alignment.Horizontal,
|
||||
layoutSize: Size,
|
||||
navigatorState: State<ViewerNavigation>,
|
||||
@@ -222,7 +230,7 @@ private fun PageContainer(
|
||||
) {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val isRtl by rememberUpdatedState(isRtl)
|
||||
val zoomableState = rememberZoomableState(zoomSpec = zoomSpec)
|
||||
val zoomableState = rememberZoomableState(zoomSpec = pagerZoomSpec)
|
||||
val status by page.status.collectAsState()
|
||||
if (status == Page.State.READY) {
|
||||
val size = page.image!!.rect.size.toSize()
|
||||
@@ -250,6 +258,18 @@ private fun PageContainer(
|
||||
val contentLocation = ZoomableContentLocation.scaledInsideAndCenterAligned(size)
|
||||
zoomableState.setContentLocation(contentLocation)
|
||||
}
|
||||
if (landscapeZoom && contentScale == ContentScale.Fit && size.width > size.height) {
|
||||
LaunchedEffect(alignment) {
|
||||
delay(500)
|
||||
if (zoomableState.zoomFraction == 0f) {
|
||||
val contentSize = zoomableState.transformedContentBounds.size
|
||||
val scale = ContentScale.FillHeight.computeScaleFactor(contentSize, layoutSize)
|
||||
val targetScale = scale.scaleX.coerceAtMost(zoomableState.zoomSpec.maxZoomFactor)
|
||||
val offset = alignment.align(0, layoutSize.width.toInt(), LayoutDirection.Ltr)
|
||||
zoomableState.zoomTo(targetScale, Offset(offset.toFloat(), 0f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
PagerItem(
|
||||
@@ -350,13 +370,21 @@ suspend fun LazyListState.performScrollBy(value: Float) {
|
||||
}
|
||||
|
||||
object DoubleTapZoom : DoubleClickToZoomListener {
|
||||
private val listener = DoubleClickToZoomListener.cycle(maxZoomFactor = 2f)
|
||||
|
||||
override suspend fun onDoubleClick(state: ZoomableState, centroid: Offset) {
|
||||
if (Settings.doubleTapToZoom.value) {
|
||||
listener.onDoubleClick(state, centroid)
|
||||
val zoomFraction = state.zoomFraction ?: return // Content isn't ready yet
|
||||
if (zoomFraction > 0.05f) {
|
||||
state.resetZoom()
|
||||
} else {
|
||||
// Workaround for https://github.com/saket/telephoto/issues/45
|
||||
state.zoomTo(
|
||||
zoomFactor = state.contentTransformation.scaleMetadata.initialScale.scaleX * 2f,
|
||||
centroid = centroid,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val pagerZoomSpec = ZoomSpec(maxZoomFactor = 5f)
|
||||
private val zoomSpec = ZoomSpec(maxZoomFactor = 3f)
|
||||
@@ -13,6 +13,9 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.FixedScale
|
||||
import com.hippo.ehviewer.Settings
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType.RIGHT_TO_LEFT
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType.VERTICAL
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
|
||||
fun Window.updateKeepScreenOn(enabled: Boolean) {
|
||||
@@ -58,8 +61,12 @@ fun Activity.setCustomBrightnessValue(value: Int) {
|
||||
window.attributes = window.attributes.apply { screenBrightness = readerBrightness }
|
||||
}
|
||||
|
||||
fun Alignment.Companion.fromPreferences(value: Int, isVertical: Boolean) = when (value) {
|
||||
1 -> if (isVertical) CenterHorizontally else Start
|
||||
fun Alignment.Companion.fromPreferences(value: Int, mode: ReadingModeType) = when (value) {
|
||||
1 -> when (mode) {
|
||||
VERTICAL -> CenterHorizontally
|
||||
RIGHT_TO_LEFT -> AbsoluteAlignment.Right
|
||||
else -> AbsoluteAlignment.Left
|
||||
}
|
||||
2 -> AbsoluteAlignment.Left
|
||||
3 -> AbsoluteAlignment.Right
|
||||
else -> CenterHorizontally
|
||||
|
||||
Reference in new issue
Block a user