Compare commits

...

1 Commits

Author SHA1 Message Date
Koitharu
ce455d4cb6 Refactor chapters grid mode 2024-03-13 14:43:35 +02:00
15 changed files with 34 additions and 32 deletions

1
.idea/.name generated
View File

@@ -1 +0,0 @@
Kotatsu

View File

@@ -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) }

View File

@@ -16,6 +16,7 @@ fun MangaDetails.mapChapters(
newCount: Int,
branch: String?,
bookmarks: List<Bookmark>,
isGrid: Boolean,
): List<ChapterListItem> {
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,
)
}
}

View File

@@ -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<HistoryInfo> = 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?) {

View File

@@ -17,7 +17,8 @@ import kotlin.math.roundToInt
fun chapterGridItemAD(
clickListener: OnListItemClickListener<ChapterListItem>,
) = adapterDelegateViewBinding<ChapterListItem, ListModel, ItemChapterGridBinding>(
{ 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)

View File

@@ -18,7 +18,8 @@ import com.google.android.material.R as MR
fun chapterListItemAD(
clickListener: OnListItemClickListener<ChapterListItem>,
) = adapterDelegateViewBinding<ChapterListItem, ListModel, ItemChapterBinding>(
{ 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)

View File

@@ -11,21 +11,12 @@ import org.koitharu.kotatsu.list.ui.model.ListModel
class ChaptersAdapter(
private val onItemClickListener: OnListItemClickListener<ChapterListItem>,
chaptersInGridView: Boolean,
) : BaseListAdapter<ListModel>(), 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? {

View File

@@ -10,6 +10,7 @@ data class ChapterListItem(
val chapter: MangaChapter,
val flags: Int,
private val uploadDateMs: Long,
val isGrid: Boolean,
) : ListModel {
var description: String? = null

View File

@@ -13,6 +13,7 @@ fun MangaChapter.toListItem(
isNew: Boolean,
isDownloaded: Boolean,
isBookmarked: Boolean,
isGrid: Boolean,
): ChapterListItem {
var flags = 0
if (isCurrent) flags = flags or FLAG_CURRENT
@@ -24,5 +25,6 @@ fun MangaChapter.toListItem(
chapter = this,
flags = flags,
uploadDateMs = uploadDate,
isGrid = isGrid,
)
}

View File

@@ -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 {

View File

@@ -59,7 +59,7 @@ fun downloadItemAD(
}
}
val chaptersAdapter = BaseListAdapter<DownloadChapter>()
.addDelegate(ListItemType.CHAPTER, downloadChapterAD())
.addDelegate(ListItemType.CHAPTER_LIST, downloadChapterAD())
binding.recyclerViewChapters.addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL))
binding.recyclerViewChapters.adapter = chaptersAdapter

View File

@@ -29,5 +29,6 @@ enum class ListItemType {
CATEGORY_LARGE,
MANGA_SCROBBLING,
NAV_ITEM,
CHAPTER,
CHAPTER_LIST,
CHAPTER_GRID,
}

View File

@@ -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
}

View File

@@ -66,6 +66,7 @@ class ChaptersSheet : BaseAdaptiveSheet<SheetChaptersBinding>(),
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<SheetChaptersBinding>(),
-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<SheetChaptersBinding>(),
adapter.items = chapters
}
}
binding.recyclerView.layoutManager = if (chaptersInGridView) {
binding.recyclerView.layoutManager = if (settings.isChaptersGridView) {
GridLayoutManager(context, 4)
} else {
LinearLayoutManager(context)

View File

@@ -15,7 +15,7 @@ class SourcesCatalogAdapter(
) : BaseListAdapter<SourceCatalogItem>(), 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))
}