diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index b3a0d4bfa..7f519af9e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -266,6 +266,10 @@ class ReaderActivity : viewModel.switchMode(mode) } + override fun onDoubleModeChanged(isEnabled: Boolean) { + readerManager.setDoubleReaderMode(isEnabled) + } + private fun onPageSaved(uri: Uri?) { if (uri != null) { Snackbar.make(viewBinding.container, R.string.page_saved, Snackbar.LENGTH_LONG) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderManager.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderManager.kt index 9e57f626c..b543fc7b1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderManager.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderManager.kt @@ -6,8 +6,10 @@ import androidx.fragment.app.FragmentManager import androidx.fragment.app.commit import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode +import org.koitharu.kotatsu.core.util.ext.findKeyByValue import org.koitharu.kotatsu.reader.ui.pager.BaseReaderFragment import org.koitharu.kotatsu.reader.ui.pager.doublepage.DoubleReaderFragment +import org.koitharu.kotatsu.reader.ui.pager.doublereversed.ReversedDoubleReaderFragment import org.koitharu.kotatsu.reader.ui.pager.reversed.ReversedReaderFragment import org.koitharu.kotatsu.reader.ui.pager.standard.PagerReaderFragment import org.koitharu.kotatsu.reader.ui.pager.vertical.VerticalReaderFragment @@ -23,14 +25,9 @@ class ReaderManager( private val modeMap = EnumMap>>(ReaderMode::class.java) init { - modeMap[ReaderMode.STANDARD] = if (useDoublePages()) { - DoubleReaderFragment::class.java - } else { - PagerReaderFragment::class.java - } - modeMap[ReaderMode.REVERSED] = ReversedReaderFragment::class.java - modeMap[ReaderMode.WEBTOON] = WebtoonReaderFragment::class.java - modeMap[ReaderMode.VERTICAL] = VerticalReaderFragment::class.java + val useDoublePages = container.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + && settings.isReaderDoubleOnLandscape + invalidateTypesMap(useDoublePages) } val currentReader: BaseReaderFragment<*>? @@ -39,7 +36,7 @@ class ReaderManager( val currentMode: ReaderMode? get() { val readerClass = currentReader?.javaClass ?: return null - return modeMap.entries.find { it.value == readerClass }?.key + return modeMap.findKeyByValue(readerClass) } fun replace(newMode: ReaderMode) { @@ -50,13 +47,27 @@ class ReaderManager( } } - private fun useDoublePages() = container.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - && settings.isReaderDoubleOnLandscape + fun setDoubleReaderMode(isEnabled: Boolean) { + val prevMode = currentMode + invalidateTypesMap(isEnabled) + val newMode = currentMode ?: return + if (newMode != prevMode) { + replace(newMode) + } + } - /*fun replace(reader: BaseReaderFragment<*>) { - fragmentManager.commit { - setReorderingAllowed(true) - replace(containerResId, reader) + private fun invalidateTypesMap(useDoublePages: Boolean) { + modeMap[ReaderMode.STANDARD] = if (useDoublePages) { + DoubleReaderFragment::class.java + } else { + PagerReaderFragment::class.java } - }*/ + modeMap[ReaderMode.REVERSED] = if (useDoublePages) { + ReversedDoubleReaderFragment::class.java + } else { + ReversedReaderFragment::class.java + } + modeMap[ReaderMode.WEBTOON] = WebtoonReaderFragment::class.java + modeMap[ReaderMode.VERTICAL] = VerticalReaderFragment::class.java + } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt index 7a13775ec..d969604eb 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt @@ -145,7 +145,7 @@ class ReaderConfigSheet : R.id.switch_double_reader -> { settings.isReaderDoubleOnLandscape = isChecked - findCallback()?.onReaderModeChanged(mode) + findCallback()?.onDoubleModeChanged(isChecked) } } } @@ -165,7 +165,7 @@ class ReaderConfigSheet : R.id.button_vertical -> ReaderMode.VERTICAL else -> return } - viewBinding?.switchDoubleReader?.isEnabled = newMode == ReaderMode.STANDARD + viewBinding?.switchDoubleReader?.isEnabled = newMode == ReaderMode.STANDARD || newMode == ReaderMode.REVERSED if (newMode == mode) { return } @@ -212,6 +212,8 @@ class ReaderConfigSheet : var isAutoScrollEnabled: Boolean fun onReaderModeChanged(mode: ReaderMode) + + fun onDoubleModeChanged(isEnabled: Boolean) } companion object { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt index 1c7e786a9..65f007615 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt @@ -18,7 +18,6 @@ import org.koitharu.kotatsu.core.util.ext.firstVisibleItemPosition import org.koitharu.kotatsu.databinding.FragmentReaderDoubleBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.ReaderState -import org.koitharu.kotatsu.reader.ui.ReaderViewModel import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter import org.koitharu.kotatsu.reader.ui.pager.BaseReaderFragment import org.koitharu.kotatsu.reader.ui.pager.ReaderPage @@ -26,7 +25,7 @@ import javax.inject.Inject import kotlin.math.absoluteValue @AndroidEntryPoint -class DoubleReaderFragment : BaseReaderFragment() { +open class DoubleReaderFragment : BaseReaderFragment() { @Inject lateinit var networkState: NetworkState @@ -51,7 +50,7 @@ class DoubleReaderFragment : BaseReaderFragment() { recyclerLifecycleDispatcher = RecyclerViewLifecycleDispatcher().also { addOnScrollListener(it) } - addOnScrollListener(PageScrollListener(viewModel)) + addOnScrollListener(PageScrollListener()) DoublePageSnapHelper().attachToRecyclerView(this) } } @@ -78,7 +77,7 @@ class DoubleReaderFragment : BaseReaderFragment() { if (position != -1) { position = position.toPagePosition() requireViewBinding().recyclerView.firstVisibleItemPosition = position - viewModel.onCurrentPageChanged(position, position + 1) + notifyPageChanged(position, position + 1) } else { Snackbar.make(requireView(), R.string.not_found_404, Snackbar.LENGTH_SHORT) .show() @@ -132,14 +131,16 @@ class DoubleReaderFragment : BaseReaderFragment() { ) } + protected open fun notifyPageChanged(lowerPos: Int, upperPos: Int) { + viewModel.onCurrentPageChanged(lowerPos, upperPos) + } + private fun getCurrentItem() = (requireViewBinding().recyclerView.layoutManager as LinearLayoutManager) .findFirstCompletelyVisibleItemPosition().toPagePosition() private fun Int.toPagePosition() = this and 1.inv() - private class PageScrollListener( - private val viewModel: ReaderViewModel, - ) : RecyclerView.OnScrollListener() { + private inner class PageScrollListener : RecyclerView.OnScrollListener() { private var firstPos = RecyclerView.NO_POSITION private var lastPos = RecyclerView.NO_POSITION @@ -157,7 +158,7 @@ class DoubleReaderFragment : BaseReaderFragment() { if (newFirstPos != firstPos || newLastPos != lastPos) { firstPos = newFirstPos lastPos = newLastPos - viewModel.onCurrentPageChanged(newFirstPos, newLastPos) + notifyPageChanged(newFirstPos, newLastPos) } } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublereversed/ReversedDoubleReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublereversed/ReversedDoubleReaderFragment.kt new file mode 100644 index 000000000..f1c9d755e --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublereversed/ReversedDoubleReaderFragment.kt @@ -0,0 +1,28 @@ +package org.koitharu.kotatsu.reader.ui.pager.doublereversed + +import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.reader.ui.pager.ReaderPage +import org.koitharu.kotatsu.reader.ui.pager.doublepage.DoubleReaderFragment + +class ReversedDoubleReaderFragment : DoubleReaderFragment() { + + override fun switchPageBy(delta: Int) { + super.switchPageBy(-delta) + } + + override fun switchPageTo(position: Int, smooth: Boolean) { + super.switchPageTo(reversed(position), smooth) + } + + override suspend fun onPagesChanged(pages: List, pendingState: ReaderState?) { + super.onPagesChanged(pages.reversed(), pendingState) + } + + override fun notifyPageChanged(lowerPos: Int, upperPos: Int) { + viewModel.onCurrentPageChanged(reversed(upperPos), reversed(lowerPos)) + } + + private fun reversed(position: Int): Int { + return ((readerAdapter?.itemCount ?: 0) - position - 1).coerceAtLeast(0) + } +}