From b10780118834fb8a0025e3faf904399192b19575 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 31 Jul 2023 11:28:46 +0300 Subject: [PATCH] Update bookmarks list screen --- .../kotatsu/bookmarks/data/BookmarksDao.kt | 8 +- .../bookmarks/domain/BookmarksRepository.kt | 14 +- .../kotatsu/bookmarks/ui/BookmarksFragment.kt | 129 +++++++++--------- .../bookmarks/ui/BookmarksViewModel.kt | 18 ++- .../bookmarks/ui/adapter/BookmarksGroupAD.kt | 69 ---------- .../ui/adapter/BookmarksGroupAdapter.kt | 46 ------- .../bookmarks/ui/model/BookmarksGroup.kt | 41 ------ .../bookmarks/ui/sheet/BookmarksAdapter.kt | 6 +- .../bookmarks/ui/sheet/BookmarksSheet.kt | 1 + .../kotatsu/core/ui/BaseListAdapter.kt | 3 +- .../kotatsu/details/ui/model/MangaBranch.kt | 1 - .../search/ui/multi/MultiSearchListModel.kt | 1 - 12 files changed, 100 insertions(+), 237 deletions(-) delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAD.kt delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAdapter.kt delete mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/model/BookmarksGroup.kt diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/BookmarksDao.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/BookmarksDao.kt index 173e0e444..d38ee4f71 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/BookmarksDao.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/data/BookmarksDao.kt @@ -12,9 +12,12 @@ import org.koitharu.kotatsu.core.db.entity.MangaWithTags @Dao abstract class BookmarksDao { - @Query("SELECT * FROM bookmarks WHERE manga_id = :mangaId AND page_id = :pageId ORDER BY percent") + @Query("SELECT * FROM bookmarks WHERE manga_id = :mangaId AND page_id = :pageId") abstract suspend fun find(mangaId: Long, pageId: Long): BookmarkEntity? + @Query("SELECT * FROM bookmarks WHERE page_id = :pageId") + abstract suspend fun find(pageId: Long): BookmarkEntity? + @Transaction @Query( "SELECT * FROM manga JOIN bookmarks ON bookmarks.manga_id = manga.manga_id ORDER BY percent", @@ -42,6 +45,9 @@ abstract class BookmarksDao { @Query("DELETE FROM bookmarks WHERE manga_id = :mangaId AND page_id = :pageId") abstract suspend fun delete(mangaId: Long, pageId: Long): Int + @Query("DELETE FROM bookmarks WHERE page_id = :pageId") + abstract suspend fun delete(pageId: Long): Int + @Query("DELETE FROM bookmarks WHERE manga_id = :mangaId AND chapter_id = :chapterId AND page = :page") abstract suspend fun delete(mangaId: Long, chapterId: Long, page: Int): Int diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/BookmarksRepository.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/BookmarksRepository.kt index fab2180f3..a8379c9aa 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/BookmarksRepository.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/domain/BookmarksRepository.kt @@ -62,18 +62,16 @@ class BookmarksRepository @Inject constructor( removeBookmark(bookmark.manga.id, bookmark.chapterId, bookmark.page) } - suspend fun removeBookmarks(ids: Map>): ReversibleHandle { + suspend fun removeBookmarks(ids: Set): ReversibleHandle { val entities = ArrayList(ids.size) db.withTransaction { val dao = db.bookmarksDao - for ((manga, idSet) in ids) { - for (pageId in idSet) { - val e = dao.find(manga.id, pageId) - if (e != null) { - entities.add(e) - } - dao.delete(manga.id, pageId) + for (pageId in ids) { + val e = dao.find(pageId) + if (e != null) { + entities.add(e) } + dao.delete(pageId) } } return BookmarksRestorer(entities) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksFragment.kt index cbc9656f0..e14c5eceb 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksFragment.kt @@ -12,31 +12,32 @@ import androidx.core.graphics.Insets import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.fragment.app.viewModels +import androidx.recyclerview.widget.GridLayoutManager import coil.ImageLoader import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.bookmarks.data.ids import org.koitharu.kotatsu.bookmarks.domain.Bookmark -import org.koitharu.kotatsu.bookmarks.ui.adapter.BookmarksGroupAdapter -import org.koitharu.kotatsu.bookmarks.ui.model.BookmarksGroup +import org.koitharu.kotatsu.bookmarks.ui.sheet.BookmarksAdapter import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver +import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.ui.BaseFragment +import org.koitharu.kotatsu.core.ui.list.ListSelectionController import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener -import org.koitharu.kotatsu.core.ui.list.SectionedSelectionController -import org.koitharu.kotatsu.core.ui.list.decor.AbstractSelectionItemDecoration -import org.koitharu.kotatsu.core.ui.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.core.ui.list.fastscroll.FastScroller import org.koitharu.kotatsu.core.ui.util.ReversibleAction import org.koitharu.kotatsu.core.ui.util.reverseAsync -import org.koitharu.kotatsu.core.util.ext.invalidateNestedItemDecorations import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf import org.koitharu.kotatsu.databinding.FragmentListSimpleBinding import org.koitharu.kotatsu.details.ui.DetailsActivity +import org.koitharu.kotatsu.list.ui.MangaListSpanResolver +import org.koitharu.kotatsu.list.ui.adapter.ListHeaderClickListener +import org.koitharu.kotatsu.list.ui.adapter.ListItemType import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener -import org.koitharu.kotatsu.list.ui.model.ListModel +import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration +import org.koitharu.kotatsu.list.ui.model.ListHeader import org.koitharu.kotatsu.main.ui.owners.AppBarOwner import org.koitharu.kotatsu.main.ui.owners.SnackbarOwner import org.koitharu.kotatsu.parsers.model.Manga @@ -48,15 +49,18 @@ class BookmarksFragment : BaseFragment(), ListStateHolderListener, OnListItemClickListener, - SectionedSelectionController.Callback, - FastScroller.FastScrollListener { + ListSelectionController.Callback2, + FastScroller.FastScrollListener, ListHeaderClickListener { @Inject lateinit var coil: ImageLoader + @Inject + lateinit var settings: AppSettings + private val viewModel by viewModels() - private var adapter: BookmarksGroupAdapter? = null - private var selectionController: SectionedSelectionController? = null + private var bookmarksAdapter: BookmarksAdapter? = null + private var selectionController: ListSelectionController? = null override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentListSimpleBinding { return FragmentListSimpleBinding.inflate(inflater, container, false) @@ -64,37 +68,46 @@ class BookmarksFragment : override fun onViewBindingCreated(binding: FragmentListSimpleBinding, savedInstanceState: Bundle?) { super.onViewBindingCreated(binding, savedInstanceState) - selectionController = SectionedSelectionController( + selectionController = ListSelectionController( activity = requireActivity(), - owner = this, + decoration = BookmarksSelectionDecoration(binding.root.context), + registryOwner = this, callback = this, ) - adapter = BookmarksGroupAdapter( + bookmarksAdapter = BookmarksAdapter( lifecycleOwner = viewLifecycleOwner, coil = coil, - listener = this, - selectionController = checkNotNull(selectionController), - bookmarkClickListener = this, - groupClickListener = OnGroupClickListener(), + clickListener = this, + headerClickListener = this, ) - binding.recyclerView.adapter = adapter - binding.recyclerView.setHasFixedSize(true) - val spacingDecoration = SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing)) - binding.recyclerView.addItemDecoration(spacingDecoration) - - viewModel.content.observe(viewLifecycleOwner, ::onListChanged) + val spanSizeLookup = SpanSizeLookup() + with(binding.recyclerView) { + setHasFixedSize(true) + val spanResolver = MangaListSpanResolver(resources) + addItemDecoration(TypedListSpacingDecoration(context)) + adapter = bookmarksAdapter + addOnLayoutChangeListener(spanResolver) + spanResolver.setGridSize(settings.gridSize / 100f, this) + val lm = GridLayoutManager(context, spanResolver.spanCount) + lm.spanSizeLookup = spanSizeLookup + layoutManager = lm + selectionController?.attachToRecyclerView(this) + } + viewModel.content.observe(viewLifecycleOwner) { + bookmarksAdapter?.setItems(it, spanSizeLookup) + } viewModel.onError.observeEvent(viewLifecycleOwner, SnackbarErrorObserver(binding.recyclerView, this)) viewModel.onActionDone.observeEvent(viewLifecycleOwner, ::onActionDone) } override fun onDestroyView() { super.onDestroyView() - adapter = null + bookmarksAdapter = null selectionController = null } override fun onItemClick(item: Bookmark, view: View) { - if (selectionController?.onItemClick(item.manga, item.pageId) != true) { + if (selectionController?.onItemClick(item.pageId) != true) { val intent = ReaderActivity.IntentBuilder(view.context) .bookmark(item) .incognito(true) @@ -104,8 +117,13 @@ class BookmarksFragment : } } + override fun onListHeaderClick(item: ListHeader, view: View) { + val manga = item.payload as? Manga ?: return + startActivity(DetailsActivity.newIntent(view.context, manga)) + } + override fun onItemLongClick(item: Bookmark, view: View): Boolean { - return selectionController?.onItemLongClick(item.manga, item.pageId) ?: false + return selectionController?.onItemLongClick(item.pageId) ?: false } override fun onRetryClick(error: Throwable) = Unit @@ -118,24 +136,16 @@ class BookmarksFragment : override fun onFastScrollStop(fastScroller: FastScroller) = Unit - override fun onSelectionChanged(controller: SectionedSelectionController, count: Int) { - requireViewBinding().recyclerView.invalidateNestedItemDecorations() + override fun onSelectionChanged(controller: ListSelectionController, count: Int) { + requireViewBinding().recyclerView.invalidateItemDecorations() } - override fun onCreateActionMode( - controller: SectionedSelectionController, - mode: ActionMode, - menu: Menu, - ): Boolean { + override fun onCreateActionMode(controller: ListSelectionController, mode: ActionMode, menu: Menu): Boolean { mode.menuInflater.inflate(R.menu.mode_bookmarks, menu) return true } - override fun onActionItemClicked( - controller: SectionedSelectionController, - mode: ActionMode, - item: MenuItem, - ): Boolean { + override fun onActionItemClicked(controller: ListSelectionController, mode: ActionMode, item: MenuItem): Boolean { return when (item.itemId) { R.id.action_remove -> { val ids = selectionController?.snapshot() ?: return false @@ -148,11 +158,6 @@ class BookmarksFragment : } } - override fun onCreateItemDecoration( - controller: SectionedSelectionController, - section: Manga, - ): AbstractSelectionItemDecoration = BookmarksSelectionDecoration(requireContext()) - override fun onWindowInsetsChanged(insets: Insets) { requireViewBinding().recyclerView.updatePadding( bottom = insets.bottom, @@ -162,10 +167,6 @@ class BookmarksFragment : } } - private fun onListChanged(list: List) { - adapter?.items = list - } - private fun onActionDone(action: ReversibleAction) { val handle = action.handle val length = if (handle == null) Snackbar.LENGTH_SHORT else Snackbar.LENGTH_LONG @@ -176,24 +177,24 @@ class BookmarksFragment : snackbar.show() } - private inner class OnGroupClickListener : OnListItemClickListener { + private inner class SpanSizeLookup : GridLayoutManager.SpanSizeLookup(), Runnable { - override fun onItemClick(item: BookmarksGroup, view: View) { - val controller = selectionController - if (controller != null && controller.count > 0) { - if (controller.getSectionCount(item.manga) == item.bookmarks.size) { - controller.clearSelection(item.manga) - } else { - controller.addToSelection(item.manga, item.bookmarks.ids()) - } - return - } - val intent = DetailsActivity.newIntent(view.context, item.manga) - startActivity(intent) + init { + isSpanIndexCacheEnabled = true + isSpanGroupIndexCacheEnabled = true } - override fun onItemLongClick(item: BookmarksGroup, view: View): Boolean { - return selectionController?.addToSelection(item.manga, item.bookmarks.ids()) ?: false + override fun getSpanSize(position: Int): Int { + val total = (viewBinding?.recyclerView?.layoutManager as? GridLayoutManager)?.spanCount ?: return 1 + return when (bookmarksAdapter?.getItemViewType(position)) { + ListItemType.PAGE_THUMB.ordinal -> 1 + else -> total + } + } + + override fun run() { + invalidateSpanGroupIndexCache() + invalidateSpanIndexCache() } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksViewModel.kt index d08ce07b4..f661ce4b2 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/BookmarksViewModel.kt @@ -10,13 +10,14 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.plus import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.bookmarks.domain.Bookmark import org.koitharu.kotatsu.bookmarks.domain.BookmarksRepository -import org.koitharu.kotatsu.bookmarks.ui.model.BookmarksGroup import org.koitharu.kotatsu.core.ui.BaseViewModel import org.koitharu.kotatsu.core.ui.util.ReversibleAction import org.koitharu.kotatsu.core.util.ext.MutableEventFlow import org.koitharu.kotatsu.core.util.ext.call import org.koitharu.kotatsu.list.ui.model.EmptyState +import org.koitharu.kotatsu.list.ui.model.ListHeader import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.LoadingState import org.koitharu.kotatsu.list.ui.model.toErrorState @@ -41,17 +42,26 @@ class BookmarksViewModel @Inject constructor( actionStringRes = 0, ), ) - } else list.map { (manga, bookmarks) -> - BookmarksGroup(manga, bookmarks) + } else { + mapList(list) } } .catch { e -> emit(listOf(e.toErrorState(canRetry = false))) } .stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, listOf(LoadingState)) - fun removeBookmarks(ids: Map>) { + fun removeBookmarks(ids: Set) { launchJob(Dispatchers.Default) { val handle = repository.removeBookmarks(ids) onActionDone.call(ReversibleAction(R.string.bookmarks_removed, handle)) } } + + private fun mapList(data: Map>): List { + val result = ArrayList(data.values.sumOf { it.size + 1 }) + for ((manga, bookmarks) in data) { + result.add(ListHeader(manga.title, R.string.more, manga)) + result.addAll(bookmarks) + } + return result + } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAD.kt deleted file mode 100644 index df737ff54..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAD.kt +++ /dev/null @@ -1,69 +0,0 @@ -package org.koitharu.kotatsu.bookmarks.ui.adapter - -import android.view.View -import androidx.lifecycle.LifecycleOwner -import androidx.recyclerview.widget.RecyclerView -import coil.ImageLoader -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding -import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.bookmarks.domain.Bookmark -import org.koitharu.kotatsu.bookmarks.ui.model.BookmarksGroup -import org.koitharu.kotatsu.core.ui.image.CoverSizeResolver -import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener -import org.koitharu.kotatsu.core.ui.list.SectionedSelectionController -import org.koitharu.kotatsu.core.ui.list.decor.SpacingItemDecoration -import org.koitharu.kotatsu.core.util.ext.clearItemDecorations -import org.koitharu.kotatsu.core.util.ext.disposeImageRequest -import org.koitharu.kotatsu.core.util.ext.enqueueWith -import org.koitharu.kotatsu.core.util.ext.newImageRequest -import org.koitharu.kotatsu.core.util.ext.source -import org.koitharu.kotatsu.databinding.ItemBookmarksGroupBinding -import org.koitharu.kotatsu.list.ui.model.ListModel -import org.koitharu.kotatsu.parsers.model.Manga - -fun bookmarksGroupAD( - coil: ImageLoader, - lifecycleOwner: LifecycleOwner, - sharedPool: RecyclerView.RecycledViewPool, - selectionController: SectionedSelectionController, - bookmarkClickListener: OnListItemClickListener, - groupClickListener: OnListItemClickListener, -) = adapterDelegateViewBinding( - { layoutInflater, parent -> ItemBookmarksGroupBinding.inflate(layoutInflater, parent, false) }, -) { - val viewListenerAdapter = object : View.OnClickListener, View.OnLongClickListener { - override fun onClick(v: View) = groupClickListener.onItemClick(item, v) - override fun onLongClick(v: View) = groupClickListener.onItemLongClick(item, v) - } - - val adapter = BookmarksAdapter(coil, lifecycleOwner, bookmarkClickListener) - binding.recyclerView.setRecycledViewPool(sharedPool) - binding.recyclerView.adapter = adapter - val spacingDecoration = SpacingItemDecoration(context.resources.getDimensionPixelOffset(R.dimen.grid_spacing)) - binding.recyclerView.addItemDecoration(spacingDecoration) - binding.root.setOnClickListener(viewListenerAdapter) - binding.root.setOnLongClickListener(viewListenerAdapter) - - bind { payloads -> - if (payloads.isEmpty()) { - binding.recyclerView.clearItemDecorations() - binding.recyclerView.addItemDecoration(spacingDecoration) - selectionController.attachToRecyclerView(item.manga, binding.recyclerView) - } - binding.imageViewCover.newImageRequest(lifecycleOwner, item.manga.coverUrl)?.run { - placeholder(R.drawable.ic_placeholder) - fallback(R.drawable.ic_placeholder) - error(R.drawable.ic_error_placeholder) - allowRgb565(true) - size(CoverSizeResolver(binding.imageViewCover)) - source(item.manga.source) - enqueueWith(coil) - } - binding.textViewTitle.text = item.manga.title - adapter.items = item.bookmarks - } - - onViewRecycled { - binding.imageViewCover.disposeImageRequest() - } -} 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 deleted file mode 100644 index e0030ec91..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/adapter/BookmarksGroupAdapter.kt +++ /dev/null @@ -1,46 +0,0 @@ -package org.koitharu.kotatsu.bookmarks.ui.adapter - -import androidx.lifecycle.LifecycleOwner -import androidx.recyclerview.widget.RecyclerView -import coil.ImageLoader -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.adapter.ListStateHolderListener -import org.koitharu.kotatsu.list.ui.adapter.emptyStateListAD -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.parsers.model.Manga - -class BookmarksGroupAdapter( - coil: ImageLoader, - lifecycleOwner: LifecycleOwner, - selectionController: SectionedSelectionController, - listener: ListStateHolderListener, - bookmarkClickListener: OnListItemClickListener, - groupClickListener: OnListItemClickListener, -) : BaseListAdapter() { - - init { - val pool = RecyclerView.RecycledViewPool() - delegatesManager - .addDelegate( - bookmarksGroupAD( - coil = coil, - lifecycleOwner = lifecycleOwner, - sharedPool = pool, - selectionController = selectionController, - bookmarkClickListener = bookmarkClickListener, - groupClickListener = groupClickListener, - ), - ) - .addDelegate(loadingStateAD()) - .addDelegate(loadingFooterAD()) - .addDelegate(emptyStateListAD(coil, lifecycleOwner, listener)) - .addDelegate(errorStateListAD(listener)) - } -} 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 deleted file mode 100644 index 2bd51e2d9..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/model/BookmarksGroup.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.koitharu.kotatsu.bookmarks.ui.model - -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 - -class BookmarksGroup( - val manga: Manga, - val bookmarks: List, -) : ListModel { - - override fun areItemsTheSame(other: ListModel): Boolean { - return other is BookmarksGroup && other.manga.id == manga.id - } - - override fun getChangePayload(previousState: ListModel): Any? { - return if (previousState is BookmarksGroup && previousState.bookmarks != bookmarks) { - ListModelDiffCallback.PAYLOAD_NESTED_LIST_CHANGED - } else { - super.getChangePayload(previousState) - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as BookmarksGroup - - if (manga != other.manga) return false - - return bookmarks == other.bookmarks - } - - override fun hashCode(): Int { - var result = manga.hashCode() - result = 31 * result + bookmarks.hashCode() - return result - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksAdapter.kt index 064a6c894..7c5307731 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksAdapter.kt @@ -7,9 +7,11 @@ import org.koitharu.kotatsu.bookmarks.domain.Bookmark 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.adapter.ListHeaderClickListener import org.koitharu.kotatsu.list.ui.adapter.ListItemType import org.koitharu.kotatsu.list.ui.adapter.listHeaderAD import org.koitharu.kotatsu.list.ui.adapter.loadingFooterAD +import org.koitharu.kotatsu.list.ui.adapter.loadingStateAD import org.koitharu.kotatsu.list.ui.model.ListHeader import org.koitharu.kotatsu.list.ui.model.ListModel @@ -17,12 +19,14 @@ class BookmarksAdapter( coil: ImageLoader, lifecycleOwner: LifecycleOwner, clickListener: OnListItemClickListener, + headerClickListener: ListHeaderClickListener?, ) : BaseListAdapter(), FastScroller.SectionIndexer { init { addDelegate(ListItemType.PAGE_THUMB, bookmarkLargeAD(coil, lifecycleOwner, clickListener)) - addDelegate(ListItemType.HEADER, listHeaderAD(null)) + addDelegate(ListItemType.HEADER, listHeaderAD(headerClickListener)) addDelegate(ListItemType.FOOTER_LOADING, loadingFooterAD()) + addDelegate(ListItemType.STATE_LOADING, loadingStateAD()) } override fun getSectionText(context: Context, position: Int): CharSequence? { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksSheet.kt index c1a59e5c5..2f600a427 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/bookmarks/ui/sheet/BookmarksSheet.kt @@ -72,6 +72,7 @@ class BookmarksSheet : coil = coil, lifecycleOwner = viewLifecycleOwner, clickListener = this@BookmarksSheet, + headerClickListener = null, ) viewBinding?.headerBar?.setTitle(R.string.bookmarks) with(binding.recyclerView) { 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 4ce1f429f..76cc7fc89 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 @@ -26,8 +26,9 @@ open class BaseListAdapter( setItems(value, ContinuationResumeRunnable(cont)) } - fun addDelegate(type: ListItemType, delegate: AdapterDelegate>) { + fun addDelegate(type: ListItemType, delegate: AdapterDelegate>): BaseListAdapter { delegatesManager.addDelegate(type.ordinal, delegate) + return this } fun addListListener(listListener: ListListener) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/MangaBranch.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/MangaBranch.kt index 3cd38cddc..dfe1f7d66 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/MangaBranch.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/MangaBranch.kt @@ -1,6 +1,5 @@ package org.koitharu.kotatsu.details.ui.model -import org.koitharu.kotatsu.bookmarks.ui.model.BookmarksGroup import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchListModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchListModel.kt index ac38bd770..83d6c9dc2 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchListModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/MultiSearchListModel.kt @@ -1,6 +1,5 @@ package org.koitharu.kotatsu.search.ui.multi -import org.koitharu.kotatsu.bookmarks.ui.model.BookmarksGroup import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.list.ui.model.MangaItemModel