feat: Random sort

This commit is contained in:
Ahmad Ansori Palembani 2025-01-05 19:18:08 +07:00
parent eebc3dc822
commit 7fc95e3029
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
8 changed files with 68 additions and 33 deletions

View file

@ -10,6 +10,9 @@ The format is simplified version of [Keep a Changelog](https://keepachangelog.co
## [Unreleased]
### Additions
- Add random library sort
### Fixes
- Allow users to bypass onboarding's permission step if Shizuku is installed
- Fix Recents page shows "No recent chapters" instead of a loading screen

View file

@ -32,14 +32,17 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.view.compatToolTipText
import eu.kanade.tachiyomi.util.view.setText
import eu.kanade.tachiyomi.util.view.text
import kotlin.random.Random
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import yokai.domain.library.LibraryPreferences
import yokai.i18n.MR
import yokai.util.lang.getString
class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
BaseFlexibleViewHolder(view, adapter, true) {
private val libraryPreferences: LibraryPreferences = Injekt.get()
private val binding = LibraryCategoryHeaderItemBinding.bind(view)
val progressDrawableStart = CircularProgressDrawable(itemView.context)
val progressDrawableEnd = CircularProgressDrawable(itemView.context)
@ -292,6 +295,7 @@ class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
sortMode ?: return defaultDrawableRes
return when (sortMode) {
LibrarySort.DragAndDrop -> defaultDrawableRes
LibrarySort.Random -> R.drawable.ic_shuffle_24dp
else -> {
if (if (sortMode.hasInvertedSort) !isAscending else isAscending) {
R.drawable.ic_arrow_downward_24dp
@ -306,35 +310,27 @@ class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
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
}
}
}
}
): Int = getSortRes(sortingMode?.let { LibrarySort.valueOf(it) }, isAscending, defaultDrawableRes)
private fun onCatSortClicked(category: Category, menuId: Int?) {
val modType = if (menuId == null) {
val (mode, modType) = if (menuId == null) {
val sortingMode = category.sortingMode() ?: LibrarySort.Title
if (category.isAscending()) {
sortingMode.categoryValueDescending
} else {
sortingMode.categoryValue
}
sortingMode to
if (sortingMode != LibrarySort.Random && category.isAscending()) {
sortingMode.categoryValueDescending
} else {
sortingMode.categoryValue
}
} else {
val sortingMode = LibrarySort.valueOf(menuId) ?: LibrarySort.Title
if (sortingMode != LibrarySort.DragAndDrop && sortingMode == category.sortingMode()) {
onCatSortClicked(category, null)
return
}
sortingMode.categoryValue
sortingMode to sortingMode.categoryValue
}
if (mode == LibrarySort.Random) {
libraryPreferences.randomSortSeed().set(Random.nextInt())
}
adapter.libraryListener?.sortCategory(category.id!!, modType)
}

View file

@ -73,6 +73,7 @@ import yokai.domain.chapter.interactor.GetChapter
import yokai.domain.chapter.interactor.UpdateChapter
import yokai.domain.chapter.models.ChapterUpdate
import yokai.domain.history.interactor.GetHistory
import yokai.domain.library.LibraryPreferences
import yokai.domain.manga.interactor.GetLibraryManga
import yokai.domain.manga.interactor.GetManga
import yokai.domain.manga.interactor.UpdateManga
@ -90,6 +91,7 @@ typealias LibraryMutableMap = MutableMap<Category, List<LibraryItem>>
*/
class LibraryPresenter(
private val preferences: PreferencesHelper = Injekt.get(),
private val libraryPreferences: LibraryPreferences = Injekt.get(),
private val coverCache: CoverCache = Injekt.get(),
val sourceManager: SourceManager = Injekt.get(),
private val downloadCache: DownloadCache = Injekt.get(),
@ -697,6 +699,9 @@ class LibraryPresenter(
sortAlphabetical(i1, i2)
}
}
LibrarySort.Random -> {
error("You're not supposed to be here...")
}
}
if (!category.isAscending()) sort *= -1
sort
@ -738,16 +743,28 @@ class LibraryPresenter(
}
}
if (LibrarySort.valueOf(category.mangaSort) == LibrarySort.Random) {
return@mapValues values
.asSequence()
.shuffled(Random(libraryPreferences.randomSortSeed().get()))
.sortedWith { i1, i2 ->
when {
i1 is LibraryPlaceholderItem -> -1
i2 is LibraryPlaceholderItem -> 1
else -> 0
}
}
.toList()
}
values.sortedWith(Comparator(sortFn))
}.toSortedMap { category, category2 ->
// Force default category to always be at the top. This also for some reason fixed a bug where Default
// category would disappear whenever a new category is added.
if (category.id == 0) {
-1
} else if (category2.id == 0) {
1
} else {
category.order.compareTo(category2.order)
when {
// Force default category to always be at the top. This also for some reason fixed a bug where Default
// category would disappear whenever a new category is added.
category.id == 0 -> -1
category2.id == 0 -> 1
else -> category.order.compareTo(category2.order)
}
}
}

View file

@ -1,13 +1,10 @@
package eu.kanade.tachiyomi.ui.library
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.R
import yokai.i18n.MR
import yokai.util.lang.getString
import dev.icerock.moko.resources.compose.stringResource
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
import yokai.i18n.MR
enum class LibrarySort(
val mainValue: Int,
@ -33,7 +30,11 @@ enum class LibrarySort(
MR.strings.category,
R.drawable.ic_label_outline_24dp,
),
Random(
8,
MR.strings.random,
R.drawable.ic_shuffle_24dp,
)
;
val categoryValue: Char
@ -50,6 +51,7 @@ enum class LibrarySort(
LatestChapter -> "LATEST_CHAPTER"
DateFetched -> "CHAPTER_FETCH_DATE"
DateAdded -> "DATE_ADDED"
Random -> "RANDOM"
else -> "ALPHABETICAL"
}
return "$type,ASCENDING"
@ -85,6 +87,7 @@ enum class LibrarySort(
"LATEST_CHAPTER" -> LatestChapter
"CHAPTER_FETCH_DATE" -> DateFetched
"DATE_ADDED" -> DateAdded
"RANDOM" -> Random
else -> Title
}
} catch (e: Exception) {

View file

@ -13,6 +13,7 @@ import org.koin.dsl.module
import yokai.domain.backup.BackupPreferences
import yokai.domain.base.BasePreferences
import yokai.domain.download.DownloadPreferences
import yokai.domain.library.LibraryPreferences
import yokai.domain.recents.RecentsPreferences
import yokai.domain.source.SourcePreferences
import yokai.domain.storage.StoragePreferences
@ -47,6 +48,8 @@ fun preferenceModule(application: Application) = module {
single { BackupPreferences(get()) }
single { LibraryPreferences(get()) }
single {
PreferencesHelper(
context = application,

View file

@ -0,0 +1,7 @@
package yokai.domain.library
import eu.kanade.tachiyomi.core.preference.PreferenceStore
class LibraryPreferences(private val preferenceStore: PreferenceStore) {
fun randomSortSeed() = preferenceStore.getInt("library_random_sort_seed", 0)
}

View file

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M10.59,9.17L5.41,4 4,5.41l5.17,5.17 1.42,-1.41zM14.5,4l2.04,2.04L4,18.59 5.41,20 17.96,7.46 20,9.5L20,4h-5.5zM14.83,13.41l-1.41,1.41 3.13,3.13L14.5,20L20,20v-5.5l-2.04,2.04 -3.13,-3.13z"/>
</vector>

View file

@ -174,6 +174,7 @@
<string name="date_fetched">Date fetched</string>
<string name="latest_chapter">Latest chapter</string>
<string name="drag_and_drop">Drag &amp; Drop</string>
<string name="random">Random</string>
<!-- Library Display -->
<string name="display_options">Display options</string>