mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 14:51:50 +01:00
LibrarySort is now an enum
with lot of helper methods and stuff With it came the refactoring of Category sort options Also a new icon for last fetched
This commit is contained in:
parent
1ceb9692bb
commit
a71bdc14c5
@ -1,6 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.data.database.models
|
package eu.kanade.tachiyomi.data.database.models
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.annotation.StringRes
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
@ -21,9 +22,6 @@ interface Category : Serializable {
|
|||||||
|
|
||||||
var isAlone: Boolean
|
var isAlone: Boolean
|
||||||
|
|
||||||
val nameLower: String
|
|
||||||
get() = name.toLowerCase()
|
|
||||||
|
|
||||||
var isHidden: Boolean
|
var isHidden: Boolean
|
||||||
|
|
||||||
var isDynamic: Boolean
|
var isDynamic: Boolean
|
||||||
@ -34,73 +32,24 @@ interface Category : Serializable {
|
|||||||
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
|
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sortingMode(nullAsDND: Boolean = false): Int? = when (mangaSort) {
|
fun sortingMode(nullAsDND: Boolean = false): LibrarySort? = LibrarySort.valueOf(mangaSort)
|
||||||
ALPHA_ASC, ALPHA_DSC -> LibrarySort.ALPHA
|
?: if (nullAsDND && !isDynamic) LibrarySort.DragAndDrop else null
|
||||||
UPDATED_ASC, UPDATED_DSC -> LibrarySort.LATEST_CHAPTER
|
|
||||||
UNREAD_ASC, UNREAD_DSC -> LibrarySort.UNREAD
|
|
||||||
LAST_READ_ASC, LAST_READ_DSC -> LibrarySort.LAST_READ
|
|
||||||
TOTAL_ASC, TOTAL_DSC -> LibrarySort.TOTAL
|
|
||||||
DRAG_AND_DROP -> LibrarySort.DRAG_AND_DROP
|
|
||||||
DATE_ADDED_ASC, DATE_ADDED_DSC -> LibrarySort.DATE_ADDED
|
|
||||||
LAST_FETCHED_ASC, LAST_FETCHED_DSC -> LibrarySort.LAST_FETCHED
|
|
||||||
else -> if (nullAsDND && !isDynamic) LibrarySort.DRAG_AND_DROP else null
|
|
||||||
}
|
|
||||||
|
|
||||||
val isDragAndDrop
|
val isDragAndDrop
|
||||||
get() = (mangaSort == null || mangaSort == DRAG_AND_DROP) && !isDynamic
|
get() = (
|
||||||
|
mangaSort == null ||
|
||||||
|
mangaSort == LibrarySort.DragAndDrop.categoryValue
|
||||||
|
) && !isDynamic
|
||||||
|
|
||||||
fun sortRes(): Int = when (mangaSort) {
|
@StringRes
|
||||||
ALPHA_ASC, ALPHA_DSC -> R.string.title
|
fun sortRes(): Int =
|
||||||
UPDATED_ASC, UPDATED_DSC -> R.string.latest_chapter
|
(LibrarySort.valueOf(mangaSort) ?: LibrarySort.DragAndDrop).stringRes(isDynamic)
|
||||||
UNREAD_ASC, UNREAD_DSC -> R.string.unread
|
|
||||||
LAST_READ_ASC, LAST_READ_DSC -> R.string.last_read
|
|
||||||
TOTAL_ASC, TOTAL_DSC -> R.string.total_chapters
|
|
||||||
DATE_ADDED_ASC, DATE_ADDED_DSC -> R.string.date_added
|
|
||||||
LAST_FETCHED_ASC, LAST_FETCHED_DSC -> R.string.last_fetched
|
|
||||||
else -> if (isDynamic) R.string.category else R.string.drag_and_drop
|
|
||||||
}
|
|
||||||
|
|
||||||
fun catSortingMode(): Int? = when (mangaSort) {
|
|
||||||
ALPHA_ASC, ALPHA_DSC -> 0
|
|
||||||
UPDATED_ASC, UPDATED_DSC -> 1
|
|
||||||
UNREAD_ASC, UNREAD_DSC -> 2
|
|
||||||
LAST_READ_ASC, LAST_READ_DSC -> 3
|
|
||||||
TOTAL_ASC, TOTAL_DSC -> 4
|
|
||||||
DATE_ADDED_ASC, DATE_ADDED_DSC -> 5
|
|
||||||
LAST_FETCHED_ASC, LAST_FETCHED_DSC -> 6
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun changeSortTo(sort: Int) {
|
fun changeSortTo(sort: Int) {
|
||||||
mangaSort = when (sort) {
|
mangaSort = (LibrarySort.valueOf(sort) ?: LibrarySort.Title).categoryValue
|
||||||
LibrarySort.ALPHA -> ALPHA_ASC
|
|
||||||
LibrarySort.LATEST_CHAPTER -> UPDATED_ASC
|
|
||||||
LibrarySort.UNREAD -> UNREAD_ASC
|
|
||||||
LibrarySort.LAST_READ -> LAST_READ_ASC
|
|
||||||
LibrarySort.TOTAL -> ALPHA_ASC
|
|
||||||
LibrarySort.DATE_ADDED -> DATE_ADDED_ASC
|
|
||||||
LibrarySort.LAST_FETCHED -> LAST_FETCHED_ASC
|
|
||||||
else -> ALPHA_ASC
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DRAG_AND_DROP = 'D'
|
|
||||||
const val ALPHA_ASC = 'a'
|
|
||||||
const val ALPHA_DSC = 'b'
|
|
||||||
const val UPDATED_ASC = 'c'
|
|
||||||
const val UPDATED_DSC = 'd'
|
|
||||||
const val UNREAD_ASC = 'e'
|
|
||||||
const val UNREAD_DSC = 'f'
|
|
||||||
const val LAST_READ_ASC = 'g'
|
|
||||||
const val LAST_READ_DSC = 'h'
|
|
||||||
const val TOTAL_ASC = 'i'
|
|
||||||
const val TOTAL_DSC = 'j'
|
|
||||||
const val DATE_ADDED_ASC = 'k'
|
|
||||||
const val DATE_ADDED_DSC = 'l'
|
|
||||||
const val LAST_FETCHED_ASC = 'm'
|
|
||||||
const val LAST_FETCHED_DSC = 'n'
|
|
||||||
|
|
||||||
fun create(name: String): Category = CategoryImpl().apply {
|
fun create(name: String): Category = CategoryImpl().apply {
|
||||||
this.name = name
|
this.name = name
|
||||||
}
|
}
|
||||||
@ -112,18 +61,9 @@ interface Category : Serializable {
|
|||||||
|
|
||||||
fun createCustom(name: String, libSort: Int, ascending: Boolean): Category =
|
fun createCustom(name: String, libSort: Int, ascending: Boolean): Category =
|
||||||
create(name).apply {
|
create(name).apply {
|
||||||
mangaSort = when (libSort) {
|
val librarySort = LibrarySort.valueOf(libSort) ?: LibrarySort.DragAndDrop
|
||||||
LibrarySort.ALPHA -> ALPHA_ASC
|
changeSortTo(librarySort.mainValue)
|
||||||
LibrarySort.LATEST_CHAPTER -> UPDATED_ASC
|
if (mangaSort != LibrarySort.DragAndDrop.categoryValue && !ascending) {
|
||||||
LibrarySort.UNREAD -> UNREAD_ASC
|
|
||||||
LibrarySort.LAST_READ -> LAST_READ_ASC
|
|
||||||
LibrarySort.TOTAL -> TOTAL_ASC
|
|
||||||
LibrarySort.DATE_ADDED -> DATE_ADDED_ASC
|
|
||||||
LibrarySort.LAST_FETCHED -> LAST_FETCHED_ASC
|
|
||||||
LibrarySort.DRAG_AND_DROP -> DRAG_AND_DROP
|
|
||||||
else -> DRAG_AND_DROP
|
|
||||||
}
|
|
||||||
if (mangaSort != DRAG_AND_DROP && !ascending) {
|
|
||||||
mangaSort = mangaSort?.plus(1)
|
mangaSort = mangaSort?.plus(1)
|
||||||
}
|
}
|
||||||
isDynamic = true
|
isDynamic = true
|
||||||
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -75,7 +76,7 @@ class CategoryPresenter(
|
|||||||
cat.order = categories.maxOf { it.order } + 1
|
cat.order = categories.maxOf { it.order } + 1
|
||||||
|
|
||||||
// Insert into database.
|
// Insert into database.
|
||||||
cat.mangaSort = Category.ALPHA_ASC
|
cat.mangaSort = LibrarySort.Title.categoryValue
|
||||||
db.insertCategory(cat).executeAsBlocking()
|
db.insertCategory(cat).executeAsBlocking()
|
||||||
val cats = db.getCategories().executeAsBlocking()
|
val cats = db.getCategories().executeAsBlocking()
|
||||||
val newCat = cats.find { it.name == name } ?: return false
|
val newCat = cats.find { it.name == name } ?: return false
|
||||||
|
@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.databinding.MangaCategoryDialogBinding
|
import eu.kanade.tachiyomi.databinding.MangaCategoryDialogBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
|
import eu.kanade.tachiyomi.ui.library.LibrarySort
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
if (this.category == null) {
|
if (this.category == null) {
|
||||||
val categories = db.getCategories().executeAsBlocking()
|
val categories = db.getCategories().executeAsBlocking()
|
||||||
category.order = categories.maxOf { it.order } + 1
|
category.order = categories.maxOf { it.order } + 1
|
||||||
category.mangaSort = Category.ALPHA_ASC
|
category.mangaSort = LibrarySort.Title.categoryValue
|
||||||
val dbCategory = db.insertCategory(category).executeAsBlocking()
|
val dbCategory = db.insertCategory(category).executeAsBlocking()
|
||||||
category.id = dbCategory.insertedId()?.toInt()
|
category.id = dbCategory.insertedId()?.toInt()
|
||||||
this.category = category
|
this.category = category
|
||||||
|
@ -140,7 +140,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
is LibraryItem -> {
|
is LibraryItem -> {
|
||||||
val text = if (item.manga.isBlank()) return item.header?.category?.name.orEmpty()
|
val text = if (item.manga.isBlank()) return item.header?.category?.name.orEmpty()
|
||||||
else when (getSort(position)) {
|
else when (getSort(position)) {
|
||||||
LibrarySort.DRAG_AND_DROP -> {
|
LibrarySort.DragAndDrop -> {
|
||||||
if (item.header.category.isDynamic) {
|
if (item.header.category.isDynamic) {
|
||||||
val category = db.getCategoriesForManga(item.manga).executeAsBlocking().firstOrNull()?.name
|
val category = db.getCategoriesForManga(item.manga).executeAsBlocking().firstOrNull()?.name
|
||||||
category ?: recyclerView.context.getString(R.string.default_value)
|
category ?: recyclerView.context.getString(R.string.default_value)
|
||||||
@ -150,7 +150,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
else title.take(10)
|
else title.take(10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibrarySort.LAST_FETCHED -> {
|
LibrarySort.LastFetched -> {
|
||||||
val id = item.manga.id ?: return ""
|
val id = item.manga.id ?: return ""
|
||||||
val history = db.getChapters(id).executeAsBlocking()
|
val history = db.getChapters(id).executeAsBlocking()
|
||||||
val last = history.maxOfOrNull { it.date_fetch }
|
val last = history.maxOfOrNull { it.date_fetch }
|
||||||
@ -163,7 +163,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
"N/A"
|
"N/A"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibrarySort.LAST_READ -> {
|
LibrarySort.LastRead -> {
|
||||||
val id = item.manga.id ?: return ""
|
val id = item.manga.id ?: return ""
|
||||||
val history = db.getHistoryByMangaId(id).executeAsBlocking()
|
val history = db.getHistoryByMangaId(id).executeAsBlocking()
|
||||||
val last = history.maxOfOrNull { it.last_read }
|
val last = history.maxOfOrNull { it.last_read }
|
||||||
@ -176,12 +176,12 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
"N/A"
|
"N/A"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibrarySort.UNREAD -> {
|
LibrarySort.Unread -> {
|
||||||
val unread = item.manga.unread
|
val unread = item.manga.unread
|
||||||
if (unread > 0) recyclerView.context.getString(R.string._unread, unread)
|
if (unread > 0) recyclerView.context.getString(R.string._unread, unread)
|
||||||
else recyclerView.context.getString(R.string.read)
|
else recyclerView.context.getString(R.string.read)
|
||||||
}
|
}
|
||||||
LibrarySort.TOTAL -> {
|
LibrarySort.TotalChapters -> {
|
||||||
val total = item.manga.totalChapters
|
val total = item.manga.totalChapters
|
||||||
if (total > 0) recyclerView.resources.getQuantityString(
|
if (total > 0) recyclerView.resources.getQuantityString(
|
||||||
R.plurals.chapters_plural,
|
R.plurals.chapters_plural,
|
||||||
@ -192,7 +192,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
"N/A"
|
"N/A"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibrarySort.LATEST_CHAPTER -> {
|
LibrarySort.LatestChapter -> {
|
||||||
val lastUpdate = item.manga.last_update
|
val lastUpdate = item.manga.last_update
|
||||||
if (lastUpdate > 0) {
|
if (lastUpdate > 0) {
|
||||||
recyclerView.context.getString(
|
recyclerView.context.getString(
|
||||||
@ -203,7 +203,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
"N/A"
|
"N/A"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LibrarySort.DATE_ADDED -> {
|
LibrarySort.DateAdded -> {
|
||||||
val added = item.manga.date_added
|
val added = item.manga.date_added
|
||||||
if (added > 0) {
|
if (added > 0) {
|
||||||
recyclerView.context.getString(R.string.added_, added.timeSpanFromNow(preferences.context))
|
recyclerView.context.getString(R.string.added_, added.timeSpanFromNow(preferences.context))
|
||||||
@ -211,7 +211,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
"N/A"
|
"N/A"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
LibrarySort.Title -> {
|
||||||
val title = if (preferences.removeArticles().getOrDefault()) {
|
val title = if (preferences.removeArticles().getOrDefault()) {
|
||||||
item.manga.title.removeArticles()
|
item.manga.title.removeArticles()
|
||||||
} else {
|
} else {
|
||||||
@ -230,13 +230,9 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSort(position: Int): Int {
|
private fun getSort(position: Int): LibrarySort {
|
||||||
val header = (getItem(position) as? LibraryItem)?.header
|
val header = (getItem(position) as? LibraryItem)?.header
|
||||||
return if (header != null) {
|
return header?.category?.sortingMode() ?: LibrarySort.DragAndDrop
|
||||||
header.category.sortingMode() ?: LibrarySort.DRAG_AND_DROP
|
|
||||||
} else {
|
|
||||||
LibrarySort.DRAG_AND_DROP
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LibraryListener {
|
interface LibraryListener {
|
||||||
@ -244,7 +240,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
|||||||
fun onItemReleased(position: Int)
|
fun onItemReleased(position: Int)
|
||||||
fun canDrag(): Boolean
|
fun canDrag(): Boolean
|
||||||
fun updateCategory(catId: Int): Boolean
|
fun updateCategory(catId: Int): Boolean
|
||||||
fun sortCategory(catId: Int, sortBy: Int)
|
fun sortCategory(catId: Int, sortBy: Char)
|
||||||
fun selectAll(position: Int)
|
fun selectAll(position: Int)
|
||||||
fun allSelected(position: Int): Boolean
|
fun allSelected(position: Int): Boolean
|
||||||
fun toggleCategoryVisibility(position: Int)
|
fun toggleCategoryVisibility(position: Int)
|
||||||
|
@ -97,7 +97,6 @@ import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
|||||||
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
import eu.kanade.tachiyomi.widget.EndAnimatorListener
|
import eu.kanade.tachiyomi.widget.EndAnimatorListener
|
||||||
import kotlinx.coroutines.cancel
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
@ -1422,9 +1421,9 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sortCategory(catId: Int, sortBy: Int) {
|
override fun sortCategory(catId: Int, sortBy: Char) {
|
||||||
val category = presenter.categories.find { it.id == catId }
|
val category = presenter.categories.find { it.id == catId }
|
||||||
if (category?.isDynamic == false && ('a' + (sortBy - 1)) == Category.DRAG_AND_DROP) {
|
if (category?.isDynamic == false && sortBy == LibrarySort.DragAndDrop.categoryValue) {
|
||||||
val item = adapter.findCategoryHeader(catId) ?: return
|
val item = adapter.findCategoryHeader(catId) ?: return
|
||||||
val libraryItems = adapter.getSectionItems(item)
|
val libraryItems = adapter.getSectionItems(item)
|
||||||
.filterIsInstance<LibraryItem>()
|
.filterIsInstance<LibraryItem>()
|
||||||
|
@ -4,6 +4,7 @@ import android.app.Activity
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
@ -90,15 +91,7 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
|
|||||||
|
|
||||||
val isAscending = category.isAscending()
|
val isAscending = category.isAscending()
|
||||||
val sortingMode = category.sortingMode()
|
val sortingMode = category.sortingMode()
|
||||||
val sortDrawable = when {
|
val sortDrawable = getSortRes(sortingMode, isAscending, R.drawable.ic_sort_24dp)
|
||||||
sortingMode == LibrarySort.DRAG_AND_DROP || sortingMode == null -> R.drawable.ic_sort_24dp
|
|
||||||
if (sortingMode == LibrarySort.DATE_ADDED ||
|
|
||||||
sortingMode == LibrarySort.LATEST_CHAPTER ||
|
|
||||||
sortingMode == LibrarySort.LAST_READ ||
|
|
||||||
sortingMode == LibrarySort.LAST_FETCHED
|
|
||||||
) !isAscending else isAscending -> R.drawable.ic_arrow_downward_24dp
|
|
||||||
else -> R.drawable.ic_arrow_upward_24dp
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.categorySort.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, sortDrawable, 0)
|
binding.categorySort.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, sortDrawable, 0)
|
||||||
binding.categorySort.setText(category.sortRes())
|
binding.categorySort.setText(category.sortRes())
|
||||||
@ -146,66 +139,13 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
|
|||||||
val category =
|
val category =
|
||||||
(adapter.getItem(flexibleAdapterPosition) as? LibraryHeaderItem)?.category ?: return
|
(adapter.getItem(flexibleAdapterPosition) as? LibraryHeaderItem)?.category ?: return
|
||||||
adapter.controller.activity?.let { activity ->
|
adapter.controller.activity?.let { activity ->
|
||||||
val items = mutableListOf(
|
val items = LibrarySort.values().map { it.menuSheetItem(category.isDynamic) }
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.ALPHA,
|
|
||||||
R.drawable.ic_sort_by_alpha_24dp,
|
|
||||||
R.string.title
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.LAST_READ,
|
|
||||||
R.drawable.ic_recent_read_outline_24dp,
|
|
||||||
R.string.last_read
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.LATEST_CHAPTER,
|
|
||||||
R.drawable.ic_new_releases_24dp,
|
|
||||||
R.string.latest_chapter
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.LAST_FETCHED,
|
|
||||||
R.drawable.ic_check_24dp,
|
|
||||||
R.string.last_fetched
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.UNREAD,
|
|
||||||
R.drawable.ic_eye_24dp,
|
|
||||||
R.string.unread
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.TOTAL,
|
|
||||||
R.drawable.ic_sort_by_numeric_24dp,
|
|
||||||
R.string.total_chapters
|
|
||||||
),
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.DATE_ADDED,
|
|
||||||
R.drawable.ic_heart_outline_24dp,
|
|
||||||
R.string.date_added
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if (category.isDynamic) {
|
|
||||||
items.add(
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.DRAG_AND_DROP,
|
|
||||||
R.drawable.ic_label_outline_24dp,
|
|
||||||
R.string.category
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
items.add(
|
|
||||||
MaterialMenuSheet.MenuSheetItem(
|
|
||||||
LibrarySort.DRAG_AND_DROP,
|
|
||||||
R.drawable.ic_swap_vert_24dp,
|
|
||||||
R.string.drag_and_drop
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val sortingMode = category.sortingMode(true)
|
val sortingMode = category.sortingMode(true)
|
||||||
val sheet = MaterialMenuSheet(
|
val sheet = MaterialMenuSheet(
|
||||||
activity,
|
activity,
|
||||||
items,
|
items,
|
||||||
activity.getString(R.string.sort_by),
|
activity.getString(R.string.sort_by),
|
||||||
sortingMode
|
sortingMode?.mainValue
|
||||||
) { sheet, item ->
|
) { sheet, item ->
|
||||||
onCatSortClicked(category, item)
|
onCatSortClicked(category, item)
|
||||||
val nCategory = (adapter.getItem(flexibleAdapterPosition) as? LibraryHeaderItem)?.category
|
val nCategory = (adapter.getItem(flexibleAdapterPosition) as? LibraryHeaderItem)?.category
|
||||||
@ -216,46 +156,62 @@ class LibraryHeaderHolder(val view: View, private val adapter: LibraryCategoryAd
|
|||||||
}
|
}
|
||||||
val isAscending = category.isAscending()
|
val isAscending = category.isAscending()
|
||||||
val drawableRes = getSortRes(sortingMode, isAscending)
|
val drawableRes = getSortRes(sortingMode, isAscending)
|
||||||
sheet.setDrawable(sortingMode ?: -1, drawableRes)
|
sheet.setDrawable(sortingMode?.mainValue ?: -1, drawableRes)
|
||||||
sheet.show()
|
sheet.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSortRes(sortingMode: Int?, isAscending: Boolean): Int = when {
|
private fun getSortRes(
|
||||||
sortingMode == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_check_24dp
|
sortMode: LibrarySort?,
|
||||||
if (sortingMode == LibrarySort.DATE_ADDED ||
|
isAscending: Boolean,
|
||||||
sortingMode == LibrarySort.LATEST_CHAPTER ||
|
@DrawableRes defaultDrawableRes: Int = R.drawable.ic_check_24dp
|
||||||
sortingMode == LibrarySort.LAST_READ ||
|
): Int {
|
||||||
sortingMode == LibrarySort.LAST_FETCHED
|
sortMode ?: return defaultDrawableRes
|
||||||
) !isAscending else isAscending ->
|
return when (sortMode) {
|
||||||
|
LibrarySort.DragAndDrop -> defaultDrawableRes
|
||||||
|
else -> {
|
||||||
|
if (if (sortMode.hasInvertedSort) !isAscending else isAscending) {
|
||||||
R.drawable.ic_arrow_downward_24dp
|
R.drawable.ic_arrow_downward_24dp
|
||||||
else -> R.drawable.ic_arrow_upward_24dp
|
} else {
|
||||||
|
R.drawable.ic_arrow_upward_24dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSortRes(
|
||||||
|
sortingMode: Int?,
|
||||||
|
isAscending: Boolean,
|
||||||
|
@DrawableRes defaultDrawableRes: Int = R.drawable.ic_check_24dp
|
||||||
|
): Int {
|
||||||
|
sortingMode ?: return defaultDrawableRes
|
||||||
|
return when (val sortMode = LibrarySort.valueOf(sortingMode)) {
|
||||||
|
LibrarySort.DragAndDrop -> defaultDrawableRes
|
||||||
|
else -> {
|
||||||
|
if (if (sortMode?.hasInvertedSort == true) !isAscending else isAscending) {
|
||||||
|
R.drawable.ic_arrow_downward_24dp
|
||||||
|
} else {
|
||||||
|
R.drawable.ic_arrow_upward_24dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onCatSortClicked(category: Category, menuId: Int?) {
|
private fun onCatSortClicked(category: Category, menuId: Int?) {
|
||||||
val modType = if (menuId == null) {
|
val modType = if (menuId == null) {
|
||||||
val t = (category.mangaSort?.minus('a') ?: 0) + 1
|
val sortingMode = category.sortingMode() ?: LibrarySort.Title
|
||||||
if (t % 2 != 0) t + 1
|
if (category.isAscending()) {
|
||||||
else t - 1
|
sortingMode.categoryValueDescending
|
||||||
} else {
|
} else {
|
||||||
val order = when (menuId) {
|
sortingMode.categoryValue
|
||||||
LibrarySort.DRAG_AND_DROP -> {
|
|
||||||
adapter.libraryListener.sortCategory(category.id!!, 'D' - 'a' + 1)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
LibrarySort.LAST_FETCHED -> 6
|
} else {
|
||||||
LibrarySort.DATE_ADDED -> 5
|
val sortingMode = LibrarySort.valueOf(menuId) ?: LibrarySort.Title
|
||||||
LibrarySort.TOTAL -> 4
|
if (sortingMode != LibrarySort.DragAndDrop && sortingMode == category.sortingMode()) {
|
||||||
LibrarySort.LAST_READ -> 3
|
|
||||||
LibrarySort.UNREAD -> 2
|
|
||||||
LibrarySort.LATEST_CHAPTER -> 1
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
if (order == category.catSortingMode()) {
|
|
||||||
onCatSortClicked(category, null)
|
onCatSortClicked(category, null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
(2 * order + 1)
|
sortingMode.categoryValue
|
||||||
}
|
}
|
||||||
adapter.libraryListener.sortCategory(category.id!!, modType)
|
adapter.libraryListener.sortCategory(category.id!!, modType)
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ abstract class LibraryHolder(
|
|||||||
abstract fun onSetValues(item: LibraryItem)
|
abstract fun onSetValues(item: LibraryItem)
|
||||||
|
|
||||||
fun setUnreadBadge(badge: LibraryBadge, item: LibraryItem) {
|
fun setUnreadBadge(badge: LibraryBadge, item: LibraryItem) {
|
||||||
val showTotal = item.header.category.sortingMode() == LibrarySort.TOTAL
|
val showTotal = item.header.category.sortingMode() == LibrarySort.TotalChapters
|
||||||
badge.setUnreadDownload(
|
badge.setUnreadDownload(
|
||||||
when {
|
when {
|
||||||
showTotal -> item.manga.totalChapters
|
showTotal -> item.manga.totalChapters
|
||||||
|
@ -359,31 +359,35 @@ class LibraryPresenter(
|
|||||||
}
|
}
|
||||||
val compare = when {
|
val compare = when {
|
||||||
category.mangaSort != null -> {
|
category.mangaSort != null -> {
|
||||||
var sort = when (category.sortingMode()) {
|
var sort = when (category.sortingMode() ?: LibrarySort.Title) {
|
||||||
LibrarySort.ALPHA -> sortAlphabetical(i1, i2)
|
LibrarySort.Title -> sortAlphabetical(i1, i2)
|
||||||
LibrarySort.LATEST_CHAPTER -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
LibrarySort.LatestChapter -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
||||||
LibrarySort.UNREAD -> when {
|
LibrarySort.Unread -> when {
|
||||||
i1.manga.unread == i2.manga.unread -> 0
|
i1.manga.unread == i2.manga.unread -> 0
|
||||||
i1.manga.unread == 0 -> if (category.isAscending()) 1 else -1
|
i1.manga.unread == 0 -> if (category.isAscending()) 1 else -1
|
||||||
i2.manga.unread == 0 -> if (category.isAscending()) -1 else 1
|
i2.manga.unread == 0 -> if (category.isAscending()) -1 else 1
|
||||||
else -> i1.manga.unread.compareTo(i2.manga.unread)
|
else -> i1.manga.unread.compareTo(i2.manga.unread)
|
||||||
}
|
}
|
||||||
LibrarySort.LAST_READ -> {
|
LibrarySort.LastRead -> {
|
||||||
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
val manga1LastRead =
|
||||||
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
||||||
|
val manga2LastRead =
|
||||||
|
lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
||||||
manga1LastRead.compareTo(manga2LastRead)
|
manga1LastRead.compareTo(manga2LastRead)
|
||||||
}
|
}
|
||||||
LibrarySort.TOTAL -> {
|
LibrarySort.TotalChapters -> {
|
||||||
i1.manga.totalChapters.compareTo(i2.manga.totalChapters)
|
i1.manga.totalChapters.compareTo(i2.manga.totalChapters)
|
||||||
}
|
}
|
||||||
LibrarySort.LAST_FETCHED -> {
|
LibrarySort.LastFetched -> {
|
||||||
val manga1LastRead = lastFetchedManga[i1.manga.id!!] ?: lastFetchedManga.size
|
val manga1LastRead =
|
||||||
val manga2LastRead = lastFetchedManga[i2.manga.id!!] ?: lastFetchedManga.size
|
lastFetchedManga[i1.manga.id!!] ?: lastFetchedManga.size
|
||||||
|
val manga2LastRead =
|
||||||
|
lastFetchedManga[i2.manga.id!!] ?: lastFetchedManga.size
|
||||||
manga1LastRead.compareTo(manga2LastRead)
|
manga1LastRead.compareTo(manga2LastRead)
|
||||||
}
|
}
|
||||||
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
LibrarySort.DateAdded -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||||
else -> {
|
LibrarySort.DragAndDrop -> {
|
||||||
if (LibrarySort.DRAG_AND_DROP == category.sortingMode() && category.isDynamic) {
|
if (category.isDynamic) {
|
||||||
val category1 =
|
val category1 =
|
||||||
allCategories.find { i1.manga.category == it.id }?.order
|
allCategories.find { i1.manga.category == it.id }?.order
|
||||||
?: 0
|
?: 0
|
||||||
@ -813,12 +817,12 @@ class LibraryPresenter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Update a category's sorting */
|
/** Update a category's sorting */
|
||||||
fun sortCategory(catId: Int, order: Int) {
|
fun sortCategory(catId: Int, order: Char) {
|
||||||
val category = categories.find { catId == it.id } ?: return
|
val category = categories.find { catId == it.id } ?: return
|
||||||
category.mangaSort = ('a' + (order - 1))
|
category.mangaSort = order
|
||||||
if (catId == -1 || category.isDynamic) {
|
if (catId == -1 || category.isDynamic) {
|
||||||
val sort = category.sortingMode() ?: LibrarySort.ALPHA
|
val sort = category.sortingMode() ?: LibrarySort.Title
|
||||||
preferences.librarySortingMode().set(sort)
|
preferences.librarySortingMode().set(sort.mainValue)
|
||||||
preferences.librarySortingAscending().set(category.isAscending())
|
preferences.librarySortingAscending().set(category.isAscending())
|
||||||
categories.forEach {
|
categories.forEach {
|
||||||
it.mangaSort = category.mangaSort
|
it.mangaSort = category.mangaSort
|
||||||
|
@ -1,13 +1,61 @@
|
|||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
object LibrarySort {
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
||||||
|
|
||||||
const val ALPHA = 0
|
enum class LibrarySort(
|
||||||
const val LAST_READ = 1
|
val mainValue: Int,
|
||||||
const val LATEST_CHAPTER = 2
|
@StringRes private val stringRes: Int,
|
||||||
const val UNREAD = 3
|
@DrawableRes private val iconRes: Int,
|
||||||
const val TOTAL = 4
|
private val catValue: Int = mainValue,
|
||||||
const val DATE_ADDED = 5
|
@StringRes private val dynamicStringRes: Int = stringRes,
|
||||||
const val LAST_FETCHED = 6
|
@DrawableRes private val dynamicIconRes: Int = iconRes
|
||||||
const val DRAG_AND_DROP = 7
|
) {
|
||||||
|
|
||||||
|
Title(0, R.string.title, R.drawable.ic_sort_by_alpha_24dp),
|
||||||
|
LastRead(1, R.string.last_read, R.drawable.ic_recent_read_outline_24dp, 3),
|
||||||
|
LatestChapter(2, R.string.latest_chapter, R.drawable.ic_new_releases_24dp, 1),
|
||||||
|
LastFetched(6, R.string.last_fetched, R.drawable.ic_calendar_text_outline_24dp),
|
||||||
|
Unread(3, R.string.unread, R.drawable.ic_eye_24dp, 2),
|
||||||
|
TotalChapters(4, R.string.total_chapters, R.drawable.ic_sort_by_numeric_24dp),
|
||||||
|
DateAdded(5, R.string.date_added, R.drawable.ic_heart_outline_24dp),
|
||||||
|
DragAndDrop(
|
||||||
|
7,
|
||||||
|
R.string.drag_and_drop,
|
||||||
|
R.drawable.ic_swap_vert_24dp,
|
||||||
|
7,
|
||||||
|
R.string.category,
|
||||||
|
R.drawable.ic_label_outline_24dp
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
val categoryValue: Char
|
||||||
|
get() = if (this == DragAndDrop) 'D' else 'a' + catValue * 2
|
||||||
|
|
||||||
|
val categoryValueDescending: Char
|
||||||
|
get() = if (this == DragAndDrop) 'D' else 'b' + catValue * 2
|
||||||
|
|
||||||
|
@StringRes
|
||||||
|
fun stringRes(isDynamic: Boolean) = if (isDynamic) dynamicStringRes else stringRes
|
||||||
|
|
||||||
|
@DrawableRes
|
||||||
|
fun iconRes(isDynamic: Boolean) = if (isDynamic) dynamicIconRes else iconRes
|
||||||
|
|
||||||
|
val hasInvertedSort: Boolean
|
||||||
|
get() = this in listOf(LastRead, DateAdded, LatestChapter, LastFetched)
|
||||||
|
|
||||||
|
fun menuSheetItem(isDynamic: Boolean): MaterialMenuSheet.MenuSheetItem {
|
||||||
|
return MaterialMenuSheet.MenuSheetItem(
|
||||||
|
mainValue,
|
||||||
|
iconRes(isDynamic),
|
||||||
|
stringRes(isDynamic)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun valueOf(value: Int) = values().find { it.mainValue == value }
|
||||||
|
fun valueOf(char: Char?) = values().find { it.categoryValue == char || it.categoryValueDescending == char }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/calendar_text_outline.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#000" android:pathData="M19,4H18V2H16V4H8V2H6V4H5A2,2 0 0,0 3,6V20A2,2 0 0,0 5,22H19A2,2 0 0,0 21,20V6A2,2 0 0,0 19,4M19,20H5V10H19V20M5,8V6H19V8H5M7,12H17V14H7V12M7,16H14V18H7V16Z" />
|
||||||
|
</vector>
|
Loading…
Reference in New Issue
Block a user