Double page reader for reversed mode

master
Koitharu 2 years ago
parent d24754f2a0
commit 2d61209696
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -266,6 +266,10 @@ class ReaderActivity :
viewModel.switchMode(mode) viewModel.switchMode(mode)
} }
override fun onDoubleModeChanged(isEnabled: Boolean) {
readerManager.setDoubleReaderMode(isEnabled)
}
private fun onPageSaved(uri: Uri?) { private fun onPageSaved(uri: Uri?) {
if (uri != null) { if (uri != null) {
Snackbar.make(viewBinding.container, R.string.page_saved, Snackbar.LENGTH_LONG) Snackbar.make(viewBinding.container, R.string.page_saved, Snackbar.LENGTH_LONG)

@ -6,8 +6,10 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.commit import androidx.fragment.app.commit
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.ReaderMode 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.BaseReaderFragment
import org.koitharu.kotatsu.reader.ui.pager.doublepage.DoubleReaderFragment 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.reversed.ReversedReaderFragment
import org.koitharu.kotatsu.reader.ui.pager.standard.PagerReaderFragment import org.koitharu.kotatsu.reader.ui.pager.standard.PagerReaderFragment
import org.koitharu.kotatsu.reader.ui.pager.vertical.VerticalReaderFragment 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) private val modeMap = EnumMap<ReaderMode, Class<out BaseReaderFragment<*>>>(ReaderMode::class.java)
init { init {
modeMap[ReaderMode.STANDARD] = if (useDoublePages()) { val useDoublePages = container.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
DoubleReaderFragment::class.java && settings.isReaderDoubleOnLandscape
} else { invalidateTypesMap(useDoublePages)
PagerReaderFragment::class.java
}
modeMap[ReaderMode.REVERSED] = ReversedReaderFragment::class.java
modeMap[ReaderMode.WEBTOON] = WebtoonReaderFragment::class.java
modeMap[ReaderMode.VERTICAL] = VerticalReaderFragment::class.java
} }
val currentReader: BaseReaderFragment<*>? val currentReader: BaseReaderFragment<*>?
@ -39,7 +36,7 @@ class ReaderManager(
val currentMode: ReaderMode? val currentMode: ReaderMode?
get() { get() {
val readerClass = currentReader?.javaClass ?: return null val readerClass = currentReader?.javaClass ?: return null
return modeMap.entries.find { it.value == readerClass }?.key return modeMap.findKeyByValue(readerClass)
} }
fun replace(newMode: ReaderMode) { fun replace(newMode: ReaderMode) {
@ -50,13 +47,27 @@ class ReaderManager(
} }
} }
private fun useDoublePages() = container.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE fun setDoubleReaderMode(isEnabled: Boolean) {
&& settings.isReaderDoubleOnLandscape val prevMode = currentMode
invalidateTypesMap(isEnabled)
val newMode = currentMode ?: return
if (newMode != prevMode) {
replace(newMode)
}
}
/*fun replace(reader: BaseReaderFragment<*>) { private fun invalidateTypesMap(useDoublePages: Boolean) {
fragmentManager.commit { modeMap[ReaderMode.STANDARD] = if (useDoublePages) {
setReorderingAllowed(true) DoubleReaderFragment::class.java
replace(containerResId, reader) } 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
} }
}*/
} }

@ -145,7 +145,7 @@ class ReaderConfigSheet :
R.id.switch_double_reader -> { R.id.switch_double_reader -> {
settings.isReaderDoubleOnLandscape = isChecked settings.isReaderDoubleOnLandscape = isChecked
findCallback()?.onReaderModeChanged(mode) findCallback()?.onDoubleModeChanged(isChecked)
} }
} }
} }
@ -165,7 +165,7 @@ class ReaderConfigSheet :
R.id.button_vertical -> ReaderMode.VERTICAL R.id.button_vertical -> ReaderMode.VERTICAL
else -> return else -> return
} }
viewBinding?.switchDoubleReader?.isEnabled = newMode == ReaderMode.STANDARD viewBinding?.switchDoubleReader?.isEnabled = newMode == ReaderMode.STANDARD || newMode == ReaderMode.REVERSED
if (newMode == mode) { if (newMode == mode) {
return return
} }
@ -212,6 +212,8 @@ class ReaderConfigSheet :
var isAutoScrollEnabled: Boolean var isAutoScrollEnabled: Boolean
fun onReaderModeChanged(mode: ReaderMode) fun onReaderModeChanged(mode: ReaderMode)
fun onDoubleModeChanged(isEnabled: Boolean)
} }
companion object { companion object {

@ -18,7 +18,6 @@ import org.koitharu.kotatsu.core.util.ext.firstVisibleItemPosition
import org.koitharu.kotatsu.databinding.FragmentReaderDoubleBinding import org.koitharu.kotatsu.databinding.FragmentReaderDoubleBinding
import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.domain.PageLoader
import org.koitharu.kotatsu.reader.ui.ReaderState 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.BaseReaderAdapter
import org.koitharu.kotatsu.reader.ui.pager.BaseReaderFragment import org.koitharu.kotatsu.reader.ui.pager.BaseReaderFragment
import org.koitharu.kotatsu.reader.ui.pager.ReaderPage import org.koitharu.kotatsu.reader.ui.pager.ReaderPage
@ -26,7 +25,7 @@ import javax.inject.Inject
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
@AndroidEntryPoint @AndroidEntryPoint
class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() { open class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() {
@Inject @Inject
lateinit var networkState: NetworkState lateinit var networkState: NetworkState
@ -51,7 +50,7 @@ class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() {
recyclerLifecycleDispatcher = RecyclerViewLifecycleDispatcher().also { recyclerLifecycleDispatcher = RecyclerViewLifecycleDispatcher().also {
addOnScrollListener(it) addOnScrollListener(it)
} }
addOnScrollListener(PageScrollListener(viewModel)) addOnScrollListener(PageScrollListener())
DoublePageSnapHelper().attachToRecyclerView(this) DoublePageSnapHelper().attachToRecyclerView(this)
} }
} }
@ -78,7 +77,7 @@ class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() {
if (position != -1) { if (position != -1) {
position = position.toPagePosition() position = position.toPagePosition()
requireViewBinding().recyclerView.firstVisibleItemPosition = position requireViewBinding().recyclerView.firstVisibleItemPosition = position
viewModel.onCurrentPageChanged(position, position + 1) notifyPageChanged(position, position + 1)
} else { } else {
Snackbar.make(requireView(), R.string.not_found_404, Snackbar.LENGTH_SHORT) Snackbar.make(requireView(), R.string.not_found_404, Snackbar.LENGTH_SHORT)
.show() .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) private fun getCurrentItem() = (requireViewBinding().recyclerView.layoutManager as LinearLayoutManager)
.findFirstCompletelyVisibleItemPosition().toPagePosition() .findFirstCompletelyVisibleItemPosition().toPagePosition()
private fun Int.toPagePosition() = this and 1.inv() private fun Int.toPagePosition() = this and 1.inv()
private class PageScrollListener( private inner class PageScrollListener : RecyclerView.OnScrollListener() {
private val viewModel: ReaderViewModel,
) : RecyclerView.OnScrollListener() {
private var firstPos = RecyclerView.NO_POSITION private var firstPos = RecyclerView.NO_POSITION
private var lastPos = RecyclerView.NO_POSITION private var lastPos = RecyclerView.NO_POSITION
@ -157,7 +158,7 @@ class DoubleReaderFragment : BaseReaderFragment<FragmentReaderDoubleBinding>() {
if (newFirstPos != firstPos || newLastPos != lastPos) { if (newFirstPos != firstPos || newLastPos != lastPos) {
firstPos = newFirstPos firstPos = newFirstPos
lastPos = newLastPos lastPos = newLastPos
viewModel.onCurrentPageChanged(newFirstPos, newLastPos) notifyPageChanged(newFirstPos, newLastPos)
} }
} }
} }

@ -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)
}
}
Loading…
Cancel
Save