mirror of
https://github.com/null2264/yokai.git
synced 2025-07-16 22:06:54 +00:00
feat: Toggle for double tap to zoom
Closes GH-161
This commit is contained in:
parent
c7eed6d2d3
commit
7fc73ddcdc
10 changed files with 60 additions and 25 deletions
|
@ -11,6 +11,7 @@
|
||||||
-->
|
-->
|
||||||
## Additions
|
## Additions
|
||||||
- Add toggle to enable/disable chapter swipe action(s)
|
- Add toggle to enable/disable chapter swipe action(s)
|
||||||
|
- Add toggle to enable/disable webtoon double tap to zoom
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
- Fixed chapter number parsing (@Naputt1)
|
- Fixed chapter number parsing (@Naputt1)
|
||||||
|
|
|
@ -7,15 +7,14 @@ import android.util.AttributeSet
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import yokai.i18n.MR
|
|
||||||
import yokai.util.lang.getString
|
|
||||||
import dev.icerock.moko.resources.compose.stringResource
|
|
||||||
import eu.kanade.tachiyomi.databinding.ReaderPagedLayoutBinding
|
import eu.kanade.tachiyomi.databinding.ReaderPagedLayoutBinding
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import eu.kanade.tachiyomi.util.bindToPreference
|
import eu.kanade.tachiyomi.util.bindToPreference
|
||||||
import eu.kanade.tachiyomi.util.lang.addBetaTag
|
import eu.kanade.tachiyomi.util.lang.addBetaTag
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
|
import eu.kanade.tachiyomi.widget.BaseReaderSettingsView
|
||||||
|
import yokai.i18n.MR
|
||||||
|
import yokai.util.lang.getString
|
||||||
|
|
||||||
class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||||
BaseReaderSettingsView<ReaderPagedLayoutBinding>(context, attrs) {
|
BaseReaderSettingsView<ReaderPagedLayoutBinding>(context, attrs) {
|
||||||
|
@ -61,6 +60,7 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||||
R.array.webtoon_side_padding_values,
|
R.array.webtoon_side_padding_values,
|
||||||
)
|
)
|
||||||
webtoonEnableZoomOut.bindToPreference(preferences.webtoonEnableZoomOut())
|
webtoonEnableZoomOut.bindToPreference(preferences.webtoonEnableZoomOut())
|
||||||
|
webtoonEnableDoubleTapZoom.bindToPreference(readerPreferences.webtoonDoubleTapZoomEnabled())
|
||||||
webtoonNav.bindToPreference(preferences.navigationModeWebtoon())
|
webtoonNav.bindToPreference(preferences.navigationModeWebtoon())
|
||||||
webtoonInvert.bindToPreference(preferences.webtoonNavInverted())
|
webtoonInvert.bindToPreference(preferences.webtoonNavInverted())
|
||||||
webtoonPageLayout.bindToPreference(preferences.webtoonPageLayout())
|
webtoonPageLayout.bindToPreference(preferences.webtoonPageLayout())
|
||||||
|
@ -94,6 +94,7 @@ class ReaderPagedView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||||
binding.cropBordersWebtoon,
|
binding.cropBordersWebtoon,
|
||||||
binding.webtoonSidePadding,
|
binding.webtoonSidePadding,
|
||||||
binding.webtoonEnableZoomOut,
|
binding.webtoonEnableZoomOut,
|
||||||
|
binding.webtoonEnableDoubleTapZoom,
|
||||||
binding.webtoonNav,
|
binding.webtoonNav,
|
||||||
binding.webtoonInvert,
|
binding.webtoonInvert,
|
||||||
binding.webtoonPageLayout,
|
binding.webtoonPageLayout,
|
||||||
|
|
|
@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
import yokai.domain.ui.settings.ReaderPreferences
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration used by webtoon viewers.
|
* Configuration used by webtoon viewers.
|
||||||
|
@ -23,6 +24,7 @@ import uy.kohesive.injekt.api.get
|
||||||
class WebtoonConfig(
|
class WebtoonConfig(
|
||||||
scope: CoroutineScope,
|
scope: CoroutineScope,
|
||||||
preferences: PreferencesHelper = Injekt.get(),
|
preferences: PreferencesHelper = Injekt.get(),
|
||||||
|
readerPreferences: ReaderPreferences = Injekt.get(),
|
||||||
) : ViewerConfig(preferences, scope) {
|
) : ViewerConfig(preferences, scope) {
|
||||||
|
|
||||||
var webtoonCropBorders = false
|
var webtoonCropBorders = false
|
||||||
|
@ -39,6 +41,11 @@ class WebtoonConfig(
|
||||||
|
|
||||||
var zoomPropertyChangedListener: ((Boolean) -> Unit)? = null
|
var zoomPropertyChangedListener: ((Boolean) -> Unit)? = null
|
||||||
|
|
||||||
|
var doubleTapZoom = true
|
||||||
|
private set
|
||||||
|
|
||||||
|
var doubleTapZoomChangedListener: ((Boolean) -> Unit)? = null
|
||||||
|
|
||||||
var splitPages = preferences.webtoonPageLayout().get() == PageLayout.SPLIT_PAGES.webtoonValue
|
var splitPages = preferences.webtoonPageLayout().get() == PageLayout.SPLIT_PAGES.webtoonValue
|
||||||
|
|
||||||
var invertDoublePages = false
|
var invertDoublePages = false
|
||||||
|
@ -79,6 +86,9 @@ class WebtoonConfig(
|
||||||
preferences.webtoonEnableZoomOut()
|
preferences.webtoonEnableZoomOut()
|
||||||
.register({ enableZoomOut = it }, { zoomPropertyChangedListener?.invoke(it) })
|
.register({ enableZoomOut = it }, { zoomPropertyChangedListener?.invoke(it) })
|
||||||
|
|
||||||
|
readerPreferences.webtoonDoubleTapZoomEnabled()
|
||||||
|
.register({ doubleTapZoom = it }, { doubleTapZoomChangedListener?.invoke(it) })
|
||||||
|
|
||||||
preferences.webtoonPageLayout()
|
preferences.webtoonPageLayout()
|
||||||
.register(
|
.register(
|
||||||
{ splitPages = it == PageLayout.SPLIT_PAGES.webtoonValue },
|
{ splitPages = it == PageLayout.SPLIT_PAGES.webtoonValue },
|
||||||
|
|
|
@ -31,6 +31,13 @@ class WebtoonFrame(context: Context) : FrameLayout(context) {
|
||||||
recycler?.canZoomOut = value
|
recycler?.canZoomOut = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var doubleTapZoom = true
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
recycler?.doubleTapZoom = value
|
||||||
|
scaleDetector.isQuickScaleEnabled = value
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recycler view added in this frame.
|
* Recycler view added in this frame.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -40,6 +40,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f)
|
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var doubleTapZoom = true
|
||||||
|
|
||||||
private val minRate
|
private val minRate
|
||||||
get() = if (canZoomOut) MIN_RATE else DEFAULT_RATE
|
get() = if (canZoomOut) MIN_RATE else DEFAULT_RATE
|
||||||
|
@ -231,7 +232,7 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onDoubleTapConfirmed(ev: MotionEvent) {
|
fun onDoubleTapConfirmed(ev: MotionEvent) {
|
||||||
if (!isZooming) {
|
if (!isZooming && doubleTapZoom) {
|
||||||
if (scaleX != DEFAULT_RATE) {
|
if (scaleX != DEFAULT_RATE) {
|
||||||
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f)
|
zoom(currentScale, DEFAULT_RATE, x, 0f, y, 0f)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -19,11 +19,11 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import kotlin.math.max
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of a [BaseViewer] to display pages with a [RecyclerView].
|
* Implementation of a [BaseViewer] to display pages with a [RecyclerView].
|
||||||
|
@ -139,6 +139,10 @@ class WebtoonViewer(val activity: ReaderActivity, val hasMargins: Boolean = fals
|
||||||
frame.enableZoomOut = it
|
frame.enableZoomOut = it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.doubleTapZoomChangedListener = {
|
||||||
|
frame.doubleTapZoom = it
|
||||||
|
}
|
||||||
|
|
||||||
config.navigationModeChangedListener = {
|
config.navigationModeChangedListener = {
|
||||||
val showOnStart = config.navigationOverlayForNewUser
|
val showOnStart = config.navigationOverlayForNewUser
|
||||||
activity.binding.navigationOverlay.setNavigation(config.navigator, showOnStart)
|
activity.binding.navigationOverlay.setNavigation(config.navigator, showOnStart)
|
||||||
|
|
|
@ -4,9 +4,6 @@ import android.content.ComponentName
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import yokai.i18n.MR
|
|
||||||
import yokai.util.lang.getString
|
|
||||||
import dev.icerock.moko.resources.compose.stringResource
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
||||||
import eu.kanade.tachiyomi.data.preference.changesIn
|
import eu.kanade.tachiyomi.data.preference.changesIn
|
||||||
import eu.kanade.tachiyomi.ui.reader.settings.OrientationType
|
import eu.kanade.tachiyomi.ui.reader.settings.OrientationType
|
||||||
|
@ -25,9 +22,7 @@ import eu.kanade.tachiyomi.ui.setting.multiSelectListPreferenceMat
|
||||||
import eu.kanade.tachiyomi.ui.setting.onClick
|
import eu.kanade.tachiyomi.ui.setting.onClick
|
||||||
import eu.kanade.tachiyomi.ui.setting.preference
|
import eu.kanade.tachiyomi.ui.setting.preference
|
||||||
import eu.kanade.tachiyomi.ui.setting.preferenceCategory
|
import eu.kanade.tachiyomi.ui.setting.preferenceCategory
|
||||||
import eu.kanade.tachiyomi.ui.setting.summaryMRes as summaryRes
|
|
||||||
import eu.kanade.tachiyomi.ui.setting.switchPreference
|
import eu.kanade.tachiyomi.ui.setting.switchPreference
|
||||||
import eu.kanade.tachiyomi.ui.setting.titleMRes as titleRes
|
|
||||||
import eu.kanade.tachiyomi.util.lang.addBetaTag
|
import eu.kanade.tachiyomi.util.lang.addBetaTag
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
import eu.kanade.tachiyomi.util.system.isTablet
|
import eu.kanade.tachiyomi.util.system.isTablet
|
||||||
|
@ -36,7 +31,11 @@ import uy.kohesive.injekt.injectLazy
|
||||||
import yokai.domain.ui.settings.ReaderPreferences
|
import yokai.domain.ui.settings.ReaderPreferences
|
||||||
import yokai.domain.ui.settings.ReaderPreferences.CutoutBehaviour
|
import yokai.domain.ui.settings.ReaderPreferences.CutoutBehaviour
|
||||||
import yokai.domain.ui.settings.ReaderPreferences.LandscapeCutoutBehaviour
|
import yokai.domain.ui.settings.ReaderPreferences.LandscapeCutoutBehaviour
|
||||||
|
import yokai.i18n.MR
|
||||||
|
import yokai.util.lang.getString
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||||
|
import eu.kanade.tachiyomi.ui.setting.summaryMRes as summaryRes
|
||||||
|
import eu.kanade.tachiyomi.ui.setting.titleMRes as titleRes
|
||||||
|
|
||||||
class SettingsReaderController : SettingsLegacyController() {
|
class SettingsReaderController : SettingsLegacyController() {
|
||||||
|
|
||||||
|
@ -375,15 +374,18 @@ class SettingsReaderController : SettingsLegacyController() {
|
||||||
}
|
}
|
||||||
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
key = Keys.webtoonInvertDoublePages
|
bindTo(preferences.webtoonInvertDoublePages())
|
||||||
titleRes = MR.strings.invert_double_pages
|
titleRes = MR.strings.invert_double_pages
|
||||||
defaultValue = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switchPreference {
|
switchPreference {
|
||||||
key = Keys.webtoonEnableZoomOut
|
bindTo(preferences.webtoonEnableZoomOut())
|
||||||
titleRes = MR.strings.enable_zoom_out
|
titleRes = MR.strings.enable_zoom_out
|
||||||
defaultValue = false
|
}
|
||||||
|
|
||||||
|
switchPreference {
|
||||||
|
bindTo(readerPreferences.webtoonDoubleTapZoomEnabled())
|
||||||
|
titleRes = MR.strings.pref_double_tap_zoom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
preferenceCategory {
|
preferenceCategory {
|
||||||
|
|
|
@ -43,4 +43,6 @@ class ReaderPreferences(private val preferenceStore: PreferenceStore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun webtoonDoubleTapZoomEnabled() = preferenceStore.getBoolean("pref_enable_double_tap_zoom_webtoon", true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPagedView xmlns:android="http://schemas.android.com/apk/res/android"
|
<eu.kanade.tachiyomi.ui.reader.settings.ReaderPagedView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/filter_bottom_sheet"
|
android:id="@+id/filter_bottom_sheet"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -153,8 +152,15 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:text="@string/enable_zoom_out"
|
android:text="@string/enable_zoom_out"
|
||||||
android:textColor="?attr/colorOnBackground"
|
android:textColor="?attr/colorOnBackground" />
|
||||||
app:layout_constraintTop_toBottomOf="@id/webtoon_side_padding" />
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/webtoon_enable_double_tap_zoom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/pref_double_tap_zoom"
|
||||||
|
android:textColor="?attr/colorOnBackground" />
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
|
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
|
||||||
android:id="@+id/webtoon_page_layout"
|
android:id="@+id/webtoon_page_layout"
|
||||||
|
|
|
@ -511,6 +511,7 @@
|
||||||
<string name="pref_low">Low</string>
|
<string name="pref_low">Low</string>
|
||||||
<string name="pref_lowest">Lowest</string>
|
<string name="pref_lowest">Lowest</string>
|
||||||
<string name="pref_display_profile">Custom display profile</string>
|
<string name="pref_display_profile">Custom display profile</string>
|
||||||
|
<string name="pref_double_tap_zoom">Double tap to zoom</string>
|
||||||
|
|
||||||
<!-- Manga details -->
|
<!-- Manga details -->
|
||||||
<string name="about_this_">About this %1$s</string>
|
<string name="about_this_">About this %1$s</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue