Double page reader for reversed mode

This commit is contained in:
Koitharu
2024-02-03 16:40:56 +02:00
parent d24754f2a0
commit 2d61209696
5 changed files with 73 additions and 27 deletions

View File

@@ -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)

View File

@@ -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<out BaseReaderFragment<*>>>(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 replace(reader: BaseReaderFragment<*>) {
fragmentManager.commit {
setReorderingAllowed(true)
replace(containerResId, reader)
fun setDoubleReaderMode(isEnabled: Boolean) {
val prevMode = currentMode
invalidateTypesMap(isEnabled)
val newMode = currentMode ?: return
if (newMode != prevMode) {
replace(newMode)
}
}*/
}
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
}
}

View File

@@ -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 {

View File

@@ -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<FragmentReaderDoubleBinding>() {
open class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() {
@Inject
lateinit var networkState: NetworkState
@@ -51,7 +50,7 @@ class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() {
recyclerLifecycleDispatcher = RecyclerViewLifecycleDispatcher().also {
addOnScrollListener(it)
}
addOnScrollListener(PageScrollListener(viewModel))
addOnScrollListener(PageScrollListener())
DoublePageSnapHelper().attachToRecyclerView(this)
}
}
@@ -78,7 +77,7 @@ class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() {
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<FragmentReaderDoubleBinding>() {
)
}
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<FragmentReaderDoubleBinding>() {
if (newFirstPos != firstPos || newLastPos != lastPos) {
firstPos = newFirstPos
lastPos = newLastPos
viewModel.onCurrentPageChanged(newFirstPos, newLastPos)
notifyPageChanged(newFirstPos, newLastPos)
}
}
}

View File

@@ -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<ReaderPage>, 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)
}
}