From e22b98b476c9abea7d3c45a6a420d4a3297ffbb5 Mon Sep 17 00:00:00 2001 From: vianh Date: Fri, 7 Oct 2022 11:13:30 +0700 Subject: [PATCH 1/5] Support zoom for webtoon mode --- .../reader/ui/pager/webtoon/ScalingFrame.kt | 196 ++++++++++++++++++ .../res/layout/fragment_reader_webtoon.xml | 15 +- 2 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/ScalingFrame.kt diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/ScalingFrame.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/ScalingFrame.kt new file mode 100644 index 000000000..b7ec2ea45 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/ScalingFrame.kt @@ -0,0 +1,196 @@ +package org.koitharu.kotatsu.reader.ui.pager.webtoon + +import android.animation.ObjectAnimator +import android.content.Context +import android.graphics.Matrix +import android.graphics.Rect +import android.graphics.RectF +import android.util.AttributeSet +import android.view.GestureDetector +import android.view.MotionEvent +import android.view.ScaleGestureDetector +import android.view.animation.AccelerateDecelerateInterpolator +import android.widget.FrameLayout +import android.widget.OverScroller +import androidx.core.view.GestureDetectorCompat + +private const val TAG = "ScalingFrame" +private const val MAX_SCALE = 2.5f +private const val MIN_SCALE = 0.5f + +class ScalingFrame @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyles: Int = 0 +): FrameLayout(context, attrs, defStyles), ScaleGestureDetector.OnScaleGestureListener { + private val targetChild by lazy(LazyThreadSafetyMode.NONE) { getChildAt(0) } + + private val scaleDetector = ScaleGestureDetector(context, this) + private val gestureDetector = GestureDetectorCompat(context, GestureListener()) + private val overScroller = OverScroller(context, AccelerateDecelerateInterpolator()) + private val transformMatrix = Matrix() + private val matrixValues = FloatArray(9) + private val scale + get() = matrixValues[Matrix.MSCALE_X] + private val transX + get() = halfWidth*(scale - 1f) + matrixValues[Matrix.MTRANS_X] + private val transY + get() = halfHeight*(scale - 1f) + matrixValues[Matrix.MTRANS_Y] + private var halfWidth = 0f + private var halfHeight = 0f + private val translateBounds = RectF() + private val targetTouchRect = Rect() + + init { + syncMatrixValues() + } + + override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { + ev ?: return super.dispatchTouchEvent(ev) + if (ev.action == MotionEvent.ACTION_DOWN && overScroller.computeScrollOffset()) { + overScroller.forceFinished(true) + } + + gestureDetector.onTouchEvent(ev) + scaleDetector.onTouchEvent(ev) + + // Offset event to inside the child view + if (scale < 1) { + targetChild.getHitRect(targetTouchRect) + if (!targetTouchRect.contains(ev.x.toInt(), ev.y.toInt())) { + ev.offsetLocation(halfWidth - ev.x - targetChild.width/4, 0f) + } + } + + return super.dispatchTouchEvent(ev) + } + + override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { + return super.onInterceptTouchEvent(ev) || scaleDetector.isInProgress + } + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + halfWidth = measuredWidth / 2f + halfHeight = measuredHeight / 2f + } + + private fun invalidateRecycler() { + adjustBounds() + targetChild.run { + scaleX = scale + scaleY = scale + translationX = transX + translationY = transY + } + + val newHeight = if (scale < 1f) (height / scale).toInt() else height + if (newHeight != targetChild.height) { + targetChild.layoutParams.height = newHeight + targetChild.requestLayout() + } + + } + + private fun syncMatrixValues() { + transformMatrix.getValues(matrixValues) + } + + private fun adjustBounds() { + syncMatrixValues() + val dx = when { + transX < translateBounds.left -> translateBounds.left - transX + transX > translateBounds.right -> translateBounds.right - transX + else -> 0f + } + + val dy = when { + transY < translateBounds.top -> translateBounds.top - transY + transY > translateBounds.bottom -> translateBounds.bottom - transY + else -> 0f + } + + transformMatrix.postTranslate(dx, dy) + syncMatrixValues() + } + + private fun scaleChild(newScale: Float, focusX: Float, focusY: Float) { + val factor = newScale / scale + if (newScale > 1) { + translateBounds.set( + halfWidth * (1 - newScale), + halfHeight * (1 - newScale), + halfWidth * (newScale - 1), + halfHeight * (newScale - 1) + ) + } else { + translateBounds.set( + 0f, + halfHeight - halfHeight / newScale, + 0f, + halfHeight - halfHeight / newScale + ) + } + transformMatrix.postScale(factor, factor, focusX, focusY) + invalidateRecycler() + } + + + override fun onScale(detector: ScaleGestureDetector): Boolean { + val newScale = (scale * detector.scaleFactor).coerceIn(MIN_SCALE, MAX_SCALE) + scaleChild(newScale, halfWidth, halfHeight) + return true + } + + override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true + + override fun onScaleEnd(p0: ScaleGestureDetector) = Unit + + + private inner class GestureListener(): GestureDetector.SimpleOnGestureListener(), Runnable { + override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { + if (scale <= 1f) return false + transformMatrix.postTranslate(-distanceX, -distanceY) + invalidateRecycler() + return true + } + + override fun onDoubleTap(e: MotionEvent): Boolean { + val newScale = if (scale != 1f) 1f else MAX_SCALE + ObjectAnimator.ofFloat(scale, newScale).run { + interpolator = AccelerateDecelerateInterpolator() + duration = 300 + addUpdateListener { + scaleChild(it.animatedValue as Float, e.x, e.y) + } + start() + } + return true + } + + override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { + if (scale <= 1) return false + + overScroller.fling( + transX.toInt(), + transY.toInt(), + velocityX.toInt(), + velocityY.toInt(), + translateBounds.left.toInt(), + translateBounds.right.toInt(), + translateBounds.top.toInt(), + translateBounds.bottom.toInt() + ) + postOnAnimation(this) + return true + } + + override fun run() { + if (overScroller.computeScrollOffset()) { + transformMatrix.postTranslate(overScroller.currX - transX, overScroller.currY - transY) + invalidateRecycler() + postOnAnimation(this) + } + } + } +} diff --git a/app/src/main/res/layout/fragment_reader_webtoon.xml b/app/src/main/res/layout/fragment_reader_webtoon.xml index 2a3020690..5a09e8fdc 100644 --- a/app/src/main/res/layout/fragment_reader_webtoon.xml +++ b/app/src/main/res/layout/fragment_reader_webtoon.xml @@ -1,9 +1,14 @@ - \ No newline at end of file + android:layout_height="match_parent"> + + From d0338a604a00b694a928f35d9088c369c7fea689 Mon Sep 17 00:00:00 2001 From: vianh Date: Fri, 7 Oct 2022 16:15:53 +0700 Subject: [PATCH 2/5] Minor adjustment for webtoon scale --- ...ScalingFrame.kt => WebtoonScalingFrame.kt} | 27 +++++++++---------- .../res/layout/fragment_reader_webtoon.xml | 4 +-- 2 files changed, 14 insertions(+), 17 deletions(-) rename app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/{ScalingFrame.kt => WebtoonScalingFrame.kt} (91%) diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/ScalingFrame.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/ScalingFrame.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt index b7ec2ea45..517884e63 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/ScalingFrame.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt @@ -2,9 +2,7 @@ package org.koitharu.kotatsu.reader.ui.pager.webtoon import android.animation.ObjectAnimator import android.content.Context -import android.graphics.Matrix -import android.graphics.Rect -import android.graphics.RectF +import android.graphics.* import android.util.AttributeSet import android.view.GestureDetector import android.view.MotionEvent @@ -14,11 +12,10 @@ import android.widget.FrameLayout import android.widget.OverScroller import androidx.core.view.GestureDetectorCompat -private const val TAG = "ScalingFrame" private const val MAX_SCALE = 2.5f private const val MIN_SCALE = 0.5f -class ScalingFrame @JvmOverloads constructor( +class WebtoonScalingFrame @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyles: Int = 0 @@ -39,7 +36,7 @@ class ScalingFrame @JvmOverloads constructor( private var halfWidth = 0f private var halfHeight = 0f private val translateBounds = RectF() - private val targetTouchRect = Rect() + private val targetHitRect = Rect() init { syncMatrixValues() @@ -55,11 +52,8 @@ class ScalingFrame @JvmOverloads constructor( scaleDetector.onTouchEvent(ev) // Offset event to inside the child view - if (scale < 1) { - targetChild.getHitRect(targetTouchRect) - if (!targetTouchRect.contains(ev.x.toInt(), ev.y.toInt())) { - ev.offsetLocation(halfWidth - ev.x - targetChild.width/4, 0f) - } + if (scale < 1 && !targetHitRect.contains(ev.x.toInt(), ev.y.toInt())) { + ev.offsetLocation(halfWidth - ev.x + targetHitRect.width()/3, 0f) } return super.dispatchTouchEvent(ev) @@ -75,7 +69,7 @@ class ScalingFrame @JvmOverloads constructor( halfHeight = measuredHeight / 2f } - private fun invalidateRecycler() { + private fun invalidateTarget() { adjustBounds() targetChild.run { scaleX = scale @@ -90,6 +84,9 @@ class ScalingFrame @JvmOverloads constructor( targetChild.requestLayout() } + if (scale < 1) { + targetChild.getHitRect(targetHitRect) + } } private fun syncMatrixValues() { @@ -132,7 +129,7 @@ class ScalingFrame @JvmOverloads constructor( ) } transformMatrix.postScale(factor, factor, focusX, focusY) - invalidateRecycler() + invalidateTarget() } @@ -151,7 +148,7 @@ class ScalingFrame @JvmOverloads constructor( override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean { if (scale <= 1f) return false transformMatrix.postTranslate(-distanceX, -distanceY) - invalidateRecycler() + invalidateTarget() return true } @@ -188,7 +185,7 @@ class ScalingFrame @JvmOverloads constructor( override fun run() { if (overScroller.computeScrollOffset()) { transformMatrix.postTranslate(overScroller.currX - transX, overScroller.currY - transY) - invalidateRecycler() + invalidateTarget() postOnAnimation(this) } } diff --git a/app/src/main/res/layout/fragment_reader_webtoon.xml b/app/src/main/res/layout/fragment_reader_webtoon.xml index 5a09e8fdc..63c406385 100644 --- a/app/src/main/res/layout/fragment_reader_webtoon.xml +++ b/app/src/main/res/layout/fragment_reader_webtoon.xml @@ -1,5 +1,5 @@ - - + From eae370e41c6a424585136289b70329a311f1b9c9 Mon Sep 17 00:00:00 2001 From: vianh Date: Fri, 7 Oct 2022 22:17:53 +0700 Subject: [PATCH 3/5] Adjust zoom focus point --- .../ui/pager/webtoon/WebtoonScalingFrame.kt | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt index 517884e63..580112344 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt @@ -30,13 +30,14 @@ class WebtoonScalingFrame @JvmOverloads constructor( private val scale get() = matrixValues[Matrix.MSCALE_X] private val transX - get() = halfWidth*(scale - 1f) + matrixValues[Matrix.MTRANS_X] + get() = halfWidth * (scale - 1f) + matrixValues[Matrix.MTRANS_X] private val transY - get() = halfHeight*(scale - 1f) + matrixValues[Matrix.MTRANS_Y] + get() = halfHeight * (scale - 1f) + matrixValues[Matrix.MTRANS_Y] private var halfWidth = 0f private var halfHeight = 0f private val translateBounds = RectF() private val targetHitRect = Rect() + private var pendingScroll = 0 init { syncMatrixValues() @@ -53,9 +54,13 @@ class WebtoonScalingFrame @JvmOverloads constructor( // Offset event to inside the child view if (scale < 1 && !targetHitRect.contains(ev.x.toInt(), ev.y.toInt())) { - ev.offsetLocation(halfWidth - ev.x + targetHitRect.width()/3, 0f) + ev.offsetLocation(halfWidth - ev.x + targetHitRect.width() / 3, 0f) } + // Send action cancel to avoid recycler jump when scale end + if (scaleDetector.isInProgress) { + ev.action = MotionEvent.ACTION_CANCEL + } return super.dispatchTouchEvent(ev) } @@ -86,6 +91,8 @@ class WebtoonScalingFrame @JvmOverloads constructor( if (scale < 1) { targetChild.getHitRect(targetHitRect) + targetChild.scrollBy(0, pendingScroll) + pendingScroll = 0 } } @@ -107,6 +114,7 @@ class WebtoonScalingFrame @JvmOverloads constructor( else -> 0f } + pendingScroll = dy.toInt() transformMatrix.postTranslate(dx, dy) syncMatrixValues() } @@ -135,13 +143,15 @@ class WebtoonScalingFrame @JvmOverloads constructor( override fun onScale(detector: ScaleGestureDetector): Boolean { val newScale = (scale * detector.scaleFactor).coerceIn(MIN_SCALE, MAX_SCALE) - scaleChild(newScale, halfWidth, halfHeight) + scaleChild(newScale, detector.focusX, detector.focusY) return true } override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true - override fun onScaleEnd(p0: ScaleGestureDetector) = Unit + override fun onScaleEnd(p0: ScaleGestureDetector) { + pendingScroll = 0 + } private inner class GestureListener(): GestureDetector.SimpleOnGestureListener(), Runnable { @@ -153,7 +163,7 @@ class WebtoonScalingFrame @JvmOverloads constructor( } override fun onDoubleTap(e: MotionEvent): Boolean { - val newScale = if (scale != 1f) 1f else MAX_SCALE + val newScale = if (scale != 1f) 1f else MAX_SCALE * 0.8f ObjectAnimator.ofFloat(scale, newScale).run { interpolator = AccelerateDecelerateInterpolator() duration = 300 From 2925900214f7c2e218887cd8c9486df8eafe2c0b Mon Sep 17 00:00:00 2001 From: vianh Date: Tue, 11 Oct 2022 18:13:46 +0700 Subject: [PATCH 4/5] Add disable webtoon zoom setting --- .../koitharu/kotatsu/core/prefs/AppSettings.kt | 4 ++++ .../kotatsu/reader/ui/config/ReaderSettings.kt | 5 ++++- .../ui/pager/webtoon/WebtoonReaderFragment.kt | 2 ++ .../ui/pager/webtoon/WebtoonScalingFrame.kt | 17 ++++++++++++----- app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/pref_reader.xml | 5 +++++ 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt index 19bfbb066..20a29269b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -218,6 +218,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { get() = prefs.getEnumValue(KEY_LOCAL_LIST_ORDER, SortOrder.NEWEST) set(value) = prefs.edit { putEnumValue(KEY_LOCAL_LIST_ORDER, value) } + val isWebtoonZoomEnable: Boolean + get() = prefs.getBoolean(KEY_WEBTOON_ZOOM, true) + fun isPagesPreloadAllowed(cm: ConnectivityManager): Boolean { return when (prefs.getString(KEY_PAGES_PRELOAD, null)?.toIntOrNull()) { NETWORK_ALWAYS -> true @@ -337,6 +340,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { const val KEY_SHORTCUTS = "dynamic_shortcuts" const val KEY_READER_TAPS_LTR = "reader_taps_ltr" const val KEY_LOCAL_LIST_ORDER = "local_order" + const val KEY_WEBTOON_ZOOM = "webtoon_zoom" // About const val KEY_APP_UPDATE = "app_update" diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt index 9619e53df..283bfc661 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt @@ -27,6 +27,9 @@ class ReaderSettings( val isPagesNumbersEnabled: Boolean get() = settings.isPagesNumbersEnabled + val isWebtoonZoomEnable: Boolean + get() = settings.isWebtoonZoomEnable + override fun onInactive() { super.onInactive() settings.unsubscribe(internalObserver) @@ -60,7 +63,7 @@ class ReaderSettings( } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - if (key == AppSettings.KEY_ZOOM_MODE || key == AppSettings.KEY_PAGES_NUMBERS) { + if (key == AppSettings.KEY_ZOOM_MODE || key == AppSettings.KEY_PAGES_NUMBERS || key == AppSettings.KEY_WEBTOON_ZOOM) { notifyChanged() } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt index e91f1467c..c414ffb9c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt @@ -35,6 +35,8 @@ class WebtoonReaderFragment : BaseReader() { adapter = webtoonAdapter addOnPageScrollListener(PageScrollListener()) } + + viewModel.readerSettings.observe(viewLifecycleOwner) { binding.frame.isZoomEnable = it.isWebtoonZoomEnable } } override fun onDestroyView() { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt index 580112344..b834ecf1e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonScalingFrame.kt @@ -39,12 +39,23 @@ class WebtoonScalingFrame @JvmOverloads constructor( private val targetHitRect = Rect() private var pendingScroll = 0 + var isZoomEnable = true + set(value) { + field = value + if (scale != 1f) { + scaleChild(1f, halfWidth, halfHeight) + } + } + init { syncMatrixValues() } override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { - ev ?: return super.dispatchTouchEvent(ev) + if (!isZoomEnable || ev == null) { + return super.dispatchTouchEvent(ev) + } + if (ev.action == MotionEvent.ACTION_DOWN && overScroller.computeScrollOffset()) { overScroller.forceFinished(true) } @@ -64,10 +75,6 @@ class WebtoonScalingFrame @JvmOverloads constructor( return super.dispatchTouchEvent(ev) } - override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { - return super.onInterceptTouchEvent(ev) || scaleDetector.isInProgress - } - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) halfWidth = measuredWidth / 2f diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1d9453ba7..068b04c90 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -390,4 +390,5 @@ Discard No space left on device Show page switching slider + Webtoon zoom diff --git a/app/src/main/res/xml/pref_reader.xml b/app/src/main/res/xml/pref_reader.xml index 1842876fa..eedcddc3e 100644 --- a/app/src/main/res/xml/pref_reader.xml +++ b/app/src/main/res/xml/pref_reader.xml @@ -40,6 +40,11 @@ android:key="reader_animation" android:title="@string/pages_animation" /> + + Date: Wed, 12 Oct 2022 12:35:33 +0300 Subject: [PATCH 5/5] Refactor webtoon zoom option --- .../org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt | 6 ++++++ .../koitharu/kotatsu/reader/ui/config/ReaderSettings.kt | 9 +++++---- .../reader/ui/pager/webtoon/WebtoonReaderFragment.kt | 4 +++- app/src/main/res/values/strings.xml | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt index ea9abd350..feb64b21b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt @@ -106,6 +106,12 @@ class ReaderViewModel @AssistedInject constructor( valueProducer = { isReaderBarEnabled }, ) + val isWebtoonZoomEnabled = settings.observeAsLiveData( + context = viewModelScope.coroutineContext + Dispatchers.Default, + key = AppSettings.KEY_WEBTOON_ZOOM, + valueProducer = { isWebtoonZoomEnable }, + ) + val readerSettings = ReaderSettings( parentScope = viewModelScope, settings = settings, diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt index 283bfc661..03a6c49e9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/config/ReaderSettings.kt @@ -2,9 +2,13 @@ package org.koitharu.kotatsu.reader.ui.config import android.content.SharedPreferences import androidx.lifecycle.MediatorLiveData -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.FlowCollector import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.koitharu.kotatsu.core.model.ZoomMode import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.reader.domain.ReaderColorFilter @@ -27,9 +31,6 @@ class ReaderSettings( val isPagesNumbersEnabled: Boolean get() = settings.isPagesNumbersEnabled - val isWebtoonZoomEnable: Boolean - get() = settings.isWebtoonZoomEnable - override fun onInactive() { super.onInactive() settings.unsubscribe(internalObserver) diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt index c414ffb9c..79a4e8927 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt @@ -36,7 +36,9 @@ class WebtoonReaderFragment : BaseReader() { addOnPageScrollListener(PageScrollListener()) } - viewModel.readerSettings.observe(viewLifecycleOwner) { binding.frame.isZoomEnable = it.isWebtoonZoomEnable } + viewModel.isWebtoonZoomEnabled.observe(viewLifecycleOwner) { + binding.frame.isZoomEnable = it + } } override fun onDestroyView() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 068b04c90..c1e429c11 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -391,4 +391,5 @@ No space left on device Show page switching slider Webtoon zoom + Allow zoom in/zoom out gesture in webtoon mode (beta)