mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 14:21:47 +01:00
Option to collapse dynamic categories
This commit is contained in:
parent
94a90c6cec
commit
4bb6dbf528
@ -69,6 +69,14 @@ operator fun <T> com.tfcporciuncula.flow.Preference<Set<T>>.minusAssign(item: T)
|
||||
set(get() - item)
|
||||
}
|
||||
|
||||
operator fun <T> com.tfcporciuncula.flow.Preference<Set<T>>.plusAssign(item: Collection<T>) {
|
||||
set(get() + item)
|
||||
}
|
||||
|
||||
operator fun <T> com.tfcporciuncula.flow.Preference<Set<T>>.minusAssign(item: Collection<T>) {
|
||||
set(get() - item)
|
||||
}
|
||||
|
||||
class PreferencesHelper(val context: Context) {
|
||||
|
||||
private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
@ -270,6 +278,8 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
fun collapsedCategories() = rxPrefs.getStringSet("collapsed_categories", mutableSetOf())
|
||||
|
||||
fun collapsedDynamicCategories() = flowPrefs.getStringSet("collapsed_dynamic_categories", mutableSetOf())
|
||||
|
||||
fun hiddenSources() = flowPrefs.getStringSet("hidden_catalogues", mutableSetOf())
|
||||
|
||||
fun pinnedCatalogues() = rxPrefs.getStringSet("pinned_catalogues", emptySet())
|
||||
|
@ -918,10 +918,7 @@ class LibraryController(
|
||||
)
|
||||
adapter.isLongPressDragEnabled = canDrag()
|
||||
binding.categoryRecycler.setCategories(presenter.categories)
|
||||
displaySheet?.setExpandText(
|
||||
showExpanded = !singleCategory && presenter.showAllCategories,
|
||||
allExpanded = preferences.collapsedCategories().getOrDefault().isNotEmpty()
|
||||
)
|
||||
displaySheet?.setExpandText(canCollapseOrExpandCategory())
|
||||
if (shouldScrollToTop) {
|
||||
binding.libraryGridRecycler.recycler.scrollToPosition(0)
|
||||
shouldScrollToTop = false
|
||||
@ -1382,6 +1379,19 @@ class LibraryController(
|
||||
presenter.toggleCategoryVisibility(catId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Nullable Boolean to tell is all is collapsed/expanded/applicable
|
||||
* true = all categories are expanded
|
||||
* false = all or some categories are collapsed
|
||||
* null = is in single category mode
|
||||
*/
|
||||
fun canCollapseOrExpandCategory(): Boolean? {
|
||||
if (singleCategory || !presenter.showAllCategories) {
|
||||
return null
|
||||
}
|
||||
return presenter.allCategoriesExpanded()
|
||||
}
|
||||
|
||||
override fun manageCategory(position: Int) {
|
||||
val category = (adapter.getItem(position) as? LibraryHeaderItem)?.category ?: return
|
||||
if (!category.isDynamic) {
|
||||
|
@ -80,14 +80,6 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
|
||||
}
|
||||
val category = item.category
|
||||
|
||||
if (category.isDynamic) {
|
||||
binding.categoryHeaderLayout.background = null
|
||||
binding.categoryTitle.background = null
|
||||
} else {
|
||||
binding.categoryHeaderLayout.setBackgroundResource(R.drawable.list_item_selector)
|
||||
binding.categoryTitle.setBackgroundResource(R.drawable.square_ripple)
|
||||
}
|
||||
|
||||
if (category.isAlone && !category.isDynamic) binding.categoryTitle.text = ""
|
||||
else binding.categoryTitle.text = category.name
|
||||
if (category.sourceId != null) {
|
||||
@ -115,7 +107,7 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
|
||||
when {
|
||||
adapter.mode == SelectableAdapter.Mode.MULTI -> {
|
||||
binding.checkbox.visibleIf(!category.isHidden)
|
||||
binding.collapseArrow.visibleIf(category.isHidden && !adapter.isSingleCategory && !category.isDynamic)
|
||||
binding.collapseArrow.visibleIf(category.isHidden && !adapter.isSingleCategory)
|
||||
binding.updateButton.gone()
|
||||
binding.catProgress.gone()
|
||||
setSelection()
|
||||
@ -127,13 +119,13 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
|
||||
binding.updateButton.gone()
|
||||
}
|
||||
LibraryUpdateService.categoryInQueue(category.id) -> {
|
||||
binding.collapseArrow.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
|
||||
binding.collapseArrow.visibleIf(!adapter.isSingleCategory)
|
||||
binding.checkbox.gone()
|
||||
binding.catProgress.visible()
|
||||
binding.updateButton.invisible()
|
||||
}
|
||||
else -> {
|
||||
binding.collapseArrow.visibleIf(!adapter.isSingleCategory && !category.isDynamic)
|
||||
binding.collapseArrow.visibleIf(!adapter.isSingleCategory)
|
||||
binding.catProgress.gone()
|
||||
binding.checkbox.gone()
|
||||
binding.updateButton.visibleIf(!adapter.isSingleCategory)
|
||||
|
@ -11,6 +11,8 @@ import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.preference.minusAssign
|
||||
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
@ -581,12 +583,13 @@ class LibraryPresenter(
|
||||
}
|
||||
BY_SOURCE -> {
|
||||
val source = sourceManager.getOrStub(manga.source)
|
||||
listOf(LibraryItem(manga, makeOrGetHeader("${source.name}◘•◘${source.id}")))
|
||||
listOf(LibraryItem(manga, makeOrGetHeader("${source.name}$sourceSplitter${source.id}")))
|
||||
}
|
||||
else -> listOf(LibraryItem(manga, makeOrGetHeader(mapStatus(manga.status))))
|
||||
}
|
||||
}.flatten()
|
||||
}.flatten().toMutableList()
|
||||
|
||||
val hiddenDynamics = preferences.collapsedDynamicCategories().get()
|
||||
val headers = tagItems.map { item ->
|
||||
Category.createCustom(
|
||||
item.key,
|
||||
@ -594,11 +597,12 @@ class LibraryPresenter(
|
||||
preferences.librarySortingAscending().getOrDefault()
|
||||
).apply {
|
||||
id = item.value.catId
|
||||
if (name.contains("◘•◘")) {
|
||||
val split = name.split("◘•◘")
|
||||
if (name.contains(sourceSplitter)) {
|
||||
val split = name.split(sourceSplitter)
|
||||
name = split.first()
|
||||
sourceId = split.last().toLongOrNull()
|
||||
}
|
||||
isHidden = getDynamicCategoryName(this) in hiddenDynamics
|
||||
}
|
||||
}.sortedBy {
|
||||
if (groupType == BY_TRACK_STATUS) {
|
||||
@ -607,6 +611,22 @@ class LibraryPresenter(
|
||||
it.name
|
||||
}
|
||||
}
|
||||
headers.forEach { category ->
|
||||
val catId = category.id ?: return@forEach
|
||||
val headerItem = tagItems[if (category.sourceId != null) "${category.name}$sourceSplitter${category.sourceId}" else category.name]
|
||||
if (category.isHidden) {
|
||||
val mangaToRemove = items.filter { it.header.catId == catId }
|
||||
val mergedTitle = mangaToRemove.joinToString("-") {
|
||||
it.manga.title + "-" + it.manga.author
|
||||
}
|
||||
sectionedLibraryItems[catId] = mangaToRemove
|
||||
items.removeAll { it.header.catId == catId }
|
||||
if (headerItem != null) items.add(
|
||||
LibraryItem(LibraryManga.createHide(catId, mergedTitle), headerItem)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
headers.forEachIndexed { index, category -> category.order = index }
|
||||
return items to headers
|
||||
}
|
||||
@ -858,28 +878,61 @@ class LibraryPresenter(
|
||||
}
|
||||
|
||||
fun toggleCategoryVisibility(categoryId: Int) {
|
||||
if (categories.find { it.id == categoryId }?.isDynamic == true) return
|
||||
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
|
||||
it.toIntOrNull()
|
||||
}.toMutableSet()
|
||||
if (categoryId in categoriesHidden) {
|
||||
categoriesHidden.remove(categoryId)
|
||||
// if (categories.find { it.id == categoryId }?.isDynamic == true) return
|
||||
if (groupType == BY_DEFAULT) {
|
||||
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
|
||||
it.toIntOrNull()
|
||||
}.toMutableSet()
|
||||
if (categoryId in categoriesHidden) {
|
||||
categoriesHidden.remove(categoryId)
|
||||
} else {
|
||||
categoriesHidden.add(categoryId)
|
||||
}
|
||||
preferences.collapsedCategories()
|
||||
.set(categoriesHidden.map { it.toString() }.toMutableSet())
|
||||
} else {
|
||||
categoriesHidden.add(categoryId)
|
||||
val categoriesHidden = preferences.collapsedDynamicCategories().get().toMutableSet()
|
||||
val category = getCategory(categoryId)
|
||||
val dynamicName = getDynamicCategoryName(category)
|
||||
if (dynamicName in categoriesHidden) {
|
||||
categoriesHidden.remove(dynamicName)
|
||||
} else {
|
||||
categoriesHidden.add(dynamicName)
|
||||
}
|
||||
preferences.collapsedDynamicCategories().set(categoriesHidden)
|
||||
}
|
||||
preferences.collapsedCategories().set(categoriesHidden.map { it.toString() }.toMutableSet())
|
||||
getLibrary()
|
||||
}
|
||||
|
||||
private fun getDynamicCategoryName(category: Category): String =
|
||||
groupType.toString() + dynamicCategorySplitter + (category.sourceId?.toString() ?: category.name)
|
||||
|
||||
fun toggleAllCategoryVisibility() {
|
||||
if (preferences.collapsedCategories().getOrDefault().isEmpty()) {
|
||||
preferences.collapsedCategories().set(allCategories.map { it.id.toString() }.toMutableSet())
|
||||
if (groupType == BY_DEFAULT) {
|
||||
if (allCategoriesExpanded()) {
|
||||
preferences.collapsedCategories()
|
||||
.set(allCategories.map { it.id.toString() }.toMutableSet())
|
||||
} else {
|
||||
preferences.collapsedCategories().set(mutableSetOf())
|
||||
}
|
||||
} else {
|
||||
preferences.collapsedCategories().set(mutableSetOf())
|
||||
if (allCategoriesExpanded()) {
|
||||
preferences.collapsedDynamicCategories() += categories.map { getDynamicCategoryName(it) }
|
||||
} else {
|
||||
preferences.collapsedDynamicCategories() -= categories.map { getDynamicCategoryName(it) }
|
||||
}
|
||||
}
|
||||
getLibrary()
|
||||
}
|
||||
|
||||
fun allCategoriesExpanded(): Boolean {
|
||||
return if (groupType == BY_DEFAULT) {
|
||||
preferences.collapsedCategories().getOrDefault().isEmpty()
|
||||
} else {
|
||||
categories.none { it.isHidden }
|
||||
}
|
||||
}
|
||||
|
||||
/** download All unread */
|
||||
fun downloadUnread(mangaList: List<Manga>) {
|
||||
scope.launch {
|
||||
@ -925,6 +978,8 @@ class LibraryPresenter(
|
||||
companion object {
|
||||
private var lastLibraryItems: List<LibraryItem>? = null
|
||||
private var lastCategories: List<Category>? = null
|
||||
private const val sourceSplitter = "◘•◘"
|
||||
private const val dynamicCategorySplitter = "▄╪\t▄╪\t▄"
|
||||
|
||||
/** Give library manga to a date added based on min chapter fetch */
|
||||
fun updateDB() {
|
||||
|
@ -49,13 +49,11 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
}
|
||||
}
|
||||
|
||||
fun showExpandCategories(show: Boolean) {
|
||||
binding.expandCollapseCategories.isVisible = show
|
||||
}
|
||||
|
||||
fun setExpandText(expand: Boolean, animated: Boolean = true) {
|
||||
fun setExpandText(allExpanded: Boolean?, animated: Boolean = true) {
|
||||
binding.expandCollapseCategories.isVisible = allExpanded != null
|
||||
allExpanded ?: return
|
||||
binding.expandCollapseCategories.setText(
|
||||
if (expand) {
|
||||
if (!allExpanded) {
|
||||
R.string.expand_all_categories
|
||||
} else {
|
||||
R.string.collapse_all_categories
|
||||
@ -63,7 +61,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
)
|
||||
if (animated) {
|
||||
binding.expandCollapseCategories.setIconResource(
|
||||
if (expand) {
|
||||
if (!allExpanded) {
|
||||
R.drawable.anim_expand_less_to_more
|
||||
} else {
|
||||
R.drawable.anim_expand_more_to_less
|
||||
@ -72,7 +70,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
(binding.expandCollapseCategories.icon as? AnimatedVectorDrawable)?.start()
|
||||
} else {
|
||||
binding.expandCollapseCategories.setIconResource(
|
||||
if (expand) {
|
||||
if (!allExpanded) {
|
||||
R.drawable.ic_expand_more_24dp
|
||||
} else {
|
||||
R.drawable.ic_expand_less_24dp
|
||||
|
@ -6,15 +6,11 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||
import eu.kanade.tachiyomi.ui.setting.SettingsLibraryController
|
||||
import eu.kanade.tachiyomi.util.view.compatToolTipText
|
||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
open class TabbedLibraryDisplaySheet(val controller: Controller) :
|
||||
TabbedBottomSheetDialog(controller.activity!!) {
|
||||
@ -43,21 +39,15 @@ open class TabbedLibraryDisplaySheet(val controller: Controller) :
|
||||
}
|
||||
|
||||
if (controller is LibraryController) {
|
||||
setExpandText(
|
||||
!controller.singleCategory && controller.presenter.showAllCategories,
|
||||
Injekt.get<PreferencesHelper>().collapsedCategories().getOrDefault().isNotEmpty(),
|
||||
false
|
||||
)
|
||||
setExpandText(controller.canCollapseOrExpandCategory(), false)
|
||||
} else {
|
||||
setExpandText(showExpanded = false, allExpanded = false)
|
||||
setExpandText(null)
|
||||
categoryView.binding.addCategoriesButton.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
fun setExpandText(showExpanded: Boolean, allExpanded: Boolean, animated: Boolean = true) {
|
||||
categoryView.showExpandCategories(showExpanded)
|
||||
fun setExpandText(allExpanded: Boolean?, animated: Boolean = true) =
|
||||
categoryView.setExpandText(allExpanded, animated)
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
super.dismiss()
|
||||
|
Loading…
Reference in New Issue
Block a user