Added option to change how library is grouped
By default (categories) By tag/genre By sources (with the extension icon attached) By status and by tracking status (closes #249)
This commit is contained in:
parent
59c108a972
commit
bc8ed36d1c
@ -28,6 +28,8 @@ interface Category : Serializable {
|
||||
|
||||
var isDynamic: Boolean
|
||||
|
||||
var sourceId: Long?
|
||||
|
||||
fun isAscending(): Boolean {
|
||||
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ class CategoryImpl : Category {
|
||||
|
||||
override var isDynamic: Boolean = false
|
||||
|
||||
override var sourceId: Long? = null
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
@ -273,6 +273,8 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
fun hideHopper() = flowPrefs.getBoolean("hide_hopper", false)
|
||||
|
||||
fun groupLibraryBy() = flowPrefs.getInt("group_library_by", 0)
|
||||
|
||||
// Tutorial preferences
|
||||
fun shownFilterTutorial() = flowPrefs.getBoolean("shown_filter_tutorial", false)
|
||||
|
||||
|
@ -126,15 +126,13 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
||||
val text = if (item.manga.isBlank()) return item.header?.category?.name.orEmpty()
|
||||
else when (getSort(position)) {
|
||||
LibrarySort.DRAG_AND_DROP -> {
|
||||
if (!preferences.hideCategories().getOrDefault()) {
|
||||
val title = item.manga.title
|
||||
if (preferences.removeArticles().getOrDefault()) title.removeArticles()
|
||||
.chop(15)
|
||||
else title.take(10)
|
||||
} else {
|
||||
val category = db.getCategoriesForManga(item.manga).executeAsBlocking()
|
||||
.firstOrNull()?.name
|
||||
if (item.header.category.isDynamic) {
|
||||
val category = db.getCategoriesForManga(item.manga).executeAsBlocking().firstOrNull()?.name
|
||||
category ?: recyclerView.context.getString(R.string.default_value)
|
||||
} else {
|
||||
val title = item.manga.title
|
||||
if (preferences.removeArticles().getOrDefault()) title.removeArticles().chop(15)
|
||||
else title.take(10)
|
||||
}
|
||||
}
|
||||
LibrarySort.LAST_READ -> {
|
||||
|
@ -51,6 +51,11 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.category.ManageCategoryDialog
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_DEFAULT
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_SOURCE
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_STATUS
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_TAG
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_TRACK_STATUS
|
||||
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
|
||||
import eu.kanade.tachiyomi.ui.main.BottomSheetController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
@ -379,7 +384,7 @@ class LibraryController(
|
||||
swipe_refresh.isRefreshing = false
|
||||
if (!LibraryUpdateService.isRunning()) {
|
||||
when {
|
||||
!presenter.showAllCategories -> {
|
||||
!presenter.showAllCategories || presenter.groupType != BY_DEFAULT -> {
|
||||
presenter.categories.find { it.id == presenter.currentCategory }?.let {
|
||||
updateLibrary(it)
|
||||
}
|
||||
@ -425,6 +430,31 @@ class LibraryController(
|
||||
FilterBottomSheet.ACTION_HIDE_FILTER_TIP -> showFilterTip()
|
||||
FilterBottomSheet.ACTION_DISPLAY -> DisplayBottomSheet(this).show()
|
||||
FilterBottomSheet.ACTION_EXPAND_COLLAPSE_ALL -> presenter.toggleAllCategoryVisibility()
|
||||
FilterBottomSheet.ACTION_GROUP_BY -> {
|
||||
val groupItems = mutableListOf(BY_DEFAULT, BY_TAG, BY_SOURCE, BY_STATUS)
|
||||
if (presenter.isLoggedIntoTracking) {
|
||||
groupItems.add(BY_TRACK_STATUS)
|
||||
}
|
||||
val items = groupItems.map { id ->
|
||||
MaterialMenuSheet.MenuSheetItem(
|
||||
id,
|
||||
LibraryGroup.groupTypeDrawableRes(id),
|
||||
LibraryGroup.groupTypeStringRes(id)
|
||||
)
|
||||
}
|
||||
MaterialMenuSheet(
|
||||
activity!!,
|
||||
items,
|
||||
activity!!.getString(R.string.group_library_by),
|
||||
presenter.groupType
|
||||
) { _, item ->
|
||||
preferences.groupLibraryBy().set(item)
|
||||
presenter.groupType = item
|
||||
recycler?.scrollToPosition(0)
|
||||
presenter.getLibrary()
|
||||
true
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,7 +692,8 @@ class LibraryController(
|
||||
category_hopper_frame.visibleIf(!singleCategory && !preferences.hideHopper().get())
|
||||
filter_bottom_sheet.updateButtons(
|
||||
showHideCategories = presenter.allCategories.size > 1,
|
||||
showExpand = !singleCategory && presenter.showAllCategories
|
||||
showExpand = !singleCategory && presenter.showAllCategories,
|
||||
groupType = presenter.groupType
|
||||
)
|
||||
adapter.isLongPressDragEnabled = canDrag()
|
||||
category_recycler.setCategories(presenter.categories)
|
||||
|
@ -0,0 +1,32 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
object LibraryGroup {
|
||||
|
||||
const val BY_DEFAULT = 0
|
||||
const val BY_TAG = 1
|
||||
const val BY_SOURCE = 2
|
||||
const val BY_STATUS = 3
|
||||
const val BY_TRACK_STATUS = 4
|
||||
|
||||
fun groupTypeStringRes(type: Int): Int {
|
||||
return when (type) {
|
||||
BY_STATUS -> R.string.status
|
||||
BY_TAG -> R.string.tag
|
||||
BY_TRACK_STATUS -> R.string.tracking
|
||||
BY_SOURCE -> R.string.sources
|
||||
else -> R.string.categories
|
||||
}
|
||||
}
|
||||
|
||||
fun groupTypeDrawableRes(type: Int): Int {
|
||||
return when (type) {
|
||||
BY_STATUS -> R.drawable.ic_progress_clock_24dp
|
||||
BY_TAG -> R.drawable.ic_style_24dp
|
||||
BY_TRACK_STATUS -> R.drawable.ic_sync_black_24dp
|
||||
BY_SOURCE -> R.drawable.ic_browse_24dp
|
||||
else -> R.drawable.ic_label_outline_white_24dp
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@ import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.icon
|
||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
@ -30,13 +32,16 @@ import eu.kanade.tachiyomi.util.view.visibleIf
|
||||
import kotlinx.android.synthetic.main.library_category_header_item.*
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class LibraryHeaderItem(
|
||||
private val categoryF: (Int) -> Category,
|
||||
private val catId: Int
|
||||
val catId: Int
|
||||
) :
|
||||
AbstractHeaderItem<LibraryHeaderItem.Holder>() {
|
||||
|
||||
private val sourceManager by injectLazy<SourceManager>()
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
return R.layout.library_category_header_item
|
||||
}
|
||||
@ -139,6 +144,13 @@ class LibraryHeaderItem(
|
||||
|
||||
if (category.isAlone) sectionText.text = ""
|
||||
else sectionText.text = category.name
|
||||
if (category.sourceId != null) {
|
||||
val icon = item.sourceManager.get(category.sourceId!!)?.icon()
|
||||
icon?.setBounds(0, 0, 32.dpToPx, 32.dpToPx)
|
||||
sectionText.setCompoundDrawablesRelative(icon, null, null, null)
|
||||
} else {
|
||||
sectionText.setCompoundDrawablesRelative(null, null, null, null)
|
||||
}
|
||||
|
||||
val isAscending = category.isAscending()
|
||||
val sortingMode = category.sortingMode()
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
@ -15,6 +16,10 @@ import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_DEFAULT
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_SOURCE
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_TAG
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup.BY_TRACK_STATUS
|
||||
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
|
||||
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet.Companion.STATE_EXCLUDE
|
||||
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet.Companion.STATE_IGNORE
|
||||
@ -29,7 +34,6 @@ import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
import java.util.Comparator
|
||||
|
||||
/**
|
||||
@ -50,6 +54,11 @@ class LibraryPresenter(
|
||||
|
||||
private val loggedServices by lazy { Injekt.get<TrackManager>().services.filter { it.isLogged } }
|
||||
|
||||
var groupType = preferences.groupLibraryBy().get()
|
||||
|
||||
val isLoggedIntoTracking
|
||||
get() = loggedServices.isNotEmpty()
|
||||
|
||||
/** Current categories of the library. */
|
||||
var categories: List<Category> = emptyList()
|
||||
private set
|
||||
@ -422,63 +431,77 @@ class LibraryPresenter(
|
||||
val categories = db.getCategories().executeAsBlocking().toMutableList()
|
||||
val showCategories = !preferences.hideCategories().getOrDefault()
|
||||
var libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||
val showAll = showAllCategories
|
||||
if (!showCategories) libraryManga = libraryManga.distinctBy { it.id }
|
||||
val categoryAll = Category.createAll(
|
||||
context,
|
||||
preferences.librarySortingMode().getOrDefault(),
|
||||
preferences.librarySortingAscending().getOrDefault()
|
||||
)
|
||||
val catItemAll = LibraryHeaderItem({ categoryAll }, -1)
|
||||
val categorySet = mutableSetOf<Int>()
|
||||
val headerItems = (categories.mapNotNull { category ->
|
||||
val id = category.id
|
||||
if (id == null) null
|
||||
else id to LibraryHeaderItem({ getCategory(id) }, id)
|
||||
} + (-1 to catItemAll) + (0 to LibraryHeaderItem({ getCategory(0) }, 0))).toMap()
|
||||
val items = libraryManga.mapNotNull {
|
||||
val headerItem = (if (!showCategories) catItemAll
|
||||
else headerItems[it.category]) ?: return@mapNotNull null
|
||||
categorySet.add(it.category)
|
||||
LibraryItem(it, headerItem)
|
||||
}.toMutableList()
|
||||
|
||||
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
|
||||
it.toIntOrNull()
|
||||
}.toMutableSet()
|
||||
|
||||
if (categorySet.contains(0)) categories.add(0, createDefaultCategory())
|
||||
if (showCategories) {
|
||||
categories.forEach { category ->
|
||||
val catId = category.id ?: return@forEach
|
||||
if (catId > 0 && !categorySet.contains(catId) &&
|
||||
(catId !in categoriesHidden || !showAll)) {
|
||||
val headerItem = headerItems[catId]
|
||||
if (headerItem != null) items.add(
|
||||
LibraryItem(LibraryManga.createBlank(catId), headerItem)
|
||||
)
|
||||
} else if (catId in categoriesHidden && showAll && categories.size > 1) {
|
||||
val mangaToRemove = items.filter { it.manga.category == catId }
|
||||
val mergedTitle = mangaToRemove.joinToString("-") {
|
||||
it.manga.title + "-" + it.manga.author
|
||||
}
|
||||
sectionedLibraryItems[catId] = mangaToRemove
|
||||
items.removeAll(mangaToRemove)
|
||||
val headerItem = headerItems[catId]
|
||||
if (headerItem != null) items.add(
|
||||
LibraryItem(LibraryManga.createHide(catId, mergedTitle), headerItem)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (groupType <= BY_DEFAULT || !showCategories) {
|
||||
libraryManga = libraryManga.distinctBy { it.id }
|
||||
}
|
||||
|
||||
categories.forEach {
|
||||
it.isHidden = it.id in categoriesHidden && showAll
|
||||
val items = if (groupType <= BY_DEFAULT || !showCategories) {
|
||||
val categoryAll = Category.createAll(
|
||||
context,
|
||||
preferences.librarySortingMode().getOrDefault(),
|
||||
preferences.librarySortingAscending().getOrDefault()
|
||||
)
|
||||
val catItemAll = LibraryHeaderItem({ categoryAll }, -1)
|
||||
val categorySet = mutableSetOf<Int>()
|
||||
val headerItems = (categories.mapNotNull { category ->
|
||||
val id = category.id
|
||||
if (id == null) null
|
||||
else id to LibraryHeaderItem({ getCategory(id) }, id)
|
||||
} + (-1 to catItemAll) + (0 to LibraryHeaderItem({ getCategory(0) }, 0))).toMap()
|
||||
|
||||
val items = libraryManga.mapNotNull {
|
||||
val headerItem = (if (!showCategories) catItemAll
|
||||
else headerItems[it.category]) ?: return@mapNotNull null
|
||||
categorySet.add(it.category)
|
||||
LibraryItem(it, headerItem)
|
||||
}.toMutableList()
|
||||
|
||||
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
|
||||
it.toIntOrNull()
|
||||
}.toMutableSet()
|
||||
|
||||
if (categorySet.contains(0)) categories.add(0, createDefaultCategory())
|
||||
if (showCategories) {
|
||||
categories.forEach { category ->
|
||||
val catId = category.id ?: return@forEach
|
||||
if (catId > 0 && !categorySet.contains(catId) && (catId !in categoriesHidden ||
|
||||
!showCategories)) {
|
||||
val headerItem = headerItems[catId]
|
||||
if (headerItem != null) items.add(
|
||||
LibraryItem(LibraryManga.createBlank(catId), headerItem)
|
||||
)
|
||||
} else if (catId in categoriesHidden && showCategories && categories.size > 1) {
|
||||
val mangaToRemove = items.filter { it.manga.category == catId }
|
||||
val mergedTitle = mangaToRemove.joinToString("-") {
|
||||
it.manga.title + "-" + it.manga.author
|
||||
}
|
||||
sectionedLibraryItems[catId] = mangaToRemove
|
||||
items.removeAll(mangaToRemove)
|
||||
val headerItem = headerItems[catId]
|
||||
if (headerItem != null) items.add(
|
||||
LibraryItem(LibraryManga.createHide(catId, mergedTitle), headerItem)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
categories.forEach {
|
||||
it.isHidden = it.id in categoriesHidden && showCategories
|
||||
}
|
||||
this.categories = if (!showCategories) {
|
||||
arrayListOf(categoryAll)
|
||||
} else {
|
||||
categories
|
||||
}
|
||||
|
||||
items
|
||||
} else {
|
||||
val (items, categories) = getCustomMangaItems(libraryManga)
|
||||
this.categories = categories
|
||||
items
|
||||
}
|
||||
|
||||
this.allCategories = categories
|
||||
this.categories = if (!showCategories) arrayListOf(categoryAll)
|
||||
else categories
|
||||
|
||||
hashCategories = HashMap(this.categories.mapNotNull {
|
||||
it.id!! to it
|
||||
@ -487,6 +510,86 @@ class LibraryPresenter(
|
||||
return items
|
||||
}
|
||||
|
||||
private fun getCustomMangaItems(libraryManga: List<LibraryManga>): Pair<List<LibraryItem>,
|
||||
List<Category>> {
|
||||
val tagItems: MutableMap<String, LibraryHeaderItem> = mutableMapOf()
|
||||
|
||||
// internal function to make headers
|
||||
fun makeOrGetHeader(name: String): LibraryHeaderItem {
|
||||
return if (tagItems.containsKey(name)) {
|
||||
tagItems[name]!!
|
||||
} else {
|
||||
val headerItem = LibraryHeaderItem({ getCategory(it) }, tagItems.count())
|
||||
tagItems[name] = headerItem
|
||||
headerItem
|
||||
}
|
||||
}
|
||||
|
||||
val items = libraryManga.mapNotNull { manga ->
|
||||
when (groupType) {
|
||||
BY_TAG -> {
|
||||
val tags = if (manga.genre.isNullOrBlank()) {
|
||||
listOf("Unknown")
|
||||
} else {
|
||||
manga.genre?.split(",")?.mapNotNull {
|
||||
val tag = it.trim()
|
||||
if (tag.isBlank()) null else tag
|
||||
} ?: listOf("Unknown")
|
||||
}
|
||||
tags.map {
|
||||
LibraryItem(manga, makeOrGetHeader(it))
|
||||
}
|
||||
}
|
||||
BY_TRACK_STATUS -> {
|
||||
val status: String = {
|
||||
val tracks = db.getTracks(manga).executeAsBlocking()
|
||||
val track = tracks.find { track ->
|
||||
loggedServices.any { it.id == track?.sync_id }
|
||||
}
|
||||
if (track != null) {
|
||||
loggedServices.find { it.id == track.sync_id }?.getStatus(track.status)
|
||||
?: context.getString(R.string.unknown)
|
||||
} else {
|
||||
context.getString(R.string.not_tracked)
|
||||
}
|
||||
}()
|
||||
listOf(LibraryItem(manga, makeOrGetHeader(status)))
|
||||
}
|
||||
BY_SOURCE -> {
|
||||
val source = sourceManager.getOrStub(manga.source)
|
||||
listOf(LibraryItem(manga, makeOrGetHeader("${source.name}◘•◘${source.id}")))
|
||||
}
|
||||
else -> listOf(LibraryItem(manga, makeOrGetHeader(mapStatus(manga.status))))
|
||||
}
|
||||
}.flatten()
|
||||
|
||||
val headers = tagItems.map { item ->
|
||||
Category.createCustom(
|
||||
item.key,
|
||||
preferences.librarySortingMode().getOrDefault(),
|
||||
preferences.librarySortingAscending().getOrDefault()
|
||||
).apply {
|
||||
id = item.value.catId
|
||||
if (name.contains("◘•◘")) {
|
||||
val split = name.split("◘•◘")
|
||||
name = split.first()
|
||||
sourceId = split.last().toLongOrNull()
|
||||
}
|
||||
}
|
||||
}.sortedBy { it.name }
|
||||
headers.forEachIndexed { index, category -> category.order = index }
|
||||
return items to headers
|
||||
}
|
||||
|
||||
private fun mapStatus(status: Int): String {
|
||||
return context.getString(when (status) {
|
||||
SManga.LICENSED -> R.string.licensed
|
||||
SManga.ONGOING -> R.string.ongoing
|
||||
SManga.COMPLETED -> R.string.completed
|
||||
else -> R.string.unknown
|
||||
})
|
||||
}
|
||||
|
||||
/** Create a default category with the sort set */
|
||||
private fun createDefaultCategory(): Category {
|
||||
val default = Category.createDefault(context)
|
||||
@ -632,6 +735,9 @@ class LibraryPresenter(
|
||||
val sort = category.sortingMode() ?: LibrarySort.ALPHA
|
||||
preferences.librarySortingMode().set(sort)
|
||||
preferences.librarySortingAscending().set(category.isAscending())
|
||||
categories.forEach {
|
||||
it.mangaSort = category.mangaSort
|
||||
}
|
||||
} else if (catId >= 0) {
|
||||
if (category.id == 0) preferences.defaultMangaOrder().set(category.mangaSort.toString())
|
||||
else Injekt.get<DatabaseHelper>().insertCategory(category).executeAsBlocking()
|
||||
|
@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryGroup
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.view.collapse
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
@ -126,6 +127,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
expand_categories.setOnClickListener {
|
||||
onGroupClicked(ACTION_EXPAND_COLLAPSE_ALL)
|
||||
}
|
||||
group_by.setOnClickListener {
|
||||
onGroupClicked(ACTION_GROUP_BY)
|
||||
}
|
||||
view_options.setOnClickListener {
|
||||
onGroupClicked(ACTION_DISPLAY)
|
||||
}
|
||||
@ -413,8 +417,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
}?.set(index + 1)
|
||||
onGroupClicked(ACTION_FILTER)
|
||||
}
|
||||
val hasFilters = hasActiveFilters()
|
||||
if (hasFilters && clearButton.parent == null) {
|
||||
filter_layout.addView(clearButton, 0)
|
||||
} else if (!hasFilters && clearButton.parent != null) {
|
||||
filter_layout.removeView(clearButton)
|
||||
}
|
||||
if (tracked?.isActivated == true && trackers != null && trackers?.parent == null) {
|
||||
filter_layout.addView(trackers, filterItems.indexOf(tracked!!) + 1)
|
||||
filter_layout.addView(trackers, filterItems.indexOf(tracked!!) + 2)
|
||||
filterItems.add(filterItems.indexOf(tracked!!) + 1, trackers!!)
|
||||
} else if (tracked?.isActivated == false && trackers?.parent != null) {
|
||||
filter_layout.removeView(trackers)
|
||||
@ -422,20 +432,15 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
FILTER_TRACKER = ""
|
||||
filterItems.remove(trackers!!)
|
||||
}
|
||||
val hasFilters = hasActiveFilters()
|
||||
if (hasFilters && clearButton.parent == null) {
|
||||
filter_layout.addView(clearButton, 0)
|
||||
} else if (!hasFilters && clearButton.parent != null) {
|
||||
filter_layout.removeView(clearButton)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateButtons(showHideCategories: Boolean, showExpand: Boolean) {
|
||||
fun updateButtons(showHideCategories: Boolean, showExpand: Boolean, groupType: Int) {
|
||||
hide_categories.visibleIf(showHideCategories)
|
||||
expand_categories.visibleIf(showExpand)
|
||||
expand_categories.visibleIf(showExpand && groupType == 0)
|
||||
first_layout.visibleIf(
|
||||
hide_categories.isVisible() || expand_categories.isVisible() || !second_layout.isVisible()
|
||||
)
|
||||
group_by.setIconResource(LibraryGroup.groupTypeDrawableRes(groupType))
|
||||
}
|
||||
|
||||
private fun clearFilters() {
|
||||
@ -479,6 +484,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
const val ACTION_HIDE_FILTER_TIP = 2
|
||||
const val ACTION_DISPLAY = 3
|
||||
const val ACTION_EXPAND_COLLAPSE_ALL = 4
|
||||
const val ACTION_GROUP_BY = 5
|
||||
|
||||
const val STATE_IGNORE = 0
|
||||
const val STATE_INCLUDE = 1
|
||||
|
10
app/src/main/res/drawable/ic_progress_clock_24dp.xml
Normal file
10
app/src/main/res/drawable/ic_progress_clock_24dp.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<!-- drawable/progress_clock.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M13,2.03V2.05L13,4.05C17.39,4.59 20.5,8.58 19.96,12.97C19.5,16.61 16.64,19.5 13,19.93V21.93C18.5,21.38 22.5,16.5 21.95,11C21.5,6.25 17.73,2.5 13,2.03M11,2.06C9.05,2.25 7.19,3 5.67,4.26L7.1,5.74C8.22,4.84 9.57,4.26 11,4.06V2.06M4.26,5.67C3,7.19 2.25,9.04 2.05,11H4.05C4.24,9.58 4.8,8.23 5.69,7.1L4.26,5.67M2.06,13C2.26,14.96 3.03,16.81 4.27,18.33L5.69,16.9C4.81,15.77 4.24,14.42 4.06,13H2.06M7.1,18.37L5.67,19.74C7.18,21 9.04,21.79 11,22V20C9.58,19.82 8.23,19.25 7.1,18.37M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_style_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_style_24dp.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M2.53,19.65l1.34,0.56v-9.03l-2.43,5.86c-0.41,1.02 0.08,2.19 1.09,2.61zM22.03,15.95L17.07,3.98c-0.31,-0.75 -1.04,-1.21 -1.81,-1.23 -0.26,0 -0.53,0.04 -0.79,0.15L7.1,5.95c-0.75,0.31 -1.21,1.03 -1.23,1.8 -0.01,0.27 0.04,0.54 0.15,0.8l4.96,11.97c0.31,0.76 1.05,1.22 1.83,1.23 0.26,0 0.52,-0.05 0.77,-0.15l7.36,-3.05c1.02,-0.42 1.51,-1.59 1.09,-2.6zM7.88,8.75c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1zM5.88,19.75c0,1.1 0.9,2 2,2h1.45l-3.45,-8.34v6.34z" />
|
||||
</vector>
|
@ -89,6 +89,18 @@
|
||||
app:iconTint="?android:attr/textColorPrimary" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/group_by"
|
||||
style="@style/Theme.Widget.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/group_library_by"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
app:icon="@drawable/ic_label_outline_white_24dp"
|
||||
app:iconTint="?android:attr/textColorPrimary" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/second_layout"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -70,6 +70,7 @@
|
||||
android:layout_marginTop="28dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:background="@drawable/square_ripple"
|
||||
android:drawablePadding="6dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center|start"
|
||||
android:inputType="none"
|
||||
|
@ -123,6 +123,7 @@
|
||||
|
||||
<string name="read_progress">Read progress</string>
|
||||
<string name="series_type">Series type</string>
|
||||
<string name="group_library_by">Group library by…</string>
|
||||
|
||||
<!-- Library Sort -->
|
||||
<string name="sort_by">Sort by</string>
|
||||
@ -713,6 +714,7 @@
|
||||
<string name="sort_and_filter">Sort & Filter</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="tag">Tag</string>
|
||||
<string name="top">Top</string>
|
||||
<string name="undo">Undo</string>
|
||||
<string name="unknown_error">Unknown error</string>
|
||||
|
Loading…
Reference in New Issue
Block a user