Replace RxJava in reader transitions

Co-Authored-By: arkon <4098258+arkon@users.noreply.github.com>
This commit is contained in:
Jays2Kings 2023-03-02 01:17:42 -05:00
parent d2d650da70
commit b7fc06d2ad
3 changed files with 54 additions and 70 deletions

View file

@ -1,23 +1,19 @@
package eu.kanade.tachiyomi.ui.reader.model
import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.ui.reader.loader.PageLoader
import kotlinx.coroutines.flow.MutableStateFlow
import timber.log.Timber
data class ReaderChapter(val chapter: Chapter) {
var state: State =
State.Wait
val stateFlow = MutableStateFlow<State>(State.Wait)
var state: State
get() = stateFlow.value
set(value) {
field = value
stateRelay.call(value)
stateFlow.value = value
}
private val stateRelay by lazy { BehaviorRelay.create(state) }
val stateObserver by lazy { stateRelay.asObservable() }
val pages: List<ReaderPage>?
get() = (state as? State.Loaded)?.pages
@ -25,8 +21,7 @@ data class ReaderChapter(val chapter: Chapter) {
var requestedPage: Int = 0
var references = 0
private set
private var references = 0
fun ref() {
references++

View file

@ -17,8 +17,10 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderTransitionView
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* View of the ViewPager that contains a chapter transition.
@ -29,17 +31,15 @@ class PagerTransitionHolder(
val transition: ChapterTransition,
) : LinearLayout(viewer.activity), ViewPagerAdapter.PositionableView {
private val scope = MainScope()
private var stateJob: Job? = null
/**
* Item that identifies this view. Needed by the adapter to not recreate views.
*/
override val item: Any
get() = transition
/**
* Subscription for status changes of the transition page.
*/
private var statusSubscription: Subscription? = null
/**
* View container of the current status of the transition page. Child views will be added
* dynamically.
@ -55,11 +55,13 @@ class PagerTransitionHolder(
gravity = Gravity.CENTER
val sidePadding = 64.dpToPx
setPadding(sidePadding, 0, sidePadding, 0)
val transitionView = ReaderTransitionView(context)
addView(transitionView)
addView(pagesContainer)
transitionView.bind(transition, viewer.downloadManager, viewer.activity.viewModel.state.value.manga)
transitionView.bind(transition, viewer.downloadManager, viewer.activity.viewModel.manga)
transition.to?.let { observeStatus(it) }
if (viewer.config.hingeGapSize > 0) {
@ -74,8 +76,7 @@ class PagerTransitionHolder(
*/
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
statusSubscription?.unsubscribe()
statusSubscription = null
stateJob?.cancel()
}
/**
@ -83,18 +84,20 @@ class PagerTransitionHolder(
* state, the pages container is cleaned up before setting the new state.
*/
private fun observeStatus(chapter: ReaderChapter) {
statusSubscription?.unsubscribe()
statusSubscription = chapter.stateObserver
.observeOn(AndroidSchedulers.mainThread())
.subscribe { state ->
pagesContainer.removeAllViews()
when (state) {
is ReaderChapter.State.Wait -> {}
is ReaderChapter.State.Loading -> setLoading()
is ReaderChapter.State.Error -> setError(state.error)
is ReaderChapter.State.Loaded -> setLoaded()
stateJob?.cancel()
stateJob = scope.launch {
chapter.stateFlow
.collectLatest { state ->
pagesContainer.removeAllViews()
when (state) {
is ReaderChapter.State.Loading -> setLoading()
is ReaderChapter.State.Error -> setError(state.error)
is ReaderChapter.State.Wait, is ReaderChapter.State.Loaded -> {
// No additional view is added
}
}
}
}
}
}
/**
@ -112,13 +115,6 @@ class PagerTransitionHolder(
pagesContainer.addView(textView)
}
/**
* Sets the loaded state on the pages container.
*/
private fun setLoaded() {
// No additional view is added
}
/**
* Sets the error state on the pages container.
*/

View file

@ -8,14 +8,17 @@ import android.widget.LinearLayout
import android.widget.ProgressBar
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.isNotEmpty
import androidx.core.view.isVisible
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderTransitionView
import eu.kanade.tachiyomi.util.system.dpToPx
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
/**
* Holder of the webtoon viewer that contains a chapter transition.
@ -25,10 +28,8 @@ class WebtoonTransitionHolder(
viewer: WebtoonViewer,
) : WebtoonBaseHolder(layout, viewer) {
/**
* Subscription for status changes of the transition page.
*/
private var statusSubscription: Subscription? = null
private val scope = MainScope()
private var stateJob: Job? = null
private val transitionView = ReaderTransitionView(context)
@ -64,7 +65,8 @@ class WebtoonTransitionHolder(
* Binds the given [transition] with this view holder, subscribing to its state.
*/
fun bind(transition: ChapterTransition) {
transitionView.bind(transition, viewer.downloadManager, viewer.activity.viewModel.state.value.manga)
transitionView.bind(transition, viewer.downloadManager, viewer.activity.viewModel.manga)
transition.to?.let { observeStatus(it, transition) }
}
@ -72,7 +74,7 @@ class WebtoonTransitionHolder(
* Called when the view is recycled and being added to the view pool.
*/
override fun recycle() {
unsubscribeStatus()
stateJob?.cancel()
}
/**
@ -80,30 +82,21 @@ class WebtoonTransitionHolder(
* state, the pages container is cleaned up before setting the new state.
*/
private fun observeStatus(chapter: ReaderChapter, transition: ChapterTransition) {
unsubscribeStatus()
statusSubscription = chapter.stateObserver
.observeOn(AndroidSchedulers.mainThread())
.subscribe { state ->
pagesContainer.removeAllViews()
when (state) {
is ReaderChapter.State.Wait -> {}
is ReaderChapter.State.Loading -> setLoading()
is ReaderChapter.State.Error -> setError(state.error, transition)
is ReaderChapter.State.Loaded -> setLoaded()
stateJob?.cancel()
stateJob = scope.launch {
chapter.stateFlow
.collectLatest { state ->
pagesContainer.removeAllViews()
when (state) {
is ReaderChapter.State.Loading -> setLoading()
is ReaderChapter.State.Error -> setError(state.error, transition)
is ReaderChapter.State.Wait, is ReaderChapter.State.Loaded -> {
// No additional view is added
}
}
pagesContainer.isVisible = pagesContainer.isNotEmpty()
}
pagesContainer.isVisible = pagesContainer.childCount > 0
}
addSubscription(statusSubscription)
}
/**
* Unsubscribes from the status subscription.
*/
private fun unsubscribeStatus() {
removeSubscription(statusSubscription)
statusSubscription = null
}
}
/**