MangaController optimizations (#6089)
* MangaController: Fix ignored stable ids * MangaController: Replace notifyDataSetChanged * ChaptersSettingsSheet: Optimizations (cherry picked from commit 684965f3e56ceb64f8f7be0a23d6a884480eaed2) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt # app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoHeaderAdapter.kt
This commit is contained in:
parent
7fb4cd29dc
commit
b116f5e1fd
@ -55,7 +55,6 @@ import eu.kanade.tachiyomi.source.LocalSource
|
|||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.FabController
|
import eu.kanade.tachiyomi.ui.base.controller.FabController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
|
||||||
@ -94,7 +93,6 @@ import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
|||||||
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
|
import eu.kanade.tachiyomi.util.chapter.NoChaptersException
|
||||||
import eu.kanade.tachiyomi.util.hasCustomCover
|
import eu.kanade.tachiyomi.util.hasCustomCover
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
|
||||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import eu.kanade.tachiyomi.util.system.toShareIntent
|
import eu.kanade.tachiyomi.util.system.toShareIntent
|
||||||
@ -105,7 +103,6 @@ import eu.kanade.tachiyomi.util.view.snack
|
|||||||
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
|
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
|
||||||
import exh.log.xLogD
|
import exh.log.xLogD
|
||||||
import exh.md.similar.MangaDexSimilarController
|
import exh.md.similar.MangaDexSimilarController
|
||||||
import exh.metadata.metadata.base.FlatMetadata
|
|
||||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||||
import exh.recs.RecommendsController
|
import exh.recs.RecommendsController
|
||||||
import exh.source.MERGED_SOURCE_ID
|
import exh.source.MERGED_SOURCE_ID
|
||||||
@ -304,18 +301,29 @@ class MangaController :
|
|||||||
if (manga == null || source == null) return
|
if (manga == null || source == null) return
|
||||||
|
|
||||||
// Init RecyclerView and adapter
|
// Init RecyclerView and adapter
|
||||||
mangaInfoAdapter = MangaInfoHeaderAdapter(this, fromSource, binding.infoRecycler != null)
|
mangaInfoAdapter = MangaInfoHeaderAdapter(this, fromSource, binding.infoRecycler != null).apply {
|
||||||
chaptersHeaderAdapter = MangaChaptersHeaderAdapter(this)
|
setHasStableIds(true)
|
||||||
|
}
|
||||||
|
chaptersHeaderAdapter = MangaChaptersHeaderAdapter(this).apply {
|
||||||
|
setHasStableIds(true)
|
||||||
|
}
|
||||||
chaptersAdapter = ChaptersAdapter(this, view.context)
|
chaptersAdapter = ChaptersAdapter(this, view.context)
|
||||||
// SY -->
|
// SY -->
|
||||||
if (!preferences.recommendsInOverflow().get() || smartSearchConfig != null) {
|
if (!preferences.recommendsInOverflow().get() || smartSearchConfig != null) {
|
||||||
mangaInfoButtonsAdapter = MangaInfoButtonsAdapter(this)
|
mangaInfoButtonsAdapter = MangaInfoButtonsAdapter(this).apply {
|
||||||
|
setHasStableIds(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
// Phone layout
|
// Phone layout
|
||||||
binding.fullRecycler?.let {
|
binding.fullRecycler?.let {
|
||||||
|
val config = ConcatAdapter.Config.Builder()
|
||||||
|
.setIsolateViewTypes(true)
|
||||||
|
.setStableIdMode(ConcatAdapter.Config.StableIdMode.SHARED_STABLE_IDS)
|
||||||
|
.build()
|
||||||
it.adapter = ConcatAdapter(
|
it.adapter = ConcatAdapter(
|
||||||
|
config,
|
||||||
listOfNotNull(
|
listOfNotNull(
|
||||||
mangaInfoAdapter,
|
mangaInfoAdapter,
|
||||||
mangaInfoButtonsAdapter,
|
mangaInfoButtonsAdapter,
|
||||||
@ -390,7 +398,6 @@ class MangaController :
|
|||||||
settingsSheet = ChaptersSettingsSheet(router, presenter) { group ->
|
settingsSheet = ChaptersSettingsSheet(router, presenter) { group ->
|
||||||
if (group is ChaptersSettingsSheet.Filter.FilterGroup) {
|
if (group is ChaptersSettingsSheet.Filter.FilterGroup) {
|
||||||
updateFilterIconState()
|
updateFilterIconState()
|
||||||
chaptersAdapter?.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,17 +576,6 @@ class MangaController :
|
|||||||
|
|
||||||
// Manga info - start
|
// Manga info - start
|
||||||
|
|
||||||
// SY -->
|
|
||||||
fun onNextMetaInfo(flatMetadata: FlatMetadata) {
|
|
||||||
val mainSource = presenter.source.getMainSource<MetadataSource<*, *>>()
|
|
||||||
if (mainSource != null) {
|
|
||||||
presenter.meta = flatMetadata.raise(mainSource.metaClass)
|
|
||||||
mangaInfoAdapter?.notifyMetaAdapter()
|
|
||||||
updateFilterIconState()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// SY <--
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if manga is initialized.
|
* Check if manga is initialized.
|
||||||
* If true update header with manga information,
|
* If true update header with manga information,
|
||||||
@ -834,7 +830,7 @@ class MangaController :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mangaInfoAdapter?.notifyDataSetChanged()
|
mangaInfoAdapter?.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onCategoriesClick() {
|
fun onCategoriesClick() {
|
||||||
@ -1038,7 +1034,7 @@ class MangaController :
|
|||||||
|
|
||||||
override fun deleteMangaCover(manga: Manga) {
|
override fun deleteMangaCover(manga: Manga) {
|
||||||
presenter.deleteCustomCover(manga)
|
presenter.deleteCustomCover(manga)
|
||||||
mangaInfoAdapter?.notifyDataSetChanged()
|
mangaInfoAdapter?.notifyItemChanged(0, manga)
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,7 +1053,7 @@ class MangaController :
|
|||||||
|
|
||||||
fun onSetCoverSuccess() {
|
fun onSetCoverSuccess() {
|
||||||
editMangaDialog?.loadCover()
|
editMangaDialog?.loadCover()
|
||||||
mangaInfoAdapter?.notifyDataSetChanged()
|
mangaInfoAdapter?.notifyItemChanged(0, this)
|
||||||
(dialog as? MangaFullCoverDialog)?.setImage(manga)
|
(dialog as? MangaFullCoverDialog)?.setImage(manga)
|
||||||
activity?.toast(R.string.cover_updated)
|
activity?.toast(R.string.cover_updated)
|
||||||
}
|
}
|
||||||
@ -1172,19 +1168,20 @@ class MangaController :
|
|||||||
val lastClickPosition = lastClickPositionStack.peek()!!
|
val lastClickPosition = lastClickPositionStack.peek()!!
|
||||||
when {
|
when {
|
||||||
lastClickPosition == -1 -> setSelection(position)
|
lastClickPosition == -1 -> setSelection(position)
|
||||||
lastClickPosition > position ->
|
lastClickPosition > position -> {
|
||||||
for (i in position until lastClickPosition)
|
for (i in position until lastClickPosition) setSelection(i)
|
||||||
setSelection(i)
|
chaptersAdapter?.notifyItemRangeChanged(position, lastClickPosition, position)
|
||||||
lastClickPosition < position ->
|
}
|
||||||
for (i in lastClickPosition + 1..position)
|
lastClickPosition < position -> {
|
||||||
setSelection(i)
|
for (i in lastClickPosition + 1..position) setSelection(i)
|
||||||
|
chaptersAdapter?.notifyItemRangeChanged(lastClickPosition + 1, position, position)
|
||||||
|
}
|
||||||
else -> setSelection(position)
|
else -> setSelection(position)
|
||||||
}
|
}
|
||||||
if (lastClickPosition != position) {
|
if (lastClickPosition != position) {
|
||||||
lastClickPositionStack.remove(position) // move to top if already exists
|
lastClickPositionStack.remove(position) // move to top if already exists
|
||||||
lastClickPositionStack.push(position)
|
lastClickPositionStack.push(position)
|
||||||
}
|
}
|
||||||
chaptersAdapter?.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showSettingsSheet() {
|
fun showSettingsSheet() {
|
||||||
@ -1197,7 +1194,6 @@ class MangaController :
|
|||||||
val adapter = chaptersAdapter ?: return
|
val adapter = chaptersAdapter ?: return
|
||||||
val item = adapter.getItem(position) ?: return
|
val item = adapter.getItem(position) ?: return
|
||||||
adapter.toggleSelection(position)
|
adapter.toggleSelection(position)
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
if (adapter.isSelected(position)) {
|
if (adapter.isSelected(position)) {
|
||||||
selectedChapters.add(item)
|
selectedChapters.add(item)
|
||||||
} else {
|
} else {
|
||||||
@ -1330,11 +1326,11 @@ class MangaController :
|
|||||||
selectedChapters.clear()
|
selectedChapters.clear()
|
||||||
for (i in 0..adapter.itemCount) {
|
for (i in 0..adapter.itemCount) {
|
||||||
adapter.toggleSelection(i)
|
adapter.toggleSelection(i)
|
||||||
|
adapter.notifyItemChanged(i, i)
|
||||||
}
|
}
|
||||||
selectedChapters.addAll(adapter.selectedPositions.mapNotNull { adapter.getItem(it) })
|
selectedChapters.addAll(adapter.selectedPositions.mapNotNull { adapter.getItem(it) })
|
||||||
|
|
||||||
actionMode?.invalidate()
|
actionMode?.invalidate()
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markAsRead(chapters: List<ChapterItem>) {
|
private fun markAsRead(chapters: List<ChapterItem>) {
|
||||||
@ -1401,10 +1397,7 @@ class MangaController :
|
|||||||
fun onChaptersDeleted(chapters: List<ChapterItem>) {
|
fun onChaptersDeleted(chapters: List<ChapterItem>) {
|
||||||
// this is needed so the downloaded text gets removed from the item
|
// this is needed so the downloaded text gets removed from the item
|
||||||
chapters.forEach {
|
chapters.forEach {
|
||||||
chaptersAdapter?.updateItem(it)
|
chaptersAdapter?.updateItem(it, it)
|
||||||
}
|
|
||||||
launchUI {
|
|
||||||
chaptersAdapter?.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,6 +1106,7 @@ class MangaPresenter(
|
|||||||
fun setDisplayMode(mode: Int) {
|
fun setDisplayMode(mode: Int) {
|
||||||
manga.displayMode = mode
|
manga.displayMode = mode
|
||||||
db.updateChapterFlags(manga).executeAsBlocking()
|
db.updateChapterFlags(manga).executeAsBlocking()
|
||||||
|
refreshChapters()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,7 +155,7 @@ class ChaptersSettingsSheet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
initModels()
|
initModels()
|
||||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
adapter.notifyItemChanged(items.indexOf(item), item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,18 +197,18 @@ class ChaptersSettingsSheet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClicked(item: Item) {
|
override fun onItemClicked(item: Item) {
|
||||||
item as Item.MultiStateGroup
|
items.forEachIndexed { i, multiSort ->
|
||||||
val prevState = item.state
|
multiSort.state = if (multiSort == item) {
|
||||||
|
when (item.state) {
|
||||||
item.group.items.forEach {
|
Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
|
||||||
(it as Item.MultiStateGroup).state =
|
Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
|
||||||
|
Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
|
||||||
|
else -> throw Exception("Unknown state")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Item.MultiSort.SORT_NONE
|
Item.MultiSort.SORT_NONE
|
||||||
}
|
}
|
||||||
item.state = when (prevState) {
|
adapter.notifyItemChanged(i, multiSort)
|
||||||
Item.MultiSort.SORT_NONE -> Item.MultiSort.SORT_ASC
|
|
||||||
Item.MultiSort.SORT_ASC -> Item.MultiSort.SORT_DESC
|
|
||||||
Item.MultiSort.SORT_DESC -> Item.MultiSort.SORT_ASC
|
|
||||||
else -> throw Exception("Unknown state")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
when (item) {
|
when (item) {
|
||||||
@ -219,8 +219,6 @@ class ChaptersSettingsSheet(
|
|||||||
}
|
}
|
||||||
|
|
||||||
presenter.reverseSortOrder()
|
presenter.reverseSortOrder()
|
||||||
|
|
||||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,16 +252,16 @@ class ChaptersSettingsSheet(
|
|||||||
item as Item.Radio
|
item as Item.Radio
|
||||||
if (item.checked) return
|
if (item.checked) return
|
||||||
|
|
||||||
item.group.items.forEach { (it as Item.Radio).checked = false }
|
items.forEachIndexed { index, radio ->
|
||||||
item.checked = true
|
radio.checked = item == radio
|
||||||
|
adapter.notifyItemChanged(index, radio)
|
||||||
|
}
|
||||||
|
|
||||||
when (item) {
|
when (item) {
|
||||||
displayTitle -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NAME)
|
displayTitle -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NAME)
|
||||||
displayChapterNum -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NUMBER)
|
displayChapterNum -> presenter.setDisplayMode(Manga.CHAPTER_DISPLAY_NUMBER)
|
||||||
else -> throw NotImplementedError("Unknown display mode")
|
else -> throw NotImplementedError("Unknown display mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
item.group.items.forEach { adapter.notifyItemChanged(it) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,20 +30,20 @@ class MangaChaptersHeaderAdapter(
|
|||||||
|
|
||||||
override fun getItemCount(): Int = 1
|
override fun getItemCount(): Int = 1
|
||||||
|
|
||||||
|
override fun getItemId(position: Int): Long = hashCode().toLong()
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
||||||
holder.bind()
|
holder.bind()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setNumChapters(numChapters: Int) {
|
fun setNumChapters(numChapters: Int) {
|
||||||
this.numChapters = numChapters
|
this.numChapters = numChapters
|
||||||
|
notifyItemChanged(0, this)
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setHasActiveFilters(hasActiveFilters: Boolean) {
|
fun setHasActiveFilters(hasActiveFilters: Boolean) {
|
||||||
this.hasActiveFilters = hasActiveFilters
|
this.hasActiveFilters = hasActiveFilters
|
||||||
|
notifyItemChanged(0, this)
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
inner class HeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
@ -66,7 +66,9 @@ class MangaInfoHeaderAdapter(
|
|||||||
binding.mangaSummarySection.expanded = fromSource || isTablet
|
binding.mangaSummarySection.expanded = fromSource || isTablet
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
metaInfoAdapter = source.getMainSource<MetadataSource<*, *>>()?.getDescriptionAdapter(controller)
|
metaInfoAdapter = source.getMainSource<MetadataSource<*, *>>()?.getDescriptionAdapter(controller)?.apply {
|
||||||
|
setHasStableIds(true)
|
||||||
|
}
|
||||||
binding.metadataView.isVisible = if (metaInfoAdapter != null) {
|
binding.metadataView.isVisible = if (metaInfoAdapter != null) {
|
||||||
binding.metadataView.layoutManager = LinearLayoutManager(binding.root.context)
|
binding.metadataView.layoutManager = LinearLayoutManager(binding.root.context)
|
||||||
binding.metadataView.adapter = metaInfoAdapter
|
binding.metadataView.adapter = metaInfoAdapter
|
||||||
@ -81,6 +83,8 @@ class MangaInfoHeaderAdapter(
|
|||||||
|
|
||||||
override fun getItemCount(): Int = 1
|
override fun getItemCount(): Int = 1
|
||||||
|
|
||||||
|
override fun getItemId(position: Int): Long = hashCode().toLong()
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: HeaderViewHolder, position: Int) {
|
||||||
holder.bind()
|
holder.bind()
|
||||||
}
|
}
|
||||||
@ -98,15 +102,17 @@ class MangaInfoHeaderAdapter(
|
|||||||
this.meta = meta
|
this.meta = meta
|
||||||
this.mergedMangaReferences = mergedMangaReferences
|
this.mergedMangaReferences = mergedMangaReferences
|
||||||
// SY <--
|
// SY <--
|
||||||
|
update()
|
||||||
|
updateMetaAdapter()
|
||||||
|
}
|
||||||
|
|
||||||
notifyDataSetChanged()
|
fun update() {
|
||||||
notifyMetaAdapter()
|
notifyItemChanged(0, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTrackingCount(trackCount: Int) {
|
fun setTrackingCount(trackCount: Int) {
|
||||||
this.trackCount = trackCount
|
this.trackCount = trackCount
|
||||||
|
update()
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateCoverPosition() {
|
private fun updateCoverPosition() {
|
||||||
@ -116,7 +122,7 @@ class MangaInfoHeaderAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyMetaAdapter() {
|
private fun updateMetaAdapter() {
|
||||||
metaInfoAdapter?.notifyDataSetChanged()
|
metaInfoAdapter?.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user