mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-24 13:01:51 +01:00
Optimizations to sorting + category refactoring
Category: • new bool called isDynamic used for all category • new bool called isAlone, for when using no categories or when hiding all categories Sort Optimizing: •Using SQLite query for library mangas to also set the total chapters, instead of checking the total count later •No longer using regex for removing articles from text, because it's pretty heavy •All category now uses the same catergory sorting logic as regular categories
This commit is contained in:
parent
7083d41ffe
commit
d9ad689506
@ -19,14 +19,15 @@ interface Category : Serializable {
|
||||
|
||||
var mangaSort: Char?
|
||||
|
||||
var isFirst: Boolean?
|
||||
var isLast: Boolean?
|
||||
var isAlone: Boolean
|
||||
|
||||
val nameLower: String
|
||||
get() = name.toLowerCase()
|
||||
|
||||
var isHidden: Boolean
|
||||
|
||||
var isDynamic: Boolean
|
||||
|
||||
fun isAscending(): Boolean {
|
||||
return ((mangaSort?.minus('a') ?: 0) % 2) != 1
|
||||
}
|
||||
@ -49,7 +50,7 @@ interface Category : Serializable {
|
||||
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
|
||||
else -> if (id == -1) R.string.category else R.string.drag_and_drop
|
||||
else -> if (isDynamic) R.string.category else R.string.drag_and_drop
|
||||
}
|
||||
|
||||
fun catSortingMode(): Int? = when (mangaSort) {
|
||||
@ -96,12 +97,10 @@ interface Category : Serializable {
|
||||
fun createDefault(context: Context): Category =
|
||||
create(context.getString(R.string.default_value)).apply {
|
||||
id = 0
|
||||
isFirst = true
|
||||
}
|
||||
|
||||
fun createAll(context: Context, libSort: Int, ascending: Boolean): Category =
|
||||
create(context.getString(R.string.all)).apply {
|
||||
id = -1
|
||||
fun createCustom(name: String, libSort: Int, ascending: Boolean): Category =
|
||||
create(name).apply {
|
||||
mangaSort = when (libSort) {
|
||||
LibrarySort.ALPHA -> ALPHA_ASC
|
||||
LibrarySort.LATEST_CHAPTER -> UPDATED_ASC
|
||||
@ -113,11 +112,15 @@ interface Category : Serializable {
|
||||
else -> DRAG_AND_DROP
|
||||
}
|
||||
if (mangaSort != DRAG_AND_DROP && !ascending) {
|
||||
mangaSort?.plus(1)
|
||||
mangaSort = mangaSort?.plus(1)
|
||||
}
|
||||
isDynamic = true
|
||||
}
|
||||
|
||||
fun createAll(context: Context, libSort: Int, ascending: Boolean): Category =
|
||||
createCustom(context.getString(R.string.all), libSort, ascending).apply {
|
||||
id = -1
|
||||
order = -1
|
||||
isFirst = true
|
||||
isLast = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ class CategoryImpl : Category {
|
||||
|
||||
override var mangaSort: Char? = null
|
||||
|
||||
override var isFirst: Boolean? = null
|
||||
|
||||
override var isLast: Boolean? = null
|
||||
override var isAlone: Boolean = false
|
||||
|
||||
override var isHidden: Boolean = false
|
||||
|
||||
override var isDynamic: Boolean = false
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
@ -3,10 +3,15 @@ package eu.kanade.tachiyomi.data.database.models
|
||||
class LibraryManga : MangaImpl() {
|
||||
|
||||
var unread: Int = 0
|
||||
var read: Int = 0
|
||||
|
||||
var category: Int = 0
|
||||
|
||||
var hasRead: Boolean = false
|
||||
val totalChapters
|
||||
get() = read + unread
|
||||
|
||||
val hasRead
|
||||
get() = read > 0
|
||||
|
||||
companion object {
|
||||
fun createBlank(categoryId: Int): LibraryManga = LibraryManga().apply {
|
||||
|
@ -18,7 +18,7 @@ class LibraryMangaGetResolver : DefaultGetResolver<LibraryManga>(), BaseMangaGet
|
||||
mapBaseFromCursor(manga, cursor)
|
||||
manga.unread = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_UNREAD))
|
||||
manga.category = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_CATEGORY))
|
||||
manga.hasRead = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_HAS_READ)) > 0
|
||||
manga.read = cursor.getInt(cursor.getColumnIndex(MangaTable.COL_HAS_READ))
|
||||
|
||||
return manga
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ class LibraryCategoryAdapter(val controller: LibraryController) :
|
||||
else recyclerView.context.getString(R.string.read)
|
||||
}
|
||||
LibrarySort.TOTAL -> {
|
||||
val total = item.chapterCount
|
||||
val total = item.manga.totalChapters
|
||||
if (total > 0) recyclerView.resources.getQuantityString(
|
||||
R.plurals.chapters, total, total
|
||||
)
|
||||
|
@ -1109,8 +1109,9 @@ class LibraryController(
|
||||
|
||||
override fun manageCategory(position: Int) {
|
||||
val category = (adapter.getItem(position) as? LibraryHeaderItem)?.category ?: return
|
||||
if (category.id ?: 0 > -1)
|
||||
if (!category.isDynamic) {
|
||||
ManageCategoryDialog(this, category).showDialog(router)
|
||||
}
|
||||
}
|
||||
|
||||
override fun sortCategory(catId: Int, sortBy: Int) {
|
||||
|
@ -143,7 +143,7 @@ class LibraryHeaderItem(
|
||||
}
|
||||
val category = item.category
|
||||
|
||||
if (category.isFirst == true && category.isLast == true) sectionText.text = ""
|
||||
if (category.isAlone) sectionText.text = ""
|
||||
else sectionText.text = category.name
|
||||
sortText.text = itemView.context.getString(
|
||||
R.string.sort_by_, itemView.context.getString(category.sortRes())
|
||||
@ -165,14 +165,15 @@ class LibraryHeaderItem(
|
||||
when {
|
||||
adapter.mode == SelectableAdapter.Mode.MULTI -> {
|
||||
checkboxImage.visibleIf(!category.isHidden)
|
||||
expandImage.visibleIf(category.isHidden && !adapter.isSingleCategory)
|
||||
expandImage.visibleIf(category.isHidden && !adapter.isSingleCategory && !category.isDynamic)
|
||||
updateButton.gone()
|
||||
catProgress.gone()
|
||||
setSelection()
|
||||
}
|
||||
category.id == -1 -> {
|
||||
category.isDynamic -> {
|
||||
expandImage.gone()
|
||||
checkboxImage.gone()
|
||||
catProgress.gone()
|
||||
updateButton.gone()
|
||||
}
|
||||
LibraryUpdateService.categoryInQueue(category.id) -> {
|
||||
@ -185,7 +186,7 @@ class LibraryHeaderItem(
|
||||
expandImage.visibleIf(!adapter.isSingleCategory)
|
||||
catProgress.gone()
|
||||
checkboxImage.gone()
|
||||
updateButton.visibleIf(category.id ?: 0 > -1 && !adapter.isSingleCategory)
|
||||
updateButton.visibleIf(!adapter.isSingleCategory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,10 @@ abstract class LibraryHolder(
|
||||
abstract fun onSetValues(item: LibraryItem)
|
||||
|
||||
fun setUnreadBadge(badge: LibraryBadge, item: LibraryItem) {
|
||||
val showTotal = item.header.category.sortingMode() == LibrarySort.TOTAL
|
||||
badge.setUnreadDownload(
|
||||
when {
|
||||
item.chapterCount > -1 -> item.chapterCount
|
||||
showTotal -> item.manga.totalChapters
|
||||
item.unreadType == 2 -> item.manga.unread
|
||||
item.unreadType == 1 -> if (item.manga.unread > 0) -1 else -2
|
||||
else -> -2
|
||||
@ -38,7 +39,7 @@ abstract class LibraryHolder(
|
||||
item.manga.source == LocalSource.ID -> -2
|
||||
else -> item.downloadCount
|
||||
},
|
||||
item.chapterCount > -1)
|
||||
showTotal)
|
||||
}
|
||||
|
||||
fun setReadingButton(item: LibraryItem) {
|
||||
|
@ -35,7 +35,6 @@ class LibraryItem(
|
||||
|
||||
var downloadCount = -1
|
||||
var unreadType = 2
|
||||
var chapterCount = -1
|
||||
|
||||
private val uniformSize: Boolean
|
||||
get() = preferences.uniformGrid().getOrDefault()
|
||||
|
@ -54,6 +54,10 @@ class LibraryPresenter(
|
||||
var categories: List<Category> = emptyList()
|
||||
private set
|
||||
|
||||
var hashCategories: HashMap<Int, Category> = hashMapOf()
|
||||
|
||||
var removeArticles: Boolean = preferences.removeArticles().getOrDefault()
|
||||
|
||||
/** All categories of the library, in case they are hidden because of hide categories is on */
|
||||
var allCategories: List<Category> = emptyList()
|
||||
private set
|
||||
@ -67,8 +71,6 @@ class LibraryPresenter(
|
||||
val showAllCategories
|
||||
get() = preferences.showAllCategories().get()
|
||||
|
||||
private var totalChapters: Map<Long, Int>? = null
|
||||
|
||||
/** Save the current list to speed up loading later */
|
||||
fun onDestroy() {
|
||||
lastLibraryItems = libraryItems
|
||||
@ -86,7 +88,6 @@ class LibraryPresenter(
|
||||
/** Get favorited manga for library and sort and filter it */
|
||||
fun getLibrary() {
|
||||
scope.launch {
|
||||
totalChapters = null
|
||||
val library = withContext(Dispatchers.IO) { getLibraryFromDB() }
|
||||
library.apply {
|
||||
setDownloadCount(library)
|
||||
@ -98,9 +99,6 @@ class LibraryPresenter(
|
||||
mangaMap = applySort(mangaMap)
|
||||
val freshStart = libraryItems.isEmpty()
|
||||
sectionLibrary(mangaMap, freshStart)
|
||||
withContext(Dispatchers.IO) {
|
||||
setTotalChapters()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,74 +311,81 @@ class LibraryPresenter(
|
||||
* @param itemList the map to sort.
|
||||
*/
|
||||
private fun applySort(itemList: List<LibraryItem>): List<LibraryItem> {
|
||||
val sortingMode = preferences.librarySortingMode().getOrDefault()
|
||||
|
||||
val lastReadManga by lazy {
|
||||
var counter = 0
|
||||
db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ }
|
||||
}
|
||||
|
||||
val ascending = preferences.librarySortingAscending().getOrDefault()
|
||||
val useDnD = !preferences.hideCategories().getOrDefault()
|
||||
|
||||
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
|
||||
if (!(sortingMode == LibrarySort.DRAG_AND_DROP || useDnD)) {
|
||||
i1.chapterCount = -1
|
||||
i2.chapterCount = -1
|
||||
}
|
||||
val compare = when {
|
||||
sortingMode == LibrarySort.DRAG_AND_DROP || useDnD ->
|
||||
sortCategory(i1, i2, lastReadManga)
|
||||
sortingMode == LibrarySort.ALPHA -> sortAlphabetical(i1, i2)
|
||||
sortingMode == LibrarySort.LAST_READ -> {
|
||||
// Get index of manga, set equal to list if size unknown.
|
||||
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
||||
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
||||
manga1LastRead.compareTo(manga2LastRead)
|
||||
if (i1.header.category.id == i2.header.category.id) {
|
||||
val category = i1.header.category
|
||||
if (category.mangaOrder.isNullOrEmpty() && category.mangaSort == null) {
|
||||
category.changeSortTo(preferences.librarySortingMode().getOrDefault())
|
||||
if (category.id == 0) preferences.defaultMangaOrder()
|
||||
.set(category.mangaSort.toString())
|
||||
else if (!category.isDynamic) db.insertCategory(category).executeAsBlocking()
|
||||
}
|
||||
sortingMode == LibrarySort.LATEST_CHAPTER -> i2.manga.last_update.compareTo(i1
|
||||
.manga.last_update)
|
||||
sortingMode == LibrarySort.UNREAD ->
|
||||
when {
|
||||
i1.manga.unread == i2.manga.unread -> 0
|
||||
i1.manga.unread == 0 -> if (ascending) 1 else -1
|
||||
i2.manga.unread == 0 -> if (ascending) -1 else 1
|
||||
else -> i1.manga.unread.compareTo(i2.manga.unread)
|
||||
val compare = when {
|
||||
category.mangaSort != null -> {
|
||||
var sort = when (category.sortingMode()) {
|
||||
LibrarySort.ALPHA -> sortAlphabetical(i1, i2)
|
||||
LibrarySort.LATEST_CHAPTER -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
||||
LibrarySort.UNREAD -> when {
|
||||
i1.manga.unread == i2.manga.unread -> 0
|
||||
i1.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)
|
||||
}
|
||||
LibrarySort.LAST_READ -> {
|
||||
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
||||
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
||||
manga1LastRead.compareTo(manga2LastRead)
|
||||
}
|
||||
LibrarySort.TOTAL -> {
|
||||
i1.manga.totalChapters.compareTo(i2.manga.totalChapters)
|
||||
}
|
||||
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||
else -> {
|
||||
if (LibrarySort.DRAG_AND_DROP == category.sortingMode() && category.isDynamic) {
|
||||
val category1 =
|
||||
allCategories.find { i1.manga.category == it.id }?.order
|
||||
?: 0
|
||||
val category2 =
|
||||
allCategories.find { i2.manga.category == it.id }?.order
|
||||
?: 0
|
||||
category1.compareTo(category2)
|
||||
} else {
|
||||
sortAlphabetical(i1, i2)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!category.isAscending()) sort *= -1
|
||||
sort
|
||||
}
|
||||
sortingMode == LibrarySort.TOTAL -> {
|
||||
setTotalChapters()
|
||||
val manga1TotalChapter = totalChapters!![i1.manga.id!!] ?: 0
|
||||
val mange2TotalChapter = totalChapters!![i2.manga.id!!] ?: 0
|
||||
i1.chapterCount = totalChapters!![i1.manga.id!!] ?: 0
|
||||
i2.chapterCount = totalChapters!![i2.manga.id!!] ?: 0
|
||||
manga1TotalChapter.compareTo(mange2TotalChapter)
|
||||
category.mangaOrder.isNotEmpty() -> {
|
||||
val order = category.mangaOrder
|
||||
val index1 = order.indexOf(i1.manga.id!!)
|
||||
val index2 = order.indexOf(i2.manga.id!!)
|
||||
when {
|
||||
index1 == index2 -> 0
|
||||
index1 == -1 -> -1
|
||||
index2 == -1 -> 1
|
||||
else -> index1.compareTo(index2)
|
||||
}
|
||||
}
|
||||
else -> 0
|
||||
}
|
||||
sortingMode == LibrarySort.DATE_ADDED -> {
|
||||
i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||
}
|
||||
else -> 0
|
||||
if (compare == 0) {
|
||||
sortAlphabetical(i1, i2)
|
||||
} else compare
|
||||
} else {
|
||||
val category = i1.header.category.order
|
||||
val category2 = i2.header.category.order
|
||||
category.compareTo(category2)
|
||||
}
|
||||
if (!(sortingMode == LibrarySort.DRAG_AND_DROP || useDnD) && compare == 0) {
|
||||
if (ascending) sortAlphabetical(i1, i2)
|
||||
else sortAlphabetical(i2, i1)
|
||||
} else compare
|
||||
}
|
||||
|
||||
val comparator = if (ascending || useDnD)
|
||||
Comparator(sortFn)
|
||||
else
|
||||
Collections.reverseOrder(sortFn)
|
||||
|
||||
return itemList.sortedWith(comparator)
|
||||
}
|
||||
|
||||
/** Set the total chapters for the manga in the library */
|
||||
private fun setTotalChapters() {
|
||||
if (totalChapters != null) return
|
||||
val mangaMap = allLibraryItems
|
||||
totalChapters = mangaMap.map {
|
||||
it.manga.id!! to db.getChapters(it.manga).executeAsBlocking().size
|
||||
}.toMap()
|
||||
return itemList.sortedWith(Comparator(sortFn))
|
||||
}
|
||||
|
||||
/** Gets the category by id
|
||||
@ -388,89 +393,11 @@ class LibraryPresenter(
|
||||
* @param categoryId id of the categoty to get
|
||||
*/
|
||||
private fun getCategory(categoryId: Int): Category {
|
||||
val category = categories.find { it.id == categoryId } ?: createDefaultCategory()
|
||||
if (category.isFirst == null) {
|
||||
category.isFirst = categories.minBy { it.order }?.id == category.id
|
||||
}
|
||||
if (category.isLast == null) category.isLast = categories.lastOrNull()?.id == category.id
|
||||
val category = hashCategories[categoryId] ?: createDefaultCategory()
|
||||
category.isAlone = categories.size <= 1
|
||||
return category
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort 2 manga by the category's sorting
|
||||
*
|
||||
* @param i1 the first manga
|
||||
* @param i2 the second manga to compare
|
||||
* @param lastReadManga map of the last read of the library
|
||||
*/
|
||||
private fun sortCategory(
|
||||
i1: LibraryItem,
|
||||
i2: LibraryItem,
|
||||
lastReadManga: Map<Long, Int>
|
||||
): Int {
|
||||
return if (i1.header.category.id == i2.header.category.id) {
|
||||
val category = i1.header.category
|
||||
if (category.mangaOrder.isNullOrEmpty() && category.mangaSort == null) {
|
||||
category.changeSortTo(preferences.librarySortingMode().getOrDefault())
|
||||
if (category.id == 0) preferences.defaultMangaOrder()
|
||||
.set(category.mangaSort.toString())
|
||||
else if (category.id ?: 0 > 0) db.insertCategory(category).executeAsBlocking()
|
||||
}
|
||||
i1.chapterCount = -1
|
||||
i2.chapterCount = -1
|
||||
val compare = when {
|
||||
category.mangaSort != null -> {
|
||||
var sort = when (category.sortingMode()) {
|
||||
LibrarySort.ALPHA -> sortAlphabetical(i1, i2)
|
||||
LibrarySort.LATEST_CHAPTER -> i2.manga.last_update.compareTo(i1.manga.last_update)
|
||||
LibrarySort.UNREAD -> when {
|
||||
i1.manga.unread == i2.manga.unread -> 0
|
||||
i1.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)
|
||||
}
|
||||
LibrarySort.LAST_READ -> {
|
||||
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
|
||||
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
|
||||
manga1LastRead.compareTo(manga2LastRead)
|
||||
}
|
||||
LibrarySort.TOTAL -> {
|
||||
setTotalChapters()
|
||||
val manga1TotalChapter = totalChapters!![i1.manga.id!!] ?: 0
|
||||
val mange2TotalChapter = totalChapters!![i2.manga.id!!] ?: 0
|
||||
i1.chapterCount = totalChapters!![i1.manga.id!!] ?: 0
|
||||
i2.chapterCount = totalChapters!![i2.manga.id!!] ?: 0
|
||||
manga1TotalChapter.compareTo(mange2TotalChapter)
|
||||
}
|
||||
LibrarySort.DATE_ADDED -> i2.manga.date_added.compareTo(i1.manga.date_added)
|
||||
else -> sortAlphabetical(i1, i2)
|
||||
}
|
||||
if (!category.isAscending()) sort *= -1
|
||||
sort
|
||||
}
|
||||
category.mangaOrder.isNotEmpty() -> {
|
||||
val order = category.mangaOrder
|
||||
val index1 = order.indexOf(i1.manga.id!!)
|
||||
val index2 = order.indexOf(i2.manga.id!!)
|
||||
when {
|
||||
index1 == index2 -> 0
|
||||
index1 == -1 -> -1
|
||||
index2 == -1 -> 1
|
||||
else -> index1.compareTo(index2)
|
||||
}
|
||||
}
|
||||
else -> 0
|
||||
}
|
||||
if (compare == 0) {
|
||||
sortAlphabetical(i1, i2)
|
||||
} else compare
|
||||
} else {
|
||||
val category = i1.header.category.order
|
||||
val category2 = i2.header.category.order
|
||||
category.compareTo(category2)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort 2 manga by the their title (and remove articles if need be)
|
||||
*
|
||||
@ -478,9 +405,11 @@ class LibraryPresenter(
|
||||
* @param i2 the second manga to compare
|
||||
*/
|
||||
private fun sortAlphabetical(i1: LibraryItem, i2: LibraryItem): Int {
|
||||
return if (preferences.removeArticles().getOrDefault())
|
||||
return if (removeArticles) {
|
||||
i1.manga.title.removeArticles().compareTo(i2.manga.title.removeArticles(), true)
|
||||
else i1.manga.title.compareTo(i2.manga.title, true)
|
||||
} else {
|
||||
i1.manga.title.compareTo(i2.manga.title, true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,6 +418,7 @@ class LibraryPresenter(
|
||||
* @return an list of all the manga in a itemized form.
|
||||
*/
|
||||
private fun getLibraryFromDB(): List<LibraryItem> {
|
||||
removeArticles = preferences.removeArticles().getOrDefault()
|
||||
val categories = db.getCategories().executeAsBlocking().toMutableList()
|
||||
val showCategories = !preferences.hideCategories().getOrDefault()
|
||||
var libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||
@ -550,6 +480,10 @@ class LibraryPresenter(
|
||||
this.categories = if (!showCategories) arrayListOf(categoryAll)
|
||||
else categories
|
||||
|
||||
hashCategories = HashMap(this.categories.mapNotNull {
|
||||
it.id!! to it
|
||||
}.toMap())
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
@ -694,7 +628,7 @@ class LibraryPresenter(
|
||||
fun sortCategory(catId: Int, order: Int) {
|
||||
val category = categories.find { catId == it.id } ?: return
|
||||
category.mangaSort = ('a' + (order - 1))
|
||||
if (catId == -1) {
|
||||
if (catId == -1 || category.isDynamic) {
|
||||
val sort = category.sortingMode() ?: LibrarySort.ALPHA
|
||||
preferences.librarySortingMode().set(sort)
|
||||
preferences.librarySortingAscending().set(category.isAscending())
|
||||
@ -709,6 +643,7 @@ class LibraryPresenter(
|
||||
fun rearrangeCategory(catId: Int?, mangaIds: List<Long>) {
|
||||
scope.launch {
|
||||
val category = categories.find { catId == it.id } ?: return@launch
|
||||
if (category.isDynamic) return@launch
|
||||
category.mangaSort = null
|
||||
category.mangaOrder = mangaIds
|
||||
if (category.id == 0) preferences.defaultMangaOrder().set(mangaIds.joinToString("/"))
|
||||
@ -726,6 +661,7 @@ class LibraryPresenter(
|
||||
scope.launch {
|
||||
val categoryId = catId ?: return@launch
|
||||
val category = categories.find { catId == it.id } ?: return@launch
|
||||
if (category.isDynamic) return@launch
|
||||
|
||||
val oldCatId = manga.category
|
||||
manga.category = categoryId
|
||||
@ -762,7 +698,7 @@ class LibraryPresenter(
|
||||
}
|
||||
|
||||
fun toggleCategoryVisibility(categoryId: Int) {
|
||||
if (categoryId <= -1) return
|
||||
if (categoryId <= -1 || categories.find { it.id == categoryId }?.isDynamic == true) return
|
||||
val categoriesHidden = preferences.collapsedCategories().getOrDefault().mapNotNull {
|
||||
it.toIntOrNull()
|
||||
}.toMutableSet()
|
||||
|
@ -14,7 +14,12 @@ fun String.chop(count: Int, replacement: String = "..."): String {
|
||||
}
|
||||
|
||||
fun String.removeArticles(): String {
|
||||
return this.replace(Regex("^(an|a|the) ", RegexOption.IGNORE_CASE), "")
|
||||
return when {
|
||||
startsWith("a ", true) -> substring(2)
|
||||
startsWith("an ", true) -> substring(3)
|
||||
startsWith("the ", true) -> substring(4)
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user