From bec0ce2c961dcef8b03855430eb8cc3ccc291c01 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Wed, 13 Mar 2024 14:43:35 +0200 Subject: [PATCH] Refactor chapters grid mode --- .idea/.name | 1 - .../org/koitharu/kotatsu/core/prefs/AppSettings.kt | 4 ++-- .../koitharu/kotatsu/details/ui/ChaptersMapper.kt | 3 +++ .../koitharu/kotatsu/details/ui/DetailsViewModel.kt | 13 ++++++++----- .../{chapterGridItemAD.kt => ChapterGridItemAD.kt} | 3 ++- .../kotatsu/details/ui/adapter/ChapterListItemAD.kt | 3 ++- .../kotatsu/details/ui/adapter/ChaptersAdapter.kt | 13 ++----------- .../kotatsu/details/ui/model/ChapterListItem.kt | 4 ++++ .../details/ui/model/ListModelConversionExt.kt | 3 +++ .../details/ui/pager/chapters/ChaptersFragment.kt | 5 ++--- .../kotatsu/download/ui/list/DownloadItemAD.kt | 2 +- .../kotatsu/list/ui/adapter/ListItemType.kt | 3 ++- .../list/ui/adapter/TypedListSpacingDecoration.kt | 5 +++-- .../org/koitharu/kotatsu/reader/ui/ChaptersSheet.kt | 6 +++--- .../sources/catalog/SourcesCatalogAdapter.kt | 2 +- 15 files changed, 38 insertions(+), 32 deletions(-) delete mode 100644 .idea/.name rename app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/{chapterGridItemAD.kt => ChapterGridItemAD.kt} (93%) diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 643c6ed7e..000000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -Kotatsu \ No newline at end of file diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt index d7898bf1e..ba8374501 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -178,11 +178,11 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { get() = prefs.getBoolean(KEY_INCOGNITO_MODE, false) set(value) = prefs.edit { putBoolean(KEY_INCOGNITO_MODE, value) } - var chaptersReverse: Boolean + var isChaptersReverse: Boolean get() = prefs.getBoolean(KEY_REVERSE_CHAPTERS, false) set(value) = prefs.edit { putBoolean(KEY_REVERSE_CHAPTERS, value) } - var chaptersGridView: Boolean + var isChaptersGridView: Boolean get() = prefs.getBoolean(KEY_GRID_VIEW_CHAPTERS, false) set(value) = prefs.edit { putBoolean(KEY_GRID_VIEW_CHAPTERS, value) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/ChaptersMapper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/ChaptersMapper.kt index 3390c4d66..ca5d93ed0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/ChaptersMapper.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/ChaptersMapper.kt @@ -16,6 +16,7 @@ fun MangaDetails.mapChapters( newCount: Int, branch: String?, bookmarks: List, + isGrid: Boolean, ): List { val remoteChapters = chapters[branch].orEmpty() val localChapters = local?.manga?.getChapters(branch).orEmpty() @@ -47,6 +48,7 @@ fun MangaDetails.mapChapters( isNew = isUnread && result.size >= newFrom, isDownloaded = local != null, isBookmarked = chapter.id in bookmarked, + isGrid = isGrid, ) } if (!localMap.isNullOrEmpty()) { @@ -60,6 +62,7 @@ fun MangaDetails.mapChapters( isNew = false, isDownloaded = !isLocal, isBookmarked = chapter.id in bookmarked, + isGrid = isGrid, ) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt index f7af810a0..8e407c091 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt @@ -36,6 +36,7 @@ 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.core.util.ext.combine import org.koitharu.kotatsu.core.util.ext.computeSize import org.koitharu.kotatsu.core.util.ext.onEachWhile import org.koitharu.kotatsu.core.util.ext.requireValue @@ -122,13 +123,13 @@ class DetailsViewModel @Inject constructor( val isChaptersReversed = settings.observeAsStateFlow( scope = viewModelScope + Dispatchers.Default, key = AppSettings.KEY_REVERSE_CHAPTERS, - valueProducer = { chaptersReverse }, + valueProducer = { isChaptersReverse }, ) val isChaptersInGridView = settings.observeAsStateFlow( scope = viewModelScope + Dispatchers.Default, key = AppSettings.KEY_GRID_VIEW_CHAPTERS, - valueProducer = { chaptersGridView }, + valueProducer = { isChaptersGridView }, ) val historyInfo: StateFlow = combine( @@ -213,12 +214,14 @@ class DetailsViewModel @Inject constructor( selectedBranch, newChaptersCount, bookmarks, - ) { manga, history, branch, news, bookmarks -> + isChaptersInGridView, + ) { manga, history, branch, news, bookmarks, grid -> manga?.mapChapters( history, news, branch, bookmarks, + grid, ).orEmpty() }, isChaptersReversed, @@ -288,11 +291,11 @@ class DetailsViewModel @Inject constructor( } fun setChaptersReversed(newValue: Boolean) { - settings.chaptersReverse = newValue + settings.isChaptersReverse = newValue } fun setChaptersInGridView(newValue: Boolean) { - settings.chaptersGridView = newValue + settings.isChaptersGridView = newValue } fun setSelectedBranch(branch: String?) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/chapterGridItemAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChapterGridItemAD.kt similarity index 93% rename from app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/chapterGridItemAD.kt rename to app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChapterGridItemAD.kt index 28cc446f2..d9eee1600 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/chapterGridItemAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChapterGridItemAD.kt @@ -17,7 +17,8 @@ import kotlin.math.roundToInt fun chapterGridItemAD( clickListener: OnListItemClickListener, ) = adapterDelegateViewBinding( - { inflater, parent -> ItemChapterGridBinding.inflate(inflater, parent, false) }, + viewBinding = { inflater, parent -> ItemChapterGridBinding.inflate(inflater, parent, false) }, + on = { item, _, _ -> item is ChapterListItem && item.isGrid } ) { val eventListener = AdapterDelegateClickListenerAdapter(this, clickListener) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt index 7234dd4bb..1d52845d1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/adapter/ChapterListItemAD.kt @@ -18,7 +18,8 @@ import com.google.android.material.R as MR fun chapterListItemAD( clickListener: OnListItemClickListener, ) = adapterDelegateViewBinding( - { inflater, parent -> ItemChapterBinding.inflate(inflater, parent, false) }, + viewBinding = { inflater, parent -> ItemChapterBinding.inflate(inflater, parent, false) }, + on = { item, _, _ -> item is ChapterListItem && !item.isGrid } ) { val eventListener = AdapterDelegateClickListenerAdapter(this, clickListener) 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 c14824000..8015787e2 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 @@ -11,21 +11,12 @@ import org.koitharu.kotatsu.list.ui.model.ListModel class ChaptersAdapter( private val onItemClickListener: OnListItemClickListener, - chaptersInGridView: Boolean, ) : BaseListAdapter(), FastScroller.SectionIndexer { init { - setChapterAdapterDelegate(chaptersInGridView) addDelegate(ListItemType.HEADER, listHeaderAD(null)) - } - - fun setChapterAdapterDelegate(chaptersInGridView: Boolean) { - delegatesManager.removeDelegate(ListItemType.CHAPTER.ordinal) - if (chaptersInGridView) { - addDelegate(ListItemType.CHAPTER, chapterGridItemAD(onItemClickListener)) - } else { - addDelegate(ListItemType.CHAPTER, chapterListItemAD(onItemClickListener)) - } + addDelegate(ListItemType.CHAPTER_LIST, chapterListItemAD(onItemClickListener)) + addDelegate(ListItemType.CHAPTER_GRID, chapterGridItemAD(onItemClickListener)) } override fun getSectionText(context: Context, position: Int): CharSequence? { 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 518dcc800..19a14e133 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 @@ -48,6 +48,9 @@ data class ChapterListItem( val isNew: Boolean get() = hasFlag(FLAG_NEW) + val isGrid: Boolean + get() = hasFlag(FLAG_GRID) + private fun buildDescription(): String { val joiner = StringJoiner(" • ") chapter.formatNumber()?.let { @@ -90,5 +93,6 @@ data class ChapterListItem( const val FLAG_NEW = 8 const val FLAG_BOOKMARKED = 16 const val FLAG_DOWNLOADED = 32 + const val FLAG_GRID = 64 } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ListModelConversionExt.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ListModelConversionExt.kt index 95c4cae15..f08ca79a6 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ListModelConversionExt.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ListModelConversionExt.kt @@ -3,6 +3,7 @@ package org.koitharu.kotatsu.details.ui.model import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_BOOKMARKED import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_CURRENT import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_DOWNLOADED +import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_GRID import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_NEW import org.koitharu.kotatsu.details.ui.model.ChapterListItem.Companion.FLAG_UNREAD import org.koitharu.kotatsu.parsers.model.MangaChapter @@ -13,6 +14,7 @@ fun MangaChapter.toListItem( isNew: Boolean, isDownloaded: Boolean, isBookmarked: Boolean, + isGrid: Boolean, ): ChapterListItem { var flags = 0 if (isCurrent) flags = flags or FLAG_CURRENT @@ -20,6 +22,7 @@ fun MangaChapter.toListItem( if (isNew) flags = flags or FLAG_NEW if (isBookmarked) flags = flags or FLAG_BOOKMARKED if (isDownloaded) flags = flags or FLAG_DOWNLOADED + if (isGrid) flags = flags or FLAG_GRID return ChapterListItem( chapter = this, flags = flags, diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt index d9ada0fb3..16bfcb79a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/chapters/ChaptersFragment.kt @@ -58,7 +58,7 @@ class ChaptersFragment : override fun onViewBindingCreated(binding: FragmentChaptersBinding, savedInstanceState: Bundle?) { super.onViewBindingCreated(binding, savedInstanceState) - chaptersAdapter = ChaptersAdapter(this, viewModel.isChaptersInGridView.value) + chaptersAdapter = ChaptersAdapter(this) selectionController = ListSelectionController( activity = requireActivity(), decoration = ChaptersSelectionDecoration(binding.root.context), @@ -70,10 +70,9 @@ class ChaptersFragment : checkNotNull(selectionController).attachToRecyclerView(this) setHasFixedSize(true) isNestedScrollingEnabled = false + adapter = chaptersAdapter } viewModel.isChaptersInGridView.observe(viewLifecycleOwner) { chaptersInGridView -> - chaptersAdapter?.setChapterAdapterDelegate(chaptersInGridView) - binding.recyclerViewChapters.adapter = chaptersAdapter binding.recyclerViewChapters.layoutManager = if (chaptersInGridView) { GridLayoutManager(context, 4) } else { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt index 271b3090d..50803559b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadItemAD.kt @@ -59,7 +59,7 @@ fun downloadItemAD( } } val chaptersAdapter = BaseListAdapter() - .addDelegate(ListItemType.CHAPTER, downloadChapterAD()) + .addDelegate(ListItemType.CHAPTER_LIST, downloadChapterAD()) binding.recyclerViewChapters.addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL)) binding.recyclerViewChapters.adapter = chaptersAdapter diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/ListItemType.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/ListItemType.kt index 9603e4304..b5d9eeae1 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/ListItemType.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/ListItemType.kt @@ -29,5 +29,6 @@ enum class ListItemType { CATEGORY_LARGE, MANGA_SCROBBLING, NAV_ITEM, - CHAPTER, + CHAPTER_LIST, + CHAPTER_GRID, } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/TypedListSpacingDecoration.kt b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/TypedListSpacingDecoration.kt index a75ff38cf..f93403d52 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/TypedListSpacingDecoration.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/list/ui/adapter/TypedListSpacingDecoration.kt @@ -62,7 +62,8 @@ class TypedListSpacingDecoration( ListItemType.MANGA_NESTED_GROUP, ListItemType.CATEGORY_LARGE, ListItemType.NAV_ITEM, - ListItemType.CHAPTER, + ListItemType.CHAPTER_LIST, + ListItemType.CHAPTER_GRID, null, -> outRect.set(0) @@ -83,5 +84,5 @@ class TypedListSpacingDecoration( private fun ListItemType?.isEdgeToEdge() = this == ListItemType.MANGA_NESTED_GROUP || this == ListItemType.FILTER_SORT || this == ListItemType.FILTER_TAG - || this == ListItemType.CHAPTER + || this == ListItemType.CHAPTER_LIST } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ChaptersSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ChaptersSheet.kt index 72a3cecb6..164305bf5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ChaptersSheet.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ChaptersSheet.kt @@ -66,6 +66,7 @@ class ChaptersSheet : BaseAdaptiveSheet(), newCount = 0, branch = currentChapter?.branch, bookmarks = listOf(), + isGrid = settings.isChaptersGridView, ).withVolumeHeaders(binding.root.context) if (chapters.isEmpty()) { dismissAllowingStateLoss() @@ -77,8 +78,7 @@ class ChaptersSheet : BaseAdaptiveSheet(), -1 } binding.recyclerView.addItemDecoration(TypedListSpacingDecoration(binding.recyclerView.context, true)) - val chaptersInGridView = settings.chaptersGridView - binding.recyclerView.adapter = ChaptersAdapter(this, chaptersInGridView).also { adapter -> + binding.recyclerView.adapter = ChaptersAdapter(this).also { adapter -> if (currentPosition >= 0) { val targetPosition = (currentPosition - 1).coerceAtLeast(0) val offset = @@ -90,7 +90,7 @@ class ChaptersSheet : BaseAdaptiveSheet(), adapter.items = chapters } } - binding.recyclerView.layoutManager = if (chaptersInGridView) { + binding.recyclerView.layoutManager = if (settings.isChaptersGridView) { GridLayoutManager(context, 4) } else { LinearLayoutManager(context) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogAdapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogAdapter.kt index 0117be267..281371a45 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogAdapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/sources/catalog/SourcesCatalogAdapter.kt @@ -15,7 +15,7 @@ class SourcesCatalogAdapter( ) : BaseListAdapter(), FastScroller.SectionIndexer { init { - addDelegate(ListItemType.CHAPTER, sourceCatalogItemSourceAD(coil, lifecycleOwner, listener)) + addDelegate(ListItemType.CHAPTER_LIST, sourceCatalogItemSourceAD(coil, lifecycleOwner, listener)) addDelegate(ListItemType.HINT_EMPTY, sourceCatalogItemHintAD(coil, lifecycleOwner)) }