mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
fix(browse): A different approach
This commit is contained in:
parent
b974eff320
commit
c73d0f843f
3 changed files with 43 additions and 30 deletions
|
@ -61,7 +61,12 @@ import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||||
import eu.kanade.tachiyomi.widget.EmptyView
|
import eu.kanade.tachiyomi.widget.EmptyView
|
||||||
import eu.kanade.tachiyomi.widget.LinearLayoutManagerAccurateOffset
|
import eu.kanade.tachiyomi.widget.LinearLayoutManagerAccurateOffset
|
||||||
import kotlin.math.roundToInt
|
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 uy.kohesive.injekt.injectLazy
|
||||||
|
import yokai.domain.manga.interactor.GetManga
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
import yokai.util.lang.getString
|
import yokai.util.lang.getString
|
||||||
|
|
||||||
|
@ -101,6 +106,8 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val getManga: GetManga by injectLazy()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preferences helper.
|
* Preferences helper.
|
||||||
*/
|
*/
|
||||||
|
@ -133,6 +140,9 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
private val isBehindGlobalSearch: Boolean
|
private val isBehindGlobalSearch: Boolean
|
||||||
get() = router.backstackSize >= 2 && router.backstack[router.backstackSize - 2].controller is GlobalSearchController
|
get() = router.backstackSize >= 2 && router.backstack[router.backstackSize - 2].controller is GlobalSearchController
|
||||||
|
|
||||||
|
/** Watch for manga data changes */
|
||||||
|
private var watchJob: Job? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
}
|
}
|
||||||
|
@ -655,7 +665,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
* @param manga the manga initialized
|
* @param manga the manga initialized
|
||||||
*/
|
*/
|
||||||
fun onMangaInitialized(manga: Manga) {
|
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.
|
* @param manga the manga to find.
|
||||||
* @return the holder of the manga or null if it's not bound.
|
* @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
|
val adapter = adapter ?: return null
|
||||||
|
|
||||||
adapter.allBoundViewHolders.forEach { holder ->
|
adapter.allBoundViewHolders.forEach { holder ->
|
||||||
val item = adapter.getItem(holder.flexibleAdapterPosition) as? BrowseSourceItem
|
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
|
return holder as BrowseSourceHolder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -742,6 +752,23 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
binding.progress.isVisible = false
|
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.
|
* Called when a manga is clicked.
|
||||||
*
|
*
|
||||||
|
@ -750,6 +777,7 @@ open class BrowseSourceController(bundle: Bundle) :
|
||||||
*/
|
*/
|
||||||
override fun onItemClick(view: View?, position: Int): Boolean {
|
override fun onItemClick(view: View?, position: Int): Boolean {
|
||||||
val item = adapter?.getItem(position) as? BrowseSourceItem ?: return false
|
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())
|
router.pushController(MangaDetailsController(item.manga, true).withFadeTransaction())
|
||||||
lastPosition = position
|
lastPosition = position
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -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.LibraryItem
|
||||||
import eu.kanade.tachiyomi.ui.library.setBGAndFG
|
import eu.kanade.tachiyomi.ui.library.setBGAndFG
|
||||||
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
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
|
// FIXME: Migrate to compose
|
||||||
class BrowseSourceItem(
|
class BrowseSourceItem(
|
||||||
initialManga: Manga,
|
initialManga: Manga,
|
||||||
private val mangaFlow: Flow<Manga?>,
|
|
||||||
private val catalogueAsList: Preference<Boolean>,
|
private val catalogueAsList: Preference<Boolean>,
|
||||||
private val catalogueListType: Preference<Int>,
|
private val catalogueListType: Preference<Int>,
|
||||||
private val outlineOnCovers: Preference<Boolean>,
|
private val outlineOnCovers: Preference<Boolean>,
|
||||||
|
@ -37,8 +31,6 @@ class BrowseSourceItem(
|
||||||
val mangaId: Long = initialManga.id!!
|
val mangaId: Long = initialManga.id!!
|
||||||
var manga: Manga = initialManga
|
var manga: Manga = initialManga
|
||||||
private set
|
private set
|
||||||
private val scope = MainScope()
|
|
||||||
private var job: Job? = null
|
|
||||||
|
|
||||||
override fun getLayoutRes(): Int {
|
override fun getLayoutRes(): Int {
|
||||||
return if (catalogueAsList.get()) {
|
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(
|
override fun bindViewHolder(
|
||||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
|
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
|
||||||
holder: BrowseSourceHolder,
|
holder: BrowseSourceHolder,
|
||||||
position: Int,
|
position: Int,
|
||||||
payloads: MutableList<Any?>?,
|
payloads: MutableList<Any?>?,
|
||||||
) {
|
) {
|
||||||
if (job == null) holder.onSetValues(manga)
|
|
||||||
job?.cancel()
|
|
||||||
job = scope.launch {
|
|
||||||
mangaFlow.collectLatest {
|
|
||||||
manga = it ?: return@collectLatest
|
|
||||||
holder.onSetValues(manga)
|
holder.onSetValues(manga)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun unbindViewHolder(
|
|
||||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>?,
|
|
||||||
holder: BrowseSourceHolder?,
|
|
||||||
position: Int
|
|
||||||
) {
|
|
||||||
job?.cancel()
|
|
||||||
job = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other is BrowseSourceItem) {
|
if (other is BrowseSourceItem) {
|
||||||
return mangaId == other.mangaId
|
return this.mangaId == other.mangaId
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,6 @@ open class BrowseSourcePresenter(
|
||||||
first to second.map {
|
first to second.map {
|
||||||
BrowseSourceItem(
|
BrowseSourceItem(
|
||||||
it,
|
it,
|
||||||
getManga.subscribeByUrlAndSource(it.url, it.source),
|
|
||||||
browseAsList,
|
browseAsList,
|
||||||
sourceListType,
|
sourceListType,
|
||||||
outlineCovers,
|
outlineCovers,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue