feat(reader-paged): Add options to disable zoom in or double tap to zoom for paged-reader (#1123)

This commit is contained in:
Cuong-Tran 2025-09-04 17:03:49 +07:00 committed by GitHub
parent 242b980e57
commit 9e5069a376
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 84 additions and 13 deletions

View file

@ -256,6 +256,10 @@ object SettingsReaderScreen : SearchableSettings {
val dualPageSplit by dualPageSplitPref.collectAsState() val dualPageSplit by dualPageSplitPref.collectAsState()
val rotateToFit by rotateToFitPref.collectAsState() val rotateToFit by rotateToFitPref.collectAsState()
// KMK -->
val pagedDisableZoomIn by readerPreferences.pagedDisableZoomIn().collectAsState()
// KMK <--
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(MR.strings.pager_viewer), title = stringResource(MR.strings.pager_viewer),
preferenceItems = persistentListOf( preferenceItems = persistentListOf(
@ -311,6 +315,17 @@ object SettingsReaderScreen : SearchableSettings {
title = stringResource(MR.strings.pref_landscape_zoom), title = stringResource(MR.strings.pref_landscape_zoom),
enabled = imageScaleType == 1, enabled = imageScaleType == 1,
), ),
// KMK -->
Preference.PreferenceItem.SwitchPreference(
preference = readerPreferences.pagedDisableZoomIn(),
title = stringResource(KMR.strings.pref_paged_disable_zoom_in),
),
Preference.PreferenceItem.SwitchPreference(
preference = readerPreferences.pagedDoubleTapZoomEnabled(),
title = stringResource(MR.strings.pref_double_tap_zoom),
enabled = !pagedDisableZoomIn,
),
// KMK <--
Preference.PreferenceItem.SwitchPreference( Preference.PreferenceItem.SwitchPreference(
preference = readerPreferences.navigateToPan(), preference = readerPreferences.navigateToPan(),
title = stringResource(MR.strings.pref_navigate_pan), title = stringResource(MR.strings.pref_navigate_pan),

View file

@ -1,6 +1,5 @@
package eu.kanade.presentation.reader.settings package eu.kanade.presentation.reader.settings
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChip
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -21,7 +20,7 @@ import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState import tachiyomi.presentation.core.util.collectAsState
@Composable @Composable
internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel) { internal fun ColorFilterPage(screenModel: ReaderSettingsScreenModel) {
val customBrightness by screenModel.preferences.customBrightness().collectAsState() val customBrightness by screenModel.preferences.customBrightness().collectAsState()
CheckboxItem( CheckboxItem(
label = stringResource(MR.strings.pref_custom_brightness), label = stringResource(MR.strings.pref_custom_brightness),

View file

@ -1,6 +1,5 @@
package eu.kanade.presentation.reader.settings package eu.kanade.presentation.reader.settings
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChip
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -30,9 +29,8 @@ private val flashColors = listOf(
MR.strings.pref_flash_style_white_black to ReaderPreferences.FlashColor.WHITE_BLACK, MR.strings.pref_flash_style_white_black to ReaderPreferences.FlashColor.WHITE_BLACK,
) )
@Suppress("UnusedReceiverParameter")
@Composable @Composable
internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) { internal fun GeneralPage(screenModel: ReaderSettingsScreenModel) {
val readerTheme by screenModel.preferences.readerTheme().collectAsState() val readerTheme by screenModel.preferences.readerTheme().collectAsState()
val flashPageState by screenModel.preferences.flashOnPageChange().collectAsState() val flashPageState by screenModel.preferences.flashOnPageChange().collectAsState()

View file

@ -1,6 +1,5 @@
package eu.kanade.presentation.reader.settings package eu.kanade.presentation.reader.settings
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChip
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -27,7 +26,7 @@ import tachiyomi.presentation.core.util.collectAsState
import java.text.NumberFormat import java.text.NumberFormat
@Composable @Composable
internal fun ColumnScope.ReadingModePage(screenModel: ReaderSettingsScreenModel) { internal fun ReadingModePage(screenModel: ReaderSettingsScreenModel) {
HeadingItem(MR.strings.pref_category_for_this_series) HeadingItem(MR.strings.pref_category_for_this_series)
val manga by screenModel.mangaFlow.collectAsState() val manga by screenModel.mangaFlow.collectAsState()
@ -65,7 +64,7 @@ internal fun ColumnScope.ReadingModePage(screenModel: ReaderSettingsScreenModel)
} }
@Composable @Composable
private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenModel) { private fun PagerViewerSettings(screenModel: ReaderSettingsScreenModel) {
HeadingItem(MR.strings.pager_viewer) HeadingItem(MR.strings.pager_viewer)
val navigationModePager by screenModel.preferences.navigationModePager().collectAsState() val navigationModePager by screenModel.preferences.navigationModePager().collectAsState()
@ -171,6 +170,20 @@ private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenMod
pref = screenModel.preferences.invertDoublePages(), pref = screenModel.preferences.invertDoublePages(),
) )
// KMK -->
CheckboxItem(
label = stringResource(KMR.strings.pref_paged_disable_zoom_in),
pref = screenModel.preferences.pagedDisableZoomIn(),
)
val pagedDisableZoomIn by screenModel.preferences.pagedDisableZoomIn().collectAsState()
if (!pagedDisableZoomIn) {
CheckboxItem(
label = stringResource(MR.strings.pref_double_tap_zoom),
pref = screenModel.preferences.pagedDoubleTapZoomEnabled(),
)
}
// KMK <--
val centerMarginType by screenModel.preferences.centerMarginType().collectAsState() val centerMarginType by screenModel.preferences.centerMarginType().collectAsState()
SettingsChipRow(SYMR.strings.pref_center_margin) { SettingsChipRow(SYMR.strings.pref_center_margin) {
ReaderPreferences.CenterMarginTypes.mapIndexed { index, it -> ReaderPreferences.CenterMarginTypes.mapIndexed { index, it ->
@ -185,7 +198,7 @@ private fun ColumnScope.PagerViewerSettings(screenModel: ReaderSettingsScreenMod
} }
@Composable @Composable
private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenModel) { private fun WebtoonViewerSettings(screenModel: ReaderSettingsScreenModel) {
val numberFormat = remember { NumberFormat.getPercentInstance() } val numberFormat = remember { NumberFormat.getPercentInstance() }
HeadingItem(MR.strings.webtoon_viewer) HeadingItem(MR.strings.webtoon_viewer)
@ -279,7 +292,7 @@ private fun ColumnScope.WebtoonViewerSettings(screenModel: ReaderSettingsScreenM
// SY --> // SY -->
@Composable @Composable
private fun ColumnScope.WebtoonWithGapsViewerSettings(screenModel: ReaderSettingsScreenModel) { private fun WebtoonWithGapsViewerSettings(screenModel: ReaderSettingsScreenModel) {
HeadingItem(MR.strings.vertical_plus_viewer) HeadingItem(MR.strings.vertical_plus_viewer)
CheckboxItem( CheckboxItem(
@ -290,7 +303,7 @@ private fun ColumnScope.WebtoonWithGapsViewerSettings(screenModel: ReaderSetting
// SY <-- // SY <--
@Composable @Composable
private fun ColumnScope.TapZonesItems( private fun TapZonesItems(
selected: Int, selected: Int,
onSelect: (Int) -> Unit, onSelect: (Int) -> Unit,
invertMode: ReaderPreferences.TappingInvertMode, invertMode: ReaderPreferences.TappingInvertMode,

View file

@ -54,6 +54,8 @@ class ReaderPreferences(
fun webtoonDoubleTapZoomEnabled() = preferenceStore.getBoolean("pref_enable_double_tap_zoom_webtoon", true) fun webtoonDoubleTapZoomEnabled() = preferenceStore.getBoolean("pref_enable_double_tap_zoom_webtoon", true)
// KMK --> // KMK -->
fun pagedDoubleTapZoomEnabled() = preferenceStore.getBoolean("pref_enable_double_tap_zoom_paged", true)
fun webtoonPinchToZoomEnabled() = preferenceStore.getBoolean("pref_enable_pinch_to_zoom_webtoon", true) fun webtoonPinchToZoomEnabled() = preferenceStore.getBoolean("pref_enable_pinch_to_zoom_webtoon", true)
// KMK <-- // KMK <--
@ -87,6 +89,10 @@ class ReaderPreferences(
fun webtoonDisableZoomOut() = preferenceStore.getBoolean("webtoon_disable_zoom_out", false) fun webtoonDisableZoomOut() = preferenceStore.getBoolean("webtoon_disable_zoom_out", false)
// KMK -->
fun pagedDisableZoomIn() = preferenceStore.getBoolean("paged_disable_zoom_in", false)
// KMK <--
// endregion // endregion
// region Split two page spread // region Split two page spread

View file

@ -292,7 +292,17 @@ open class ReaderPageImageView @JvmOverloads constructor(
private fun SubsamplingScaleImageView.setupZoom(config: Config?) { private fun SubsamplingScaleImageView.setupZoom(config: Config?) {
// 5x zoom // 5x zoom
maxScale = scale * MAX_ZOOM_SCALE maxScale = scale * MAX_ZOOM_SCALE
setDoubleTapZoomScale(scale * 2) // KMK -->
if (config?.disableZoomIn == true) {
isZoomEnabled = false
} else {
if (config?.doubleTapZoom == false) {
setDoubleTapZoomScale(scale)
} else {
// KMK <--
setDoubleTapZoomScale(scale * 2)
}
}
when (config?.zoomStartPosition) { when (config?.zoomStartPosition) {
ZoomStartPosition.LEFT -> setScaleAndCenter(scale, PointF(0F, 0F)) ZoomStartPosition.LEFT -> setScaleAndCenter(scale, PointF(0F, 0F))
@ -453,6 +463,10 @@ open class ReaderPageImageView @JvmOverloads constructor(
val cropBorders: Boolean = false, val cropBorders: Boolean = false,
val zoomStartPosition: ZoomStartPosition = ZoomStartPosition.CENTER, val zoomStartPosition: ZoomStartPosition = ZoomStartPosition.CENTER,
val landscapeZoom: Boolean = false, val landscapeZoom: Boolean = false,
// KMK -->
val disableZoomIn: Boolean = false,
val doubleTapZoom: Boolean = true,
// KMK <--
) )
enum class ZoomStartPosition { enum class ZoomStartPosition {

View file

@ -49,6 +49,14 @@ class PagerConfig(
var landscapeZoom = false var landscapeZoom = false
private set private set
// KMK -->
var disableZoomIn = false
private set
var doubleTapZoom = true
private set
// KMK <--
// SY --> // SY -->
var usePageTransitions = false var usePageTransitions = false
@ -71,7 +79,6 @@ class PagerConfig(
var pageCanvasColor = Color.WHITE var pageCanvasColor = Color.WHITE
var centerMarginType = CenterMarginType.NONE var centerMarginType = CenterMarginType.NONE
// SY <-- // SY <--
init { init {
@ -116,6 +123,7 @@ class PagerConfig(
.drop(1) .drop(1)
.onEach { navigationModeChangedListener?.invoke() } .onEach { navigationModeChangedListener?.invoke() }
.launchIn(scope) .launchIn(scope)
// KMK --> // KMK -->
readerPreferences.smallerTapZone().changes() readerPreferences.smallerTapZone().changes()
.drop(1) .drop(1)
@ -147,6 +155,19 @@ class PagerConfig(
{ imagePropertyChangedListener?.invoke() }, { imagePropertyChangedListener?.invoke() },
) )
// KMK -->
readerPreferences.pagedDisableZoomIn()
.register(
{ disableZoomIn = it },
{ imagePropertyChangedListener?.invoke() },
)
readerPreferences.pagedDoubleTapZoomEnabled()
.register(
{ doubleTapZoom = it },
{ imagePropertyChangedListener?.invoke() },
)
// KMK <--
// SY --> // SY -->
readerPreferences.pageTransitionsPager() readerPreferences.pageTransitionsPager()
.register({ usePageTransitions = it }, { imagePropertyChangedListener?.invoke() }) .register({ usePageTransitions = it }, { imagePropertyChangedListener?.invoke() })

View file

@ -216,6 +216,10 @@ class PagerPageHolder(
cropBorders = viewer.config.imageCropBorders, cropBorders = viewer.config.imageCropBorders,
zoomStartPosition = viewer.config.imageZoomType, zoomStartPosition = viewer.config.imageZoomType,
landscapeZoom = viewer.config.landscapeZoom, landscapeZoom = viewer.config.landscapeZoom,
// KMK -->
disableZoomIn = viewer.config.disableZoomIn,
doubleTapZoom = viewer.config.doubleTapZoom,
// KMK <--
), ),
) )
if (!isAnimated) { if (!isAnimated) {

View file

@ -26,6 +26,7 @@
<string name="pref_viewer_nav_smaller_tap_zone">Smaller tap zones</string> <string name="pref_viewer_nav_smaller_tap_zone">Smaller tap zones</string>
<string name="error_opening_folder">Failed to open folder</string> <string name="error_opening_folder">Failed to open folder</string>
<string name="pref_pinch_to_zoom">Pinch to zoom</string> <string name="pref_pinch_to_zoom">Pinch to zoom</string>
<string name="pref_paged_disable_zoom_in">Disable zoom in</string>
<!-- Preferences --> <!-- Preferences -->
<!-- Appearance section --> <!-- Appearance section -->