diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/EntityMapping.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/EntityMapping.kt index a8b2e0912..37816464e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/EntityMapping.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/EntityMapping.kt @@ -2,7 +2,7 @@ package org.koitharu.kotatsu.bookmarks.data import org.koitharu.kotatsu.bookmarks.domain.Bookmark import org.koitharu.kotatsu.parsers.model.Manga -import java.util.* +import java.util.Date fun BookmarkEntity.toBookmark(manga: Manga) = Bookmark( manga = manga, @@ -30,4 +30,5 @@ fun Collection.toBookmarks(manga: Manga) = map { it.toBookmark(manga) } -fun Collection.ids() = map { it.pageId } \ No newline at end of file +@JvmName("bookmarksIds") +fun Collection.ids() = map { it.pageId } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/Bookmark.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/Bookmark.kt index 98116f8a4..1ef35e5c2 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/Bookmark.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/Bookmark.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.bookmarks.domain +import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaPage import java.util.Date @@ -13,11 +14,21 @@ class Bookmark( val imageUrl: String, val createdAt: Date, val percent: Float, -) { +) : ListModel { val directImageUrl: String? get() = if (isImageUrlDirect()) imageUrl else null + val imageLoadData: Any + get() = if (isImageUrlDirect()) imageUrl else toMangaPage() + + override fun areItemsTheSame(other: ListModel): Boolean { + return other is Bookmark && + manga.id == other.manga.id && + chapterId == other.chapterId && + page == other.page + } + fun toMangaPage() = MangaPage( id = pageId, url = imageUrl, diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarkListAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarkListAD.kt index 5996df31d..f8b9c411e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarkListAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarkListAD.kt @@ -28,8 +28,7 @@ fun bookmarkListAD( binding.root.setOnLongClickListener(listener) bind { - val data: Any = item.directImageUrl ?: item.toMangaPage() - binding.imageViewThumb.newImageRequest(lifecycleOwner, data)?.run { + binding.imageViewThumb.newImageRequest(lifecycleOwner, item.imageLoadData)?.run { size(CoverSizeResolver(binding.imageViewThumb)) placeholder(R.drawable.ic_placeholder) fallback(R.drawable.ic_placeholder) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksAdapter.kt index 8d15f00ab..c484af1f3 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksAdapter.kt @@ -1,32 +1,15 @@ package org.koitharu.kotatsu.bookmarks.ui.adapter import androidx.lifecycle.LifecycleOwner -import androidx.recyclerview.widget.DiffUtil import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter import org.koitharu.kotatsu.bookmarks.domain.Bookmark +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener class BookmarksAdapter( coil: ImageLoader, lifecycleOwner: LifecycleOwner, clickListener: OnListItemClickListener, -) : AsyncListDifferDelegationAdapter( - DiffCallback(), +) : BaseListAdapter( bookmarkListAD(coil, lifecycleOwner, clickListener), -) { - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: Bookmark, newItem: Bookmark): Boolean { - return oldItem.manga.id == newItem.manga.id && - oldItem.chapterId == newItem.chapterId && - oldItem.page == newItem.page - } - - override fun areContentsTheSame(oldItem: Bookmark, newItem: Bookmark): Boolean { - return oldItem.imageUrl == newItem.imageUrl - } - - } -} +) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAdapter.kt index b95e1f195..e0030ec91 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAdapter.kt @@ -3,12 +3,11 @@ package org.koitharu.kotatsu.bookmarks.ui.adapter import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter import org.koitharu.kotatsu.bookmarks.domain.Bookmark import org.koitharu.kotatsu.bookmarks.ui.model.BookmarksGroup +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.SectionedSelectionController -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.errorStateListAD @@ -24,7 +23,7 @@ class BookmarksGroupAdapter( listener: ListStateHolderListener, bookmarkClickListener: OnListItemClickListener, groupClickListener: OnListItemClickListener, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback) { +) : BaseListAdapter() { init { val pool = RecyclerView.RecycledViewPool() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/model/BookmarksGroup.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/model/BookmarksGroup.kt index 99f3afcdb..2bd51e2d9 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/model/BookmarksGroup.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/model/BookmarksGroup.kt @@ -4,7 +4,6 @@ import org.koitharu.kotatsu.bookmarks.domain.Bookmark import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.Manga -import org.koitharu.kotatsu.parsers.util.areItemsEquals class BookmarksGroup( val manga: Manga, @@ -31,14 +30,12 @@ class BookmarksGroup( if (manga != other.manga) return false - return bookmarks.areItemsEquals(other.bookmarks) { a, b -> - a.imageUrl == b.imageUrl - } + return bookmarks == other.bookmarks } override fun hashCode(): Int { var result = manga.hashCode() - result = 31 * result + bookmarks.sumOf { it.imageUrl.hashCode() } + result = 31 * result + bookmarks.hashCode() return result } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/FavouriteCategory.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/FavouriteCategory.kt index 307cb50cd..e2004f11d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/FavouriteCategory.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/FavouriteCategory.kt @@ -2,8 +2,10 @@ package org.koitharu.kotatsu.core.model import android.os.Parcelable import kotlinx.parcelize.Parcelize +import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.SortOrder -import java.util.* +import java.util.Date @Parcelize data class FavouriteCategory( @@ -14,4 +16,20 @@ data class FavouriteCategory( val createdAt: Date, val isTrackingEnabled: Boolean, val isVisibleInLibrary: Boolean, -) : Parcelable \ No newline at end of file +) : Parcelable, ListModel { + + override fun areItemsTheSame(other: ListModel): Boolean { + return other is FavouriteCategory && id == other.id + } + + override fun getChangePayload(previousState: ListModel): Any? { + if (previousState !is FavouriteCategory) { + return null + } + return if (isTrackingEnabled != previousState.isTrackingEnabled || isVisibleInLibrary != isVisibleInLibrary) { + ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED + } else { + null + } + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseListAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseListAdapter.kt index 12ae09f87..6701944ce 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseListAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseListAdapter.kt @@ -12,24 +12,24 @@ import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel import kotlin.coroutines.suspendCoroutine -open class BaseListAdapter( - vararg delegates: AdapterDelegate>, -) : AsyncListDifferDelegationAdapter( - AsyncDifferConfig.Builder(ListModelDiffCallback) +open class BaseListAdapter( + vararg delegates: AdapterDelegate>, +) : AsyncListDifferDelegationAdapter( + AsyncDifferConfig.Builder(ListModelDiffCallback()) .setBackgroundThreadExecutor(Dispatchers.Default.limitedParallelism(2).asExecutor()) .build(), *delegates, -), FlowCollector> { +), FlowCollector> { - override suspend fun emit(value: List) = suspendCoroutine { cont -> + override suspend fun emit(value: List) = suspendCoroutine { cont -> setItems(value, ContinuationResumeRunnable(cont)) } - fun addListListener(listListener: ListListener) { + fun addListListener(listListener: ListListener) { differ.addListListener(listListener) } - fun removeListListener(listListener: ListListener) { + fun removeListListener(listListener: ListListener) { differ.removeListListener(listListener) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index eb71185e0..d4e3e87c3 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -47,6 +47,7 @@ import org.koitharu.kotatsu.history.data.PROGRESS_NONE import org.koitharu.kotatsu.image.ui.ImageActivity import org.koitharu.kotatsu.list.domain.ListExtraProvider import org.koitharu.kotatsu.list.ui.adapter.mangaGridItemAD +import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.MangaItemModel import org.koitharu.kotatsu.list.ui.size.StaticItemSizeResolver import org.koitharu.kotatsu.main.ui.owners.NoModalBottomSheetOwner @@ -207,7 +208,9 @@ class DetailsFragment : return } val rv = viewBinding?.recyclerViewRelated ?: return - val adapter = (rv.adapter as? BaseListAdapter) ?: BaseListAdapter( + + @Suppress("UNCHECKED_CAST") + val adapter = (rv.adapter as? BaseListAdapter) ?: BaseListAdapter( mangaGridItemAD( coil, viewLifecycleOwner, StaticItemSizeResolver(resources.getDimensionPixelSize(R.dimen.smaller_grid_width)), diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChaptersAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChaptersAdapter.kt index d1de826d9..2cc6f1f9f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChaptersAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChaptersAdapter.kt @@ -1,16 +1,14 @@ package org.koitharu.kotatsu.details.ui.adapter import android.content.Context -import androidx.recyclerview.widget.DiffUtil -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller import org.koitharu.kotatsu.details.ui.model.ChapterListItem -import kotlin.jvm.internal.Intrinsics class ChaptersAdapter( onItemClickListener: OnListItemClickListener, -) : AsyncListDifferDelegationAdapter(DiffCallback()), FastScroller.SectionIndexer { +) : BaseListAdapter(), FastScroller.SectionIndexer { init { setHasStableIds(true) @@ -21,27 +19,6 @@ class ChaptersAdapter( return items[position].chapter.id } - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: ChapterListItem, newItem: ChapterListItem): Boolean { - return oldItem.chapter.id == newItem.chapter.id - } - - override fun areContentsTheSame( - oldItem: ChapterListItem, - newItem: ChapterListItem - ): Boolean { - return Intrinsics.areEqual(oldItem, newItem) - } - - override fun getChangePayload(oldItem: ChapterListItem, newItem: ChapterListItem): Any? { - if (oldItem.flags != newItem.flags && oldItem.chapter == newItem.chapter) { - return newItem.flags - } - return null - } - } - override fun getSectionText(context: Context, position: Int): CharSequence? { val item = items.getOrNull(position) ?: return null return item.chapter.number.toString() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt index 5c3cfd46e..cece102e9 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt @@ -1,13 +1,14 @@ package org.koitharu.kotatsu.details.ui.model import android.text.format.DateUtils +import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.MangaChapter class ChapterListItem( val chapter: MangaChapter, val flags: Int, private val uploadDateMs: Long, -) { +) : ListModel { var uploadDate: CharSequence? = null private set @@ -50,6 +51,21 @@ class ChapterListItem( return (flags and flag) == flag } + override fun areItemsTheSame(other: ListModel): Boolean { + return other is ChapterListItem && chapter.id == other.chapter.id + } + + override fun getChangePayload(previousState: ListModel): Any? { + if (previousState !is ChapterListItem) { + return super.getChangePayload(previousState) + } + return if (chapter == previousState.chapter && flags != previousState.flags) { + flags + } else { + super.getChangePayload(previousState) + } + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrollingInfoAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrollingInfoAdapter.kt index b63a5f790..aa36cb8c1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrollingInfoAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/scrobbling/ScrollingInfoAdapter.kt @@ -3,15 +3,14 @@ package org.koitharu.kotatsu.details.ui.scrobbling import androidx.fragment.app.FragmentManager import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.list.ui.model.ListModel class ScrollingInfoAdapter( lifecycleOwner: LifecycleOwner, coil: ImageLoader, fragmentManager: FragmentManager, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(scrobblingInfoAD(lifecycleOwner, coil, fragmentManager)) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsAdapter.kt index c08e21395..d1f9b1ab1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsAdapter.kt @@ -2,8 +2,7 @@ package org.koitharu.kotatsu.download.ui.list import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD @@ -13,7 +12,7 @@ class DownloadsAdapter( lifecycleOwner: LifecycleOwner, coil: ImageLoader, listener: DownloadItemListener, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(ITEM_TYPE_DOWNLOAD, downloadItemAD(lifecycleOwner, coil, listener)) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapter.kt index 66e5fc939..ca5942f9a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/explore/ui/adapter/ExploreAdapter.kt @@ -2,10 +2,9 @@ package org.koitharu.kotatsu.explore.ui.adapter import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.explore.ui.model.MangaSourceItem -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.adapter.emptyHintAD import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD @@ -16,7 +15,7 @@ class ExploreAdapter( lifecycleOwner: LifecycleOwner, listener: ExploreListEventListener, clickListener: OnListItemClickListener, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback) { +) : BaseListAdapter() { init { delegatesManager diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/adapter/CategoriesAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/adapter/CategoriesAdapter.kt index 30a8e8fc5..7e0412abc 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/adapter/CategoriesAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/adapter/CategoriesAdapter.kt @@ -2,9 +2,8 @@ package org.koitharu.kotatsu.favourites.ui.categories.adapter import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.favourites.ui.categories.FavouriteCategoriesListListener -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD @@ -15,7 +14,7 @@ class CategoriesAdapter( lifecycleOwner: LifecycleOwner, onItemClickListener: FavouriteCategoriesListListener, listListener: ListStateHolderListener, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(categoryAD(coil, lifecycleOwner, onItemClickListener)) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoriesAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoriesAdapter.kt index e0578cf56..e8ab695a4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoriesAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoriesAdapter.kt @@ -1,44 +1,16 @@ package org.koitharu.kotatsu.favourites.ui.categories.select.adapter -import androidx.recyclerview.widget.DiffUtil -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener -import org.koitharu.kotatsu.favourites.ui.categories.select.model.CategoriesHeaderItem import org.koitharu.kotatsu.favourites.ui.categories.select.model.MangaCategoryItem import org.koitharu.kotatsu.list.ui.model.ListModel class MangaCategoriesAdapter( clickListener: OnListItemClickListener, -) : AsyncListDifferDelegationAdapter(DiffCallback()) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(mangaCategoryAD(clickListener)) .addDelegate(categoriesHeaderAD()) } - - private class DiffCallback : DiffUtil.ItemCallback() { - override fun areItemsTheSame( - oldItem: ListModel, - newItem: ListModel, - ): Boolean = when { - oldItem is MangaCategoryItem && newItem is MangaCategoryItem -> oldItem.id == newItem.id - oldItem is CategoriesHeaderItem && newItem is CategoriesHeaderItem -> oldItem == newItem - else -> false - } - - override fun areContentsTheSame( - oldItem: ListModel, - newItem: ListModel, - ): Boolean = oldItem == newItem - - override fun getChangePayload( - oldItem: ListModel, - newItem: ListModel, - ): Any? { - if (oldItem is MangaCategoryItem && newItem is MangaCategoryItem && oldItem.isChecked != newItem.isChecked) { - return newItem.isChecked - } - return super.getChangePayload(oldItem, newItem) - } - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt index 05f4b7505..aaf5b358d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/select/adapter/MangaCategoryAD.kt @@ -2,8 +2,10 @@ package org.koitharu.kotatsu.favourites.ui.categories.select.adapter import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.util.ext.setChecked import org.koitharu.kotatsu.databinding.ItemCheckableNewBinding import org.koitharu.kotatsu.favourites.ui.categories.select.model.MangaCategoryItem +import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel fun mangaCategoryAD( @@ -16,10 +18,10 @@ fun mangaCategoryAD( clickListener.onItemClick(item, itemView) } - bind { + bind { payloads -> with(binding.root) { text = item.name - isChecked = item.isChecked + setChecked(item.isChecked, ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED in payloads) } } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerAdapter.kt index 3265db964..8e9f6549d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerAdapter.kt @@ -4,7 +4,6 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.AdapterListUpdateCallback import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.AsyncListDiffer -import androidx.recyclerview.widget.DiffUtil import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator.TabConfigurationStrategy @@ -13,6 +12,7 @@ import kotlinx.coroutines.asExecutor import kotlinx.coroutines.flow.FlowCollector import org.koitharu.kotatsu.core.util.ContinuationResumeRunnable import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment +import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import kotlin.coroutines.suspendCoroutine class FavouritesContainerAdapter(fragment: Fragment) : @@ -22,7 +22,7 @@ class FavouritesContainerAdapter(fragment: Fragment) : private val differ = AsyncListDiffer( AdapterListUpdateCallback(this), - AsyncDifferConfig.Builder(DiffCallback()) + AsyncDifferConfig.Builder(ListModelDiffCallback()) .setBackgroundThreadExecutor(Dispatchers.Default.limitedParallelism(2).asExecutor()) .build(), ) @@ -51,15 +51,4 @@ class FavouritesContainerAdapter(fragment: Fragment) : override suspend fun emit(value: List) = suspendCoroutine { cont -> differ.submitList(value, ContinuationResumeRunnable(cont)) } - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: FavouriteTabModel, newItem: FavouriteTabModel): Boolean { - return oldItem.id == newItem.id - } - - override fun areContentsTheSame(oldItem: FavouriteTabModel, newItem: FavouriteTabModel): Boolean { - return oldItem == newItem - } - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerViewModel.kt index 1b87b8139..00d9644e1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/container/FavouritesContainerViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.plus import org.koitharu.kotatsu.core.ui.BaseViewModel @@ -18,5 +19,6 @@ class FavouritesContainerViewModel @Inject constructor( val categories = favouritesRepository.observeCategories() .mapItems { FavouriteTabModel(it.id, it.title) } + .distinctUntilChanged() .stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList()) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterAdapter.kt index ae1a9b9ef..e17c4b4eb 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterAdapter.kt @@ -2,7 +2,7 @@ package org.koitharu.kotatsu.filter.ui import android.content.Context import androidx.recyclerview.widget.AsyncListDiffer.ListListener -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller import org.koitharu.kotatsu.filter.ui.model.FilterItem import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD @@ -13,7 +13,7 @@ import org.koitharu.kotatsu.list.ui.model.ListModel class FilterAdapter( listener: OnFilterChangedListener, listListener: ListListener, -) : AsyncListDifferDelegationAdapter(FilterDiffCallback()), FastScroller.SectionIndexer { +) : BaseListAdapter(), FastScroller.SectionIndexer { init { delegatesManager.addDelegate(filterSortDelegate(listener)).addDelegate(filterTagDelegate(listener)) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterDiffCallback.kt b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterDiffCallback.kt deleted file mode 100644 index d3319c431..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterDiffCallback.kt +++ /dev/null @@ -1,52 +0,0 @@ -package org.koitharu.kotatsu.filter.ui - -import androidx.recyclerview.widget.DiffUtil -import org.koitharu.kotatsu.filter.ui.model.FilterItem -import org.koitharu.kotatsu.list.ui.model.ListHeader -import org.koitharu.kotatsu.list.ui.model.ListModel - -class FilterDiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return when { - oldItem === newItem -> true - oldItem.javaClass != newItem.javaClass -> false - oldItem is ListHeader && newItem is ListHeader -> { - oldItem == newItem - } - - oldItem is FilterItem.Tag && newItem is FilterItem.Tag -> { - oldItem.tag == newItem.tag - } - - oldItem is FilterItem.Sort && newItem is FilterItem.Sort -> { - oldItem.order == newItem.order - } - - oldItem is FilterItem.Error && newItem is FilterItem.Error -> { - oldItem.textResId == newItem.textResId - } - - else -> false - } - } - - override fun areContentsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return oldItem == newItem - } - - override fun getChangePayload(oldItem: ListModel, newItem: ListModel): Any? { - val hasPayload = when { - oldItem is FilterItem.Tag && newItem is FilterItem.Tag -> { - oldItem.isChecked != newItem.isChecked - } - - oldItem is FilterItem.Sort && newItem is FilterItem.Sort -> { - oldItem.isSelected != newItem.isSelected - } - - else -> false - } - return if (hasPayload) Unit else super.getChangePayload(oldItem, newItem) - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterSheetFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterSheetFragment.kt index 1d31d888d..91686145a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterSheetFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/filter/ui/FilterSheetFragment.kt @@ -31,7 +31,7 @@ class FilterSheetFragment : addSheetCallback(this) val adapter = FilterAdapter(filter, this) binding.recyclerView.adapter = adapter - filter.filterItems.observe(viewLifecycleOwner, adapter::setItems) + filter.filterItems.observe(viewLifecycleOwner, adapter) if (dialog == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { binding.recyclerView.scrollIndicators = 0 diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/ListModelDiffCallback.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/ListModelDiffCallback.kt index 80ec73d4b..5233f6668 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/ListModelDiffCallback.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/ListModelDiffCallback.kt @@ -3,20 +3,24 @@ package org.koitharu.kotatsu.list.ui import androidx.recyclerview.widget.DiffUtil import org.koitharu.kotatsu.list.ui.model.ListModel -object ListModelDiffCallback : DiffUtil.ItemCallback() { +open class ListModelDiffCallback : DiffUtil.ItemCallback() { - val PAYLOAD_CHECKED_CHANGED = Any() - val PAYLOAD_NESTED_LIST_CHANGED = Any() - - override fun areItemsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { + override fun areItemsTheSame(oldItem: T, newItem: T): Boolean { return oldItem.areItemsTheSame(newItem) } - override fun areContentsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { + override fun areContentsTheSame(oldItem: T, newItem: T): Boolean { return oldItem == newItem } - override fun getChangePayload(oldItem: ListModel, newItem: ListModel): Any? { + override fun getChangePayload(oldItem: T, newItem: T): Any? { return newItem.getChangePayload(oldItem) } + + companion object : ListModelDiffCallback() { + + val PAYLOAD_CHECKED_CHANGED = Any() + val PAYLOAD_NESTED_LIST_CHANGED = Any() + val PAYLOAD_ANYTHING_CHANGED = Any() + } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListAdapter.kt index ceffdca06..53edf1cce 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/MangaListAdapter.kt @@ -3,12 +3,13 @@ package org.koitharu.kotatsu.list.ui.adapter import androidx.lifecycle.LifecycleOwner import coil.ImageLoader import org.koitharu.kotatsu.core.ui.BaseListAdapter +import org.koitharu.kotatsu.list.ui.model.ListModel open class MangaListAdapter( coil: ImageLoader, lifecycleOwner: LifecycleOwner, listener: MangaListListener, -) : BaseListAdapter() { +) : BaseListAdapter() { init { delegatesManager diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt index 596ce6b75..b0e043dca 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAdapter.kt @@ -3,10 +3,9 @@ package org.koitharu.kotatsu.reader.ui.thumbnails.adapter import android.content.Context import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD import org.koitharu.kotatsu.list.ui.model.ListHeader @@ -17,7 +16,7 @@ class PageThumbnailAdapter( coil: ImageLoader, lifecycleOwner: LifecycleOwner, clickListener: OnListItemClickListener, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback), FastScroller.SectionIndexer { +) : BaseListAdapter(), FastScroller.SectionIndexer { init { delegatesManager.addDelegate(ITEM_TYPE_THUMBNAIL, pageThumbnailAD(coil, lifecycleOwner, clickListener)) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/adapter/ScrobblingMangaAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/adapter/ScrobblingMangaAdapter.kt index 4e0c4e913..9efa98bb5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/adapter/ScrobblingMangaAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/adapter/ScrobblingMangaAdapter.kt @@ -1,48 +1,22 @@ package org.koitharu.kotatsu.scrobbling.common.ui.config.adapter import androidx.lifecycle.LifecycleOwner -import androidx.recyclerview.widget.DiffUtil import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD -import org.koitharu.kotatsu.list.ui.model.EmptyState import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo -import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus class ScrobblingMangaAdapter( clickListener: OnListItemClickListener, coil: ImageLoader, lifecycleOwner: LifecycleOwner, -) : AsyncListDifferDelegationAdapter(DiffCallback()) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(scrobblingMangaAD(clickListener, coil, lifecycleOwner)) .addDelegate(scrobblingHeaderAD()) .addDelegate(emptyStateListAD(coil, lifecycleOwner, null)) } - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return when { - oldItem is ScrobblingInfo && newItem is ScrobblingInfo -> { - oldItem.targetId == newItem.targetId && oldItem.mangaId == newItem.mangaId - } - - oldItem is ScrobblingStatus && newItem is ScrobblingStatus -> { - oldItem.ordinal == newItem.ordinal - } - - oldItem is EmptyState && newItem is EmptyState -> true - - else -> false - } - } - - override fun areContentsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return oldItem == newItem - } - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/adapter/ScrobblerSelectorAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/adapter/ScrobblerSelectorAdapter.kt index c39a79846..b730e0790 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/adapter/ScrobblerSelectorAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/selector/adapter/ScrobblerSelectorAdapter.kt @@ -1,25 +1,21 @@ package org.koitharu.kotatsu.scrobbling.common.ui.selector.adapter import androidx.lifecycle.LifecycleOwner -import androidx.recyclerview.widget.DiffUtil import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD import org.koitharu.kotatsu.list.ui.model.ListModel -import org.koitharu.kotatsu.list.ui.model.LoadingFooter import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga -import org.koitharu.kotatsu.scrobbling.common.ui.selector.model.ScrobblerHint -import kotlin.jvm.internal.Intrinsics class ScrobblerSelectorAdapter( lifecycleOwner: LifecycleOwner, coil: ImageLoader, clickListener: OnListItemClickListener, stateHolderListener: ListStateHolderListener, -) : AsyncListDifferDelegationAdapter(DiffCallback()) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(loadingStateAD()) @@ -27,21 +23,4 @@ class ScrobblerSelectorAdapter( .addDelegate(loadingFooterAD()) .addDelegate(scrobblerHintAD(stateHolderListener)) } - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return when { - oldItem === newItem -> true - oldItem is ScrobblerManga && newItem is ScrobblerManga -> oldItem.id == newItem.id - oldItem is ScrobblerHint && newItem is ScrobblerHint -> oldItem.textPrimary == newItem.textPrimary - oldItem is LoadingFooter && newItem is LoadingFooter -> oldItem.key == newItem.key - else -> false - } - } - - override fun areContentsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return Intrinsics.areEqual(oldItem, newItem) - } - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/adapter/MultiSearchAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/adapter/MultiSearchAdapter.kt index 099bda6ac..dd86aa7c0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/adapter/MultiSearchAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/adapter/MultiSearchAdapter.kt @@ -1,10 +1,9 @@ package org.koitharu.kotatsu.search.ui.multi.adapter import androidx.lifecycle.LifecycleOwner -import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView.RecycledViewPool import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.list.ui.MangaSelectionDecoration import org.koitharu.kotatsu.list.ui.adapter.MangaListListener @@ -13,10 +12,8 @@ import org.koitharu.kotatsu.list.ui.adapter.errorStateListAD import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD import org.koitharu.kotatsu.list.ui.model.ListModel -import org.koitharu.kotatsu.list.ui.model.LoadingFooter import org.koitharu.kotatsu.list.ui.size.ItemSizeResolver import org.koitharu.kotatsu.search.ui.multi.MultiSearchListModel -import kotlin.jvm.internal.Intrinsics class MultiSearchAdapter( lifecycleOwner: LifecycleOwner, @@ -25,7 +22,7 @@ class MultiSearchAdapter( itemClickListener: OnListItemClickListener, sizeResolver: ItemSizeResolver, selectionDecoration: MangaSelectionDecoration, -) : AsyncListDifferDelegationAdapter(DiffCallback()) { +) : BaseListAdapter() { init { val pool = RecycledViewPool() @@ -46,25 +43,4 @@ class MultiSearchAdapter( .addDelegate(emptyStateListAD(coil, lifecycleOwner, listener)) .addDelegate(errorStateListAD(listener)) } - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return when { - oldItem is MultiSearchListModel && newItem is MultiSearchListModel -> { - oldItem.source == newItem.source - } - - oldItem is LoadingFooter && newItem is LoadingFooter -> { - oldItem.key == newItem.key - } - - else -> oldItem.javaClass == newItem.javaClass - } - } - - override fun areContentsTheSame(oldItem: ListModel, newItem: ListModel): Boolean { - return Intrinsics.areEqual(oldItem, newItem) - } - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt index 121ef63f7..bd255e3cd 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionAdapter.kt @@ -1,12 +1,10 @@ package org.koitharu.kotatsu.search.ui.suggestion.adapter import androidx.lifecycle.LifecycleOwner -import androidx.recyclerview.widget.DiffUtil import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem -import kotlin.jvm.internal.Intrinsics const val SEARCH_SUGGESTION_ITEM_TYPE_QUERY = 0 @@ -14,7 +12,7 @@ class SearchSuggestionAdapter( coil: ImageLoader, lifecycleOwner: LifecycleOwner, listener: SearchSuggestionListener, -) : AsyncListDifferDelegationAdapter(DiffCallback()) { +) : BaseListAdapter() { init { delegatesManager @@ -23,35 +21,4 @@ class SearchSuggestionAdapter( .addDelegate(searchSuggestionTagsAD(listener)) .addDelegate(searchSuggestionMangaListAD(coil, lifecycleOwner, listener)) } - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame( - oldItem: SearchSuggestionItem, - newItem: SearchSuggestionItem, - ): Boolean = when { - oldItem is SearchSuggestionItem.RecentQuery && newItem is SearchSuggestionItem.RecentQuery -> { - oldItem.query == newItem.query - } - oldItem is SearchSuggestionItem.Source && newItem is SearchSuggestionItem.Source -> { - oldItem.source == newItem.source - } - else -> oldItem.javaClass == newItem.javaClass - } - - override fun areContentsTheSame( - oldItem: SearchSuggestionItem, - newItem: SearchSuggestionItem, - ): Boolean = Intrinsics.areEqual(oldItem, newItem) - - override fun getChangePayload(oldItem: SearchSuggestionItem, newItem: SearchSuggestionItem): Any? { - return when { - oldItem is SearchSuggestionItem.MangaList && newItem is SearchSuggestionItem.MangaList -> Unit - oldItem is SearchSuggestionItem.Source && newItem is SearchSuggestionItem.Source -> { - if (oldItem.isEnabled != newItem.isEnabled) Unit else super.getChangePayload(oldItem, newItem) - } - else -> super.getChangePayload(oldItem, newItem) - } - } - } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt index 8d720e2d1..3f00c91b7 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/suggestion/model/SearchSuggestionItem.kt @@ -1,16 +1,22 @@ package org.koitharu.kotatsu.search.ui.suggestion.model import org.koitharu.kotatsu.core.ui.widgets.ChipsView +import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.areItemsEquals -sealed interface SearchSuggestionItem { +sealed interface SearchSuggestionItem : ListModel { class MangaList( val items: List, ) : SearchSuggestionItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is MangaList + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -35,6 +41,10 @@ sealed interface SearchSuggestionItem { val query: String, ) : SearchSuggestionItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is RecentQuery && query == other.query + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -54,6 +64,21 @@ sealed interface SearchSuggestionItem { val isEnabled: Boolean, ) : SearchSuggestionItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is Source && other.source == source + } + + override fun getChangePayload(previousState: ListModel): Any? { + if (previousState !is Source) { + return super.getChangePayload(previousState) + } + return if (isEnabled != previousState.isEnabled) { + ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED + } else { + null + } + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -75,6 +100,14 @@ sealed interface SearchSuggestionItem { val tags: List, ) : SearchSuggestionItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is Tags + } + + override fun getChangePayload(previousState: ListModel): Any { + return ListModelDiffCallback.PAYLOAD_NESTED_LIST_CHANGED + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/newsources/SourcesSelectAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/newsources/SourcesSelectAdapter.kt index 17b7aaf0d..6f9039bac 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/newsources/SourcesSelectAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/newsources/SourcesSelectAdapter.kt @@ -2,8 +2,7 @@ package org.koitharu.kotatsu.settings.newsources import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter -import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigDiffCallback +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigListener import org.koitharu.kotatsu.settings.sources.adapter.sourceConfigItemCheckableDelegate import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem @@ -12,7 +11,6 @@ class SourcesSelectAdapter( listener: SourceConfigListener, coil: ImageLoader, lifecycleOwner: LifecycleOwner, -) : AsyncListDifferDelegationAdapter( - SourceConfigDiffCallback(), +) : BaseListAdapter( sourceConfigItemCheckableDelegate(listener, coil, lifecycleOwner), ) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/adapter/SourceLocalesAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/adapter/SourceLocalesAdapter.kt index 0bfac9dda..a90329b74 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/adapter/SourceLocalesAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/adapter/SourceLocalesAdapter.kt @@ -1,27 +1,13 @@ package org.koitharu.kotatsu.settings.onboard.adapter -import androidx.recyclerview.widget.DiffUtil -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.settings.onboard.model.SourceLocale class SourceLocalesAdapter( listener: SourceLocaleListener, -) : AsyncListDifferDelegationAdapter(DiffCallback()) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(sourceLocaleAD(listener)) } - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame( - oldItem: SourceLocale, - newItem: SourceLocale, - ): Boolean = oldItem.key == newItem.key - - override fun areContentsTheSame( - oldItem: SourceLocale, - newItem: SourceLocale, - ): Boolean = oldItem == newItem - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/model/SourceLocale.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/model/SourceLocale.kt index e4f8aefa8..ff8ea75c3 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/model/SourceLocale.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/onboard/model/SourceLocale.kt @@ -1,5 +1,7 @@ package org.koitharu.kotatsu.settings.onboard.model +import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.list.ui.model.ListModel import java.util.Locale data class SourceLocale( @@ -7,7 +9,19 @@ data class SourceLocale( val title: String?, val summary: String?, val isChecked: Boolean, -) : Comparable { +) : ListModel, Comparable { + + override fun areItemsTheSame(other: ListModel): Boolean { + return other is SourceLocale && key == other.key + } + + override fun getChangePayload(previousState: ListModel): Any? { + return if (previousState is SourceLocale && previousState.isChecked != isChecked) { + ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED + } else { + super.getChangePayload(previousState) + } + } override fun compareTo(other: SourceLocale): Int { return when { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapter.kt index 2c6be9c77..ef10593e4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigAdapter.kt @@ -2,15 +2,14 @@ package org.koitharu.kotatsu.settings.sources.adapter import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem class SourceConfigAdapter( listener: SourceConfigListener, coil: ImageLoader, lifecycleOwner: LifecycleOwner, -) : AsyncListDifferDelegationAdapter( - SourceConfigDiffCallback(), +) : BaseListAdapter( sourceConfigHeaderDelegate(), sourceConfigGroupDelegate(listener), sourceConfigItemDelegate2(listener, coil, lifecycleOwner), diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigDiffCallback.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigDiffCallback.kt deleted file mode 100644 index 9f57bca90..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/adapter/SourceConfigDiffCallback.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.koitharu.kotatsu.settings.sources.adapter - -import androidx.recyclerview.widget.DiffUtil -import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem -import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem.EmptySearchResult -import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem.Header -import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem.LocaleGroup -import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem.SourceItem - -class SourceConfigDiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: SourceConfigItem, newItem: SourceConfigItem): Boolean { - return when { - oldItem.javaClass != newItem.javaClass -> false - oldItem is LocaleGroup && newItem is LocaleGroup -> { - oldItem.localeId == newItem.localeId - } - - oldItem is SourceItem && newItem is SourceItem -> { - oldItem.source == newItem.source - } - - oldItem is Header && newItem is Header -> { - oldItem.titleResId == newItem.titleResId - } - - oldItem == EmptySearchResult && newItem == EmptySearchResult -> { - true - } - - oldItem is SourceConfigItem.Tip && newItem is SourceConfigItem.Tip -> { - oldItem.key == newItem.key - } - - else -> false - } - } - - override fun areContentsTheSame(oldItem: SourceConfigItem, newItem: SourceConfigItem): Boolean { - return oldItem == newItem - } - - override fun getChangePayload(oldItem: SourceConfigItem, newItem: SourceConfigItem) = Unit -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt index f178bffd9..2a00fb86e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/model/SourceConfigItem.kt @@ -2,14 +2,20 @@ package org.koitharu.kotatsu.settings.sources.model import androidx.annotation.DrawableRes import androidx.annotation.StringRes +import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.MangaSource -sealed interface SourceConfigItem { +sealed interface SourceConfigItem : ListModel { class Header( @StringRes val titleResId: Int, ) : SourceConfigItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is Header && other.titleResId == titleResId + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -26,6 +32,18 @@ sealed interface SourceConfigItem { val isExpanded: Boolean, ) : SourceConfigItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is LocaleGroup && other.localeId == localeId + } + + override fun getChangePayload(previousState: ListModel): Any? { + return if (previousState is LocaleGroup && previousState.isExpanded != isExpanded) { + ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED + } else { + super.getChangePayload(previousState) + } + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -54,6 +72,18 @@ sealed interface SourceConfigItem { val isDraggable: Boolean, ) : SourceConfigItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is SourceItem && other.source == source + } + + override fun getChangePayload(previousState: ListModel): Any? { + return if (previousState is SourceItem && previousState.isEnabled != isEnabled) { + ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED + } else { + super.getChangePayload(previousState) + } + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -83,6 +113,10 @@ sealed interface SourceConfigItem { @StringRes val textResId: Int, ) : SourceConfigItem { + override fun areItemsTheSame(other: ListModel): Boolean { + return other is Tip && other.key == key + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -104,5 +138,14 @@ sealed interface SourceConfigItem { } } - object EmptySearchResult : SourceConfigItem + object EmptySearchResult : SourceConfigItem { + + override fun equals(other: Any?): Boolean { + return other === EmptySearchResult + } + + override fun areItemsTheSame(other: ListModel): Boolean { + return other is EmptySearchResult + } + } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigAdapter.kt index af0ebbf85..8b811c710 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/categories/TrackerCategoriesConfigAdapter.kt @@ -1,32 +1,11 @@ package org.koitharu.kotatsu.settings.tracker.categories -import androidx.recyclerview.widget.DiffUtil -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener class TrackerCategoriesConfigAdapter( listener: OnListItemClickListener, -) : AsyncListDifferDelegationAdapter(DiffCallback()) { - - init { - delegatesManager.addDelegate(trackerCategoryAD(listener)) - } - - class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: FavouriteCategory, newItem: FavouriteCategory): Boolean { - return oldItem.id == newItem.id - } - - override fun areContentsTheSame(oldItem: FavouriteCategory, newItem: FavouriteCategory): Boolean { - return oldItem.isTrackingEnabled == newItem.isTrackingEnabled && oldItem.title == newItem.title - } - - override fun getChangePayload(oldItem: FavouriteCategory, newItem: FavouriteCategory): Any? { - return if (oldItem.isTrackingEnabled == newItem.isTrackingEnabled) { - super.getChangePayload(oldItem, newItem) - } else Unit - } - } -} +) : BaseListAdapter( + trackerCategoryAD(listener), +) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/adapter/ShelfAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/adapter/ShelfAdapter.kt index 7380f4164..e27568d14 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/adapter/ShelfAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/adapter/ShelfAdapter.kt @@ -4,11 +4,10 @@ import android.content.Context import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.NestedScrollStateHandle import org.koitharu.kotatsu.core.ui.list.SectionedSelectionController import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.adapter.emptyHintAD import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.errorStateListAD @@ -25,7 +24,7 @@ class ShelfAdapter( sizeResolver: ItemSizeResolver, selectionController: SectionedSelectionController, nestedScrollStateHandle: NestedScrollStateHandle, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback), FastScroller.SectionIndexer { +) : BaseListAdapter(), FastScroller.SectionIndexer { init { val pool = RecyclerView.RecycledViewPool() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/config/ShelfSettingsAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/config/ShelfSettingsAdapter.kt index 3e8c4287d..8a9f49ea4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/config/ShelfSettingsAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/shelf/ui/config/ShelfSettingsAdapter.kt @@ -1,12 +1,11 @@ package org.koitharu.kotatsu.shelf.ui.config -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.list.ui.model.ListModel class ShelfSettingsAdapter( listener: ShelfSettingsListener, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(shelfCategoryAD(listener)) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/adapter/FeedAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/adapter/FeedAdapter.kt index f4c27b9cb..1f214a64c 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/adapter/FeedAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/feed/adapter/FeedAdapter.kt @@ -3,9 +3,8 @@ package org.koitharu.kotatsu.tracker.ui.feed.adapter import android.content.Context import androidx.lifecycle.LifecycleOwner import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller -import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.adapter.MangaListListener import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD import org.koitharu.kotatsu.list.ui.adapter.errorFooterAD @@ -20,7 +19,7 @@ class FeedAdapter( coil: ImageLoader, lifecycleOwner: LifecycleOwner, listener: MangaListListener, -) : AsyncListDifferDelegationAdapter(ListModelDiffCallback), FastScroller.SectionIndexer { +) : BaseListAdapter(), FastScroller.SectionIndexer { init { delegatesManager.addDelegate(ITEM_TYPE_FEED, feedItemAD(coil, lifecycleOwner, listener)) @@ -52,6 +51,5 @@ class FeedAdapter( const val ITEM_TYPE_ERROR_FOOTER = 4 const val ITEM_TYPE_EMPTY = 5 const val ITEM_TYPE_HEADER = 6 - const val ITEM_TYPE_DATE_HEADER = 7 } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/adapter/CategorySelectAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/adapter/CategorySelectAdapter.kt index 10fac5806..0bd0a6789 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/adapter/CategorySelectAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/adapter/CategorySelectAdapter.kt @@ -1,33 +1,14 @@ package org.koitharu.kotatsu.widget.shelf.adapter -import androidx.recyclerview.widget.DiffUtil -import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter +import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener import org.koitharu.kotatsu.widget.shelf.model.CategoryItem class CategorySelectAdapter( clickListener: OnListItemClickListener -) : AsyncListDifferDelegationAdapter(DiffCallback()) { +) : BaseListAdapter() { init { delegatesManager.addDelegate(categorySelectItemAD(clickListener)) } - - private class DiffCallback : DiffUtil.ItemCallback() { - - override fun areItemsTheSame(oldItem: CategoryItem, newItem: CategoryItem): Boolean { - return oldItem.id == newItem.id - } - - override fun areContentsTheSame(oldItem: CategoryItem, newItem: CategoryItem): Boolean { - return oldItem == newItem - } - - override fun getChangePayload(oldItem: CategoryItem, newItem: CategoryItem): Any? { - if (oldItem.isSelected != newItem.isSelected) { - return newItem.isSelected - } - return super.getChangePayload(oldItem, newItem) - } - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/model/CategoryItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/model/CategoryItem.kt index 0407dd18a..82e5082a0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/model/CategoryItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/model/CategoryItem.kt @@ -1,7 +1,23 @@ package org.koitharu.kotatsu.widget.shelf.model +import org.koitharu.kotatsu.list.ui.ListModelDiffCallback +import org.koitharu.kotatsu.list.ui.model.ListModel + data class CategoryItem( val id: Long, val name: String?, val isSelected: Boolean -) \ No newline at end of file +) : ListModel { + + override fun areItemsTheSame(other: ListModel): Boolean { + return other is CategoryItem && other.id == id + } + + override fun getChangePayload(previousState: ListModel): Any? { + return if (previousState is CategoryItem && previousState.isSelected != isSelected) { + ListModelDiffCallback.PAYLOAD_CHECKED_CHANGED + } else { + null + } + } +} diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7ed21fa7f..bd8e20b18 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -74,6 +74,7 @@