fix(browse): A different approach

This commit is contained in:
Ahmad Ansori Palembani 2024-12-20 20:12:09 +07:00
parent b974eff320
commit c73d0f843f
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
3 changed files with 43 additions and 30 deletions

View file

@ -61,7 +61,12 @@ import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import eu.kanade.tachiyomi.widget.EmptyView
import eu.kanade.tachiyomi.widget.LinearLayoutManagerAccurateOffset
import kotlin.math.roundToInt
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import uy.kohesive.injekt.injectLazy
import yokai.domain.manga.interactor.GetManga
import yokai.i18n.MR
import yokai.util.lang.getString
@ -101,6 +106,8 @@ open class BrowseSourceController(bundle: Bundle) :
},
)
private val getManga: GetManga by injectLazy()
/**
* Preferences helper.
*/
@ -133,6 +140,9 @@ open class BrowseSourceController(bundle: Bundle) :
private val isBehindGlobalSearch: Boolean
get() = router.backstackSize >= 2 && router.backstack[router.backstackSize - 2].controller is GlobalSearchController
/** Watch for manga data changes */
private var watchJob: Job? = null
init {
setHasOptionsMenu(true)
}
@ -655,7 +665,7 @@ open class BrowseSourceController(bundle: Bundle) :
* @param manga the manga initialized
*/
fun onMangaInitialized(manga: Manga) {
getHolder(manga)?.setImage(manga)
getHolder(manga.id!!)?.setImage(manga)
}
/**
@ -711,12 +721,12 @@ open class BrowseSourceController(bundle: Bundle) :
* @param manga the manga to find.
* @return the holder of the manga or null if it's not bound.
*/
private fun getHolder(manga: Manga): BrowseSourceHolder? {
private fun getHolder(mangaId: Long): BrowseSourceHolder? {
val adapter = adapter ?: return null
adapter.allBoundViewHolders.forEach { holder ->
val item = adapter.getItem(holder.flexibleAdapterPosition) as? BrowseSourceItem
if (item != null && item.manga.id!! == manga.id!!) {
if (item != null && item.mangaId == mangaId) {
return holder as BrowseSourceHolder
}
}
@ -742,6 +752,23 @@ open class BrowseSourceController(bundle: Bundle) :
binding.progress.isVisible = false
}
/**
* Workaround to fix data state de-sync issues when controller detached,
* and attaching flow directly into Item caused some flickering issues.
*
* FIXME: Could easily be fixed by migrating to Compose.
*/
private fun BrowseSourceItem.subscribe(mangaFlow: Flow<Manga?>) {
watchJob?.cancel()
watchJob = viewScope.launch {
mangaFlow.collectLatest {
if (it == null) return@collectLatest
val holder = getHolder(mangaId) ?: return@collectLatest
updateManga(holder, it)
}
}
}
/**
* Called when a manga is clicked.
*
@ -750,6 +777,7 @@ open class BrowseSourceController(bundle: Bundle) :
*/
override fun onItemClick(view: View?, position: Int): Boolean {
val item = adapter?.getItem(position) as? BrowseSourceItem ?: return false
item.subscribe(getManga.subscribeByUrlAndSource(item.manga.url, item.manga.source))
router.pushController(MangaDetailsController(item.manga, true).withFadeTransaction())
lastPosition = position
return false

View file

@ -18,16 +18,10 @@ import eu.kanade.tachiyomi.domain.manga.models.Manga
import eu.kanade.tachiyomi.ui.library.LibraryItem
import eu.kanade.tachiyomi.ui.library.setBGAndFG
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
// FIXME: Migrate to compose
class BrowseSourceItem(
initialManga: Manga,
private val mangaFlow: Flow<Manga?>,
private val catalogueAsList: Preference<Boolean>,
private val catalogueListType: Preference<Int>,
private val outlineOnCovers: Preference<Boolean>,
@ -37,8 +31,6 @@ class BrowseSourceItem(
val mangaId: Long = initialManga.id!!
var manga: Manga = initialManga
private set
private val scope = MainScope()
private var job: Job? = null
override fun getLayoutRes(): Int {
return if (catalogueAsList.get()) {
@ -83,35 +75,29 @@ class BrowseSourceItem(
}
}
fun updateManga(
holder: BrowseSourceHolder,
manga: Manga,
) {
if (manga.id != mangaId) return
this.manga = manga
holder.onSetValues(manga)
}
override fun bindViewHolder(
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
holder: BrowseSourceHolder,
position: Int,
payloads: MutableList<Any?>?,
) {
if (job == null) holder.onSetValues(manga)
job?.cancel()
job = scope.launch {
mangaFlow.collectLatest {
manga = it ?: return@collectLatest
holder.onSetValues(manga)
}
}
}
override fun unbindViewHolder(
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>?,
holder: BrowseSourceHolder?,
position: Int
) {
job?.cancel()
job = null
holder.onSetValues(manga)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other is BrowseSourceItem) {
return mangaId == other.mangaId
return this.mangaId == other.mangaId
}
return false
}

View file

@ -185,7 +185,6 @@ open class BrowseSourcePresenter(
first to second.map {
BrowseSourceItem(
it,
getManga.subscribeByUrlAndSource(it.url, it.source),
browseAsList,
sourceListType,
outlineCovers,