revert: "refactor(library): Some adjustments"

This reverts commit 9276382c12.
This commit is contained in:
Ahmad Ansori Palembani 2024-12-01 09:20:15 +07:00
parent 1738dfb510
commit 2b639d0630
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
4 changed files with 58 additions and 68 deletions

View file

@ -558,7 +558,7 @@ open class LibraryController(
} }
presenter.groupType = item presenter.groupType = item
shouldScrollToTop = true shouldScrollToTop = true
presenter.updateLibrary() presenter.getLibrary()
true true
}.show() }.show()
} }
@ -1055,7 +1055,7 @@ open class LibraryController(
if (type.isEnter) { if (type.isEnter) {
binding.filterBottomSheet.filterBottomSheet.isVisible = true binding.filterBottomSheet.filterBottomSheet.isVisible = true
if (type == ControllerChangeType.POP_ENTER) { if (type == ControllerChangeType.POP_ENTER) {
presenter.updateLibrary() presenter.getLibrary()
isPoppingIn = true isPoppingIn = true
} }
DownloadJob.callListeners() DownloadJob.callListeners()
@ -1095,7 +1095,7 @@ open class LibraryController(
if (!isBindingInitialized) return if (!isBindingInitialized) return
updateFilterSheetY() updateFilterSheetY()
if (observeLater) { if (observeLater) {
presenter.updateLibrary() presenter.getLibrary()
} }
} }
@ -1408,7 +1408,7 @@ open class LibraryController(
private fun onRefresh() { private fun onRefresh() {
showCategories(false) showCategories(false)
presenter.updateLibrary() presenter.getLibrary()
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
} }
@ -1432,14 +1432,14 @@ open class LibraryController(
val isShowAllCategoriesSet = preferences.showAllCategories().get() val isShowAllCategoriesSet = preferences.showAllCategories().get()
if (!query.isNullOrBlank() && this.query.isBlank() && !isShowAllCategoriesSet) { if (!query.isNullOrBlank() && this.query.isBlank() && !isShowAllCategoriesSet) {
presenter.forceShowAllCategories = preferences.showAllCategoriesWhenSearchingSingleCategory().get() presenter.forceShowAllCategories = preferences.showAllCategoriesWhenSearchingSingleCategory().get()
presenter.updateLibrary() presenter.getLibrary()
} else if (query.isNullOrBlank() && this.query.isNotBlank() && !isShowAllCategoriesSet) { } else if (query.isNullOrBlank() && this.query.isNotBlank() && !isShowAllCategoriesSet) {
if (!isSubClass) { if (!isSubClass) {
preferences.showAllCategoriesWhenSearchingSingleCategory() preferences.showAllCategoriesWhenSearchingSingleCategory()
.set(presenter.forceShowAllCategories) .set(presenter.forceShowAllCategories)
} }
presenter.forceShowAllCategories = false presenter.forceShowAllCategories = false
presenter.updateLibrary() presenter.getLibrary()
} }
if (query != this.query && !query.isNullOrBlank()) { if (query != this.query && !query.isNullOrBlank()) {
@ -1641,7 +1641,7 @@ open class LibraryController(
if (mangaId == null) { if (mangaId == null) {
adapter.getHeaderPositions().forEach { adapter.notifyItemChanged(it) } adapter.getHeaderPositions().forEach { adapter.notifyItemChanged(it) }
} else { } else {
presenter.updateLibrary() presenter.updateManga()
} }
} }
@ -1820,7 +1820,7 @@ open class LibraryController(
val category = (adapter.getItem(position) as? LibraryHeaderItem)?.category ?: return val category = (adapter.getItem(position) as? LibraryHeaderItem)?.category ?: return
if (!category.isDynamic) { if (!category.isDynamic) {
ManageCategoryDialog(category) { ManageCategoryDialog(category) {
presenter.updateLibrary() presenter.getLibrary()
}.showDialog(router) }.showDialog(router)
} }
} }
@ -1913,7 +1913,7 @@ open class LibraryController(
isGone = true isGone = true
setOnClickListener { setOnClickListener {
presenter.forceShowAllCategories = !presenter.forceShowAllCategories presenter.forceShowAllCategories = !presenter.forceShowAllCategories
presenter.updateLibrary() presenter.getLibrary()
isSelected = presenter.forceShowAllCategories isSelected = presenter.forceShowAllCategories
} }
val pad = 12.dpToPx val pad = 12.dpToPx
@ -2192,7 +2192,7 @@ open class LibraryController(
private fun showChangeMangaCategoriesSheet() { private fun showChangeMangaCategoriesSheet() {
val activity = activity ?: return val activity = activity ?: return
selectedMangas.toList().moveCategories(activity) { selectedMangas.toList().moveCategories(activity) {
presenter.updateLibrary() presenter.getLibrary()
destroyActionModeIfNeeded() destroyActionModeIfNeeded()
} }
} }

View file

@ -54,11 +54,13 @@ import kotlin.random.Random
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -103,7 +105,10 @@ class LibraryPresenter(
private val getTrack: GetTrack by injectLazy() private val getTrack: GetTrack by injectLazy()
private val getHistory: GetHistory by injectLazy() private val getHistory: GetHistory by injectLazy()
private val forceUpdateEvent: Channel<Unit> = Channel(Channel.UNLIMITED) private val _fetchLibrary: Channel<Unit> = Channel(Channel.UNLIMITED)
val fetchLibrary = _fetchLibrary.receiveAsFlow()
.onStart { emit(Unit) }
.shareIn(presenterScope, SharingStarted.Lazily, 1)
private val context = preferences.context private val context = preferences.context
private val viewContext private val viewContext
@ -126,8 +131,6 @@ class LibraryPresenter(
private var allCategories: List<Category> = emptyList() private var allCategories: List<Category> = emptyList()
/** List of all manga to update the */ /** List of all manga to update the */
// TODO: Store sectioned before flattening it out for "show all categories"
private var currentLibrary: Map<Category, List<LibraryItem>> = mapOf()
var libraryItems: List<LibraryItem> = emptyList() var libraryItems: List<LibraryItem> = emptyList()
private var sectionedLibraryItems: MutableMap<Int, List<LibraryItem>> = mutableMapOf() private var sectionedLibraryItems: MutableMap<Int, List<LibraryItem>> = mutableMapOf()
var currentCategory = -1 var currentCategory = -1
@ -196,7 +199,6 @@ class LibraryPresenter(
} }
subscribeLibrary() subscribeLibrary()
updateLibrary()
if (!preferences.showLibrarySearchSuggestions().isSet()) { if (!preferences.showLibrarySearchSuggestions().isSet()) {
DelayedLibrarySuggestionsJob.setupTask(context, true) DelayedLibrarySuggestionsJob.setupTask(context, true)
@ -233,7 +235,7 @@ class LibraryPresenter(
combine( combine(
getLibraryFlow(), getLibraryFlow(),
emptyFlow<Unit>(), // Placeholder flow for later usage fetchLibrary,
) { data, _ -> ) { data, _ ->
categories = data.categories categories = data.categories
allCategories = data.allCategories allCategories = data.allCategories
@ -261,6 +263,13 @@ class LibraryPresenter(
} }
} }
/** Get favorited manga for library and sort and filter it */
fun getLibrary() {
presenterScope.launch {
_fetchLibrary.send(Unit)
}
}
private suspend fun reorderCategories(categories: List<Category>) { private suspend fun reorderCategories(categories: List<Category>) {
val sortedCategories = categories.sortedBy { it.order } val sortedCategories = categories.sortedBy { it.order }
sortedCategories.forEachIndexed { i, category -> category.order = i } sortedCategories.forEachIndexed { i, category -> category.order = i }
@ -314,7 +323,8 @@ class LibraryPresenter(
private suspend fun sectionLibrary(items: List<LibraryItem>, freshStart: Boolean = false) { private suspend fun sectionLibrary(items: List<LibraryItem>, freshStart: Boolean = false) {
libraryItems = items libraryItems = items
val showAll = showAllCategories || !libraryIsGrouped || categories.size <= 1 val showAll = showAllCategories || !libraryIsGrouped ||
categories.size <= 1
sectionedLibraryItems = items.groupBy { it.header.category.id ?: 0 }.toMutableMap() sectionedLibraryItems = items.groupBy { it.header.category.id ?: 0 }.toMutableMap()
if (!showAll && currentCategory == -1) { if (!showAll && currentCategory == -1) {
currentCategory = categories.find { currentCategory = categories.find {
@ -750,9 +760,6 @@ class LibraryPresenter(
preferences.librarySortingMode().changes(), preferences.librarySortingMode().changes(),
preferences.librarySortingAscending().changes(), preferences.librarySortingAscending().changes(),
preferences.collapsedCategories().changes(),
preferences.collapsedDynamicCategories().changes(),
) { ) {
ItemPreferences( ItemPreferences(
filterDownloaded = it[0] as Int, filterDownloaded = it[0] as Int,
@ -766,8 +773,6 @@ class LibraryPresenter(
showAllCategories = it[8] as Boolean, showAllCategories = it[8] as Boolean,
sortingMode = it[9] as Int, sortingMode = it[9] as Int,
sortAscending = it[10] as Boolean, sortAscending = it[10] as Boolean,
collapsedCategories = it[11] as Set<String>,
collapsedDynamicCategories = it[12] as Set<String>,
) )
} }
@ -805,24 +810,22 @@ class LibraryPresenter(
* If category id '-1' is not empty, it means the library not grouped by categories * If category id '-1' is not empty, it means the library not grouped by categories
*/ */
private fun getLibraryFlow(): Flow<LibraryData> { private fun getLibraryFlow(): Flow<LibraryData> {
val libraryItemFlow = combine( return combine(
getCategories.subscribe(), getCategories.subscribe(),
getLibraryManga.subscribe(), getLibraryManga.subscribe(),
getPreferencesFlow(), getPreferencesFlow(),
forceUpdateEvent.receiveAsFlow(), preferences.removeArticles().changes(),
) { allCategories, libraryMangaList, prefs, _ -> fetchLibrary
this.groupType = prefs.groupType ) { allCategories, libraryMangaList, prefs, removeArticles, _ ->
this.allCategories = allCategories groupType = prefs.groupType
// FIXME: Should return Map<Int, LibraryItem> where Int is category id val (items, categories, hiddenItems) = if (groupType <= BY_DEFAULT || !libraryIsGrouped) {
if (groupType <= BY_DEFAULT || !libraryIsGrouped) {
getLibraryItems( getLibraryItems(
allCategories, // FIXME: Don't depends on allCategories allCategories,
libraryMangaList, libraryMangaList,
prefs.sortingMode, prefs.sortingMode,
prefs.sortAscending, prefs.sortAscending,
prefs.showAllCategories, prefs.showAllCategories,
prefs.collapsedCategories,
) )
} else { } else {
getDynamicLibraryItems( getDynamicLibraryItems(
@ -830,16 +833,8 @@ class LibraryPresenter(
prefs.sortingMode, prefs.sortingMode,
prefs.sortAscending, prefs.sortAscending,
groupType, groupType,
prefs.collapsedDynamicCategories,
) )
} }
}
return combine(
libraryItemFlow,
preferences.removeArticles().changes(),
) { libraryItems, removeArticles ->
val (items, categories, hiddenItems) = libraryItems
LibraryData( LibraryData(
categories = categories, categories = categories,
@ -857,7 +852,6 @@ class LibraryPresenter(
sortingMode: Int, sortingMode: Int,
isAscending: Boolean, isAscending: Boolean,
showAll: Boolean, showAll: Boolean,
collapsedCategories: Set<String>,
): Triple<List<LibraryItem>, List<Category>, List<LibraryItem>> { ): Triple<List<LibraryItem>, List<Category>, List<LibraryItem>> {
val categories = allCategories.toMutableList() val categories = allCategories.toMutableList()
val hiddenItems = mutableListOf<LibraryItem>() val hiddenItems = mutableListOf<LibraryItem>()
@ -880,11 +874,6 @@ class LibraryPresenter(
} + (-1 to catItemAll) + (0 to LibraryHeaderItem({ categories.getOrDefault(0) }, 0)) } + (-1 to catItemAll) + (0 to LibraryHeaderItem({ categories.getOrDefault(0) }, 0))
).toMap() ).toMap()
// TODO
val map = libraryManga.groupBy {
categories.getOrDefault(it.category)
}
val items = if (libraryIsGrouped) { val items = if (libraryIsGrouped) {
libraryManga libraryManga
} else { } else {
@ -904,14 +893,16 @@ class LibraryPresenter(
val categoriesHidden = if (forceShowAllCategories || controllerIsSubClass) { val categoriesHidden = if (forceShowAllCategories || controllerIsSubClass) {
emptySet() emptySet()
} else { } else {
collapsedCategories.mapNotNull { it.toIntOrNull() }.toSet() preferences.collapsedCategories().get().mapNotNull { it.toIntOrNull() }.toSet()
} }
if (categorySet.contains(0)) categories.add(0, createDefaultCategory()) if (categorySet.contains(0)) categories.add(0, createDefaultCategory())
if (libraryIsGrouped) { if (libraryIsGrouped) {
categories.forEach { category -> categories.forEach { category ->
val catId = category.id ?: return@forEach val catId = category.id ?: return@forEach
if (catId > 0 && !categorySet.contains(catId) && (catId !in categoriesHidden || !showAll)) { if (catId > 0 && !categorySet.contains(catId) &&
(catId !in categoriesHidden || !showAll)
) {
val headerItem = headerItems[catId] val headerItem = headerItems[catId]
if (headerItem != null) { if (headerItem != null) {
items.add( items.add(
@ -964,7 +955,6 @@ class LibraryPresenter(
sortingMode: Int, sortingMode: Int,
isAscending: Boolean, isAscending: Boolean,
groupType: Int, groupType: Int,
collapsedDynamicCategories: Set<String>,
): Triple<List<LibraryItem>, List<Category>, List<LibraryItem>> { ): Triple<List<LibraryItem>, List<Category>, List<LibraryItem>> {
val tagItems: MutableMap<String, LibraryHeaderItem> = mutableMapOf() val tagItems: MutableMap<String, LibraryHeaderItem> = mutableMapOf()
@ -1067,7 +1057,7 @@ class LibraryPresenter(
val hiddenDynamics = if (controllerIsSubClass) { val hiddenDynamics = if (controllerIsSubClass) {
emptySet() emptySet()
} else { } else {
collapsedDynamicCategories preferences.collapsedDynamicCategories().get()
} }
val headers = tagItems.map { item -> val headers = tagItems.map { item ->
Category.createCustom( Category.createCustom(
@ -1223,6 +1213,7 @@ class LibraryPresenter(
.mapNotNull { if (it.id != null) MangaUpdate(it.id!!, favorite = false) else null } .mapNotNull { if (it.id != null) MangaUpdate(it.id!!, favorite = false) else null }
withIOContext { updateManga.awaitAll(mangaToDelete) } withIOContext { updateManga.awaitAll(mangaToDelete) }
getLibrary()
} }
} }
@ -1245,11 +1236,8 @@ class LibraryPresenter(
} }
} }
/** Force update the library */ /** Called when Library Service updates a manga, update the item as well */
fun updateLibrary() = presenterScope.launch { fun updateManga() = getLibrary()
forceUpdateEvent.send(Unit)
}
/** Undo the removal of the manga once in library */ /** Undo the removal of the manga once in library */
fun reAddMangas(mangas: List<Manga>) { fun reAddMangas(mangas: List<Manga>) {
@ -1259,12 +1247,12 @@ class LibraryPresenter(
withIOContext { updateManga.awaitAll(mangaToAdd) } withIOContext { updateManga.awaitAll(mangaToAdd) }
(view as? FilteredLibraryController)?.updateStatsPage() (view as? FilteredLibraryController)?.updateStatsPage()
getLibrary()
} }
} }
/** Returns first unread chapter of a manga */ /** Returns first unread chapter of a manga */
fun getFirstUnread(manga: Manga): Chapter? { fun getFirstUnread(manga: Manga): Chapter? {
// FIXME: Don't do blocking
val chapters = runBlocking { getChapter.awaitAll(manga) } val chapters = runBlocking { getChapter.awaitAll(manga) }
return ChapterSort(manga, chapterFilter, preferences).getNextUnreadChapter(chapters, false) return ChapterSort(manga, chapterFilter, preferences).getNextUnreadChapter(chapters, false)
} }
@ -1316,6 +1304,7 @@ class LibraryPresenter(
} }
} }
// TODO: Use SQLDelight
/** Shift a manga's category via drag & drop */ /** Shift a manga's category via drag & drop */
fun moveMangaToCategory( fun moveMangaToCategory(
manga: LibraryManga, manga: LibraryManga,
@ -1361,7 +1350,7 @@ class LibraryPresenter(
) )
} }
} }
updateLibrary() getLibrary()
} }
} }
@ -1396,6 +1385,7 @@ class LibraryPresenter(
} }
preferences.collapsedDynamicCategories().set(categoriesHidden) preferences.collapsedDynamicCategories().set(categoriesHidden)
} }
getLibrary()
} }
private fun getDynamicCategoryName(category: Category): String = private fun getDynamicCategoryName(category: Category): String =
@ -1426,6 +1416,7 @@ class LibraryPresenter(
} }
} }
} }
getLibrary()
} }
fun allCategoriesExpanded(): Boolean { fun allCategoriesExpanded(): Boolean {
@ -1467,7 +1458,7 @@ class LibraryPresenter(
mapMangaChapters[manga] = chapters mapMangaChapters[manga] = chapters
} }
updateLibrary() getLibrary()
} }
return mapMangaChapters return mapMangaChapters
} }
@ -1483,7 +1474,7 @@ class LibraryPresenter(
} }
}.flatten() }.flatten()
updateChapter.awaitAll(updates) updateChapter.awaitAll(updates)
updateLibrary() getLibrary()
} }
} }
@ -1663,9 +1654,6 @@ class LibraryPresenter(
val sortingMode: Int, val sortingMode: Int,
val sortAscending: Boolean, val sortAscending: Boolean,
val collapsedCategories: Set<String>,
val collapsedDynamicCategories: Set<String>,
) )
data class LibraryData( data class LibraryData(

View file

@ -2,14 +2,16 @@ package eu.kanade.tachiyomi.ui.library.display
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import eu.kanade.tachiyomi.R
import yokai.i18n.MR
import yokai.util.lang.getString
import dev.icerock.moko.resources.compose.stringResource
import eu.kanade.tachiyomi.databinding.LibraryCategoryLayoutBinding import eu.kanade.tachiyomi.databinding.LibraryCategoryLayoutBinding
import eu.kanade.tachiyomi.util.bindToPreference import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.lang.withSubtitle import eu.kanade.tachiyomi.util.lang.withSubtitle
import eu.kanade.tachiyomi.util.system.toInt import eu.kanade.tachiyomi.util.system.toInt
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlin.math.min import kotlin.math.min
import yokai.i18n.MR
import yokai.util.lang.getString
class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView<LibraryCategoryLayoutBinding>(context, attrs) { BaseLibraryDisplayView<LibraryCategoryLayoutBinding>(context, attrs) {
@ -18,7 +20,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
override fun initGeneralPreferences() { override fun initGeneralPreferences() {
with(binding) { with(binding) {
showAll.bindToPreference(preferences.showAllCategories()) { showAll.bindToPreference(preferences.showAllCategories()) {
controller?.presenter?.updateLibrary() controller?.presenter?.getLibrary()
binding.categoryShow.isEnabled = it binding.categoryShow.isEnabled = it
} }
categoryShow.isEnabled = showAll.isChecked categoryShow.isEnabled = showAll.isChecked
@ -28,7 +30,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
dynamicToBottom.text = context.getString(MR.strings.move_dynamic_to_bottom) dynamicToBottom.text = context.getString(MR.strings.move_dynamic_to_bottom)
.withSubtitle(context, MR.strings.when_grouping_by_sources_tags) .withSubtitle(context, MR.strings.when_grouping_by_sources_tags)
dynamicToBottom.bindToPreference(preferences.collapsedDynamicAtBottom()) { dynamicToBottom.bindToPreference(preferences.collapsedDynamicAtBottom()) {
controller?.presenter?.updateLibrary() controller?.presenter?.getLibrary()
} }
showEmptyCatsFiltering.bindToPreference(preferences.showEmptyCategoriesWhileFiltering()) { showEmptyCatsFiltering.bindToPreference(preferences.showEmptyCategoriesWhileFiltering()) {
controller?.presenter?.requestFilterUpdate() controller?.presenter?.requestFilterUpdate()

View file

@ -36,8 +36,6 @@ import eu.kanade.tachiyomi.util.view.isCollapsed
import eu.kanade.tachiyomi.util.view.isExpanded import eu.kanade.tachiyomi.util.view.isExpanded
import eu.kanade.tachiyomi.util.view.isHidden import eu.kanade.tachiyomi.util.view.isHidden
import eu.kanade.tachiyomi.util.view.setText import eu.kanade.tachiyomi.util.view.setText
import kotlin.math.max
import kotlin.math.roundToInt
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
@ -50,6 +48,8 @@ import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import yokai.i18n.MR import yokai.i18n.MR
import yokai.util.lang.getString import yokai.util.lang.getString
import kotlin.math.max
import kotlin.math.roundToInt
class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
LinearLayout(context, attrs), LinearLayout(context, attrs),
@ -637,7 +637,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
SeriesType('m', MR.strings.series_type), SeriesType('m', MR.strings.series_type),
Bookmarked('b', MR.strings.bookmarked), Bookmarked('b', MR.strings.bookmarked),
Tracked('t', MR.strings.tracking), Tracked('t', MR.strings.tracking),
ContentType('s', MR.strings.content_type) ContentType('s', MR.strings.content_type);
; ;
companion object { companion object {