mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
feat: Random sort
This commit is contained in:
parent
eebc3dc822
commit
7fc95e3029
8 changed files with 68 additions and 33 deletions
|
@ -10,6 +10,9 @@ The format is simplified version of [Keep a Changelog](https://keepachangelog.co
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Additions
|
||||||
|
- Add random library sort
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Allow users to bypass onboarding's permission step if Shizuku is installed
|
- Allow users to bypass onboarding's permission step if Shizuku is installed
|
||||||
- Fix Recents page shows "No recent chapters" instead of a loading screen
|
- Fix Recents page shows "No recent chapters" instead of a loading screen
|
||||||
|
|
|
@ -32,14 +32,17 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.view.compatToolTipText
|
import eu.kanade.tachiyomi.util.view.compatToolTipText
|
||||||
import eu.kanade.tachiyomi.util.view.setText
|
import eu.kanade.tachiyomi.util.view.setText
|
||||||
import eu.kanade.tachiyomi.util.view.text
|
import eu.kanade.tachiyomi.util.view.text
|
||||||
|
import kotlin.random.Random
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
import yokai.domain.library.LibraryPreferences
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
import yokai.util.lang.getString
|
import yokai.util.lang.getString
|
||||||
|
|
||||||
class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
|
class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
|
||||||
BaseFlexibleViewHolder(view, adapter, true) {
|
BaseFlexibleViewHolder(view, adapter, true) {
|
||||||
|
|
||||||
|
private val libraryPreferences: LibraryPreferences = Injekt.get()
|
||||||
private val binding = LibraryCategoryHeaderItemBinding.bind(view)
|
private val binding = LibraryCategoryHeaderItemBinding.bind(view)
|
||||||
val progressDrawableStart = CircularProgressDrawable(itemView.context)
|
val progressDrawableStart = CircularProgressDrawable(itemView.context)
|
||||||
val progressDrawableEnd = CircularProgressDrawable(itemView.context)
|
val progressDrawableEnd = CircularProgressDrawable(itemView.context)
|
||||||
|
@ -292,6 +295,7 @@ class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
|
||||||
sortMode ?: return defaultDrawableRes
|
sortMode ?: return defaultDrawableRes
|
||||||
return when (sortMode) {
|
return when (sortMode) {
|
||||||
LibrarySort.DragAndDrop -> defaultDrawableRes
|
LibrarySort.DragAndDrop -> defaultDrawableRes
|
||||||
|
LibrarySort.Random -> R.drawable.ic_shuffle_24dp
|
||||||
else -> {
|
else -> {
|
||||||
if (if (sortMode.hasInvertedSort) !isAscending else isAscending) {
|
if (if (sortMode.hasInvertedSort) !isAscending else isAscending) {
|
||||||
R.drawable.ic_arrow_downward_24dp
|
R.drawable.ic_arrow_downward_24dp
|
||||||
|
@ -306,35 +310,27 @@ class LibraryHeaderHolder(val view: View, val adapter: LibraryCategoryAdapter) :
|
||||||
sortingMode: Int?,
|
sortingMode: Int?,
|
||||||
isAscending: Boolean,
|
isAscending: Boolean,
|
||||||
@DrawableRes defaultDrawableRes: Int = R.drawable.ic_check_24dp,
|
@DrawableRes defaultDrawableRes: Int = R.drawable.ic_check_24dp,
|
||||||
): Int {
|
): Int = getSortRes(sortingMode?.let { LibrarySort.valueOf(it) }, isAscending, defaultDrawableRes)
|
||||||
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 (mode, modType) = if (menuId == null) {
|
||||||
val sortingMode = category.sortingMode() ?: LibrarySort.Title
|
val sortingMode = category.sortingMode() ?: LibrarySort.Title
|
||||||
if (category.isAscending()) {
|
sortingMode to
|
||||||
sortingMode.categoryValueDescending
|
if (sortingMode != LibrarySort.Random && category.isAscending()) {
|
||||||
} else {
|
sortingMode.categoryValueDescending
|
||||||
sortingMode.categoryValue
|
} else {
|
||||||
}
|
sortingMode.categoryValue
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val sortingMode = LibrarySort.valueOf(menuId) ?: LibrarySort.Title
|
val sortingMode = LibrarySort.valueOf(menuId) ?: LibrarySort.Title
|
||||||
if (sortingMode != LibrarySort.DragAndDrop && sortingMode == category.sortingMode()) {
|
if (sortingMode != LibrarySort.DragAndDrop && sortingMode == category.sortingMode()) {
|
||||||
onCatSortClicked(category, null)
|
onCatSortClicked(category, null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sortingMode.categoryValue
|
sortingMode to sortingMode.categoryValue
|
||||||
|
}
|
||||||
|
if (mode == LibrarySort.Random) {
|
||||||
|
libraryPreferences.randomSortSeed().set(Random.nextInt())
|
||||||
}
|
}
|
||||||
adapter.libraryListener?.sortCategory(category.id!!, modType)
|
adapter.libraryListener?.sortCategory(category.id!!, modType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ import yokai.domain.chapter.interactor.GetChapter
|
||||||
import yokai.domain.chapter.interactor.UpdateChapter
|
import yokai.domain.chapter.interactor.UpdateChapter
|
||||||
import yokai.domain.chapter.models.ChapterUpdate
|
import yokai.domain.chapter.models.ChapterUpdate
|
||||||
import yokai.domain.history.interactor.GetHistory
|
import yokai.domain.history.interactor.GetHistory
|
||||||
|
import yokai.domain.library.LibraryPreferences
|
||||||
import yokai.domain.manga.interactor.GetLibraryManga
|
import yokai.domain.manga.interactor.GetLibraryManga
|
||||||
import yokai.domain.manga.interactor.GetManga
|
import yokai.domain.manga.interactor.GetManga
|
||||||
import yokai.domain.manga.interactor.UpdateManga
|
import yokai.domain.manga.interactor.UpdateManga
|
||||||
|
@ -90,6 +91,7 @@ typealias LibraryMutableMap = MutableMap<Category, List<LibraryItem>>
|
||||||
*/
|
*/
|
||||||
class LibraryPresenter(
|
class LibraryPresenter(
|
||||||
private val preferences: PreferencesHelper = Injekt.get(),
|
private val preferences: PreferencesHelper = Injekt.get(),
|
||||||
|
private val libraryPreferences: LibraryPreferences = Injekt.get(),
|
||||||
private val coverCache: CoverCache = Injekt.get(),
|
private val coverCache: CoverCache = Injekt.get(),
|
||||||
val sourceManager: SourceManager = Injekt.get(),
|
val sourceManager: SourceManager = Injekt.get(),
|
||||||
private val downloadCache: DownloadCache = Injekt.get(),
|
private val downloadCache: DownloadCache = Injekt.get(),
|
||||||
|
@ -697,6 +699,9 @@ class LibraryPresenter(
|
||||||
sortAlphabetical(i1, i2)
|
sortAlphabetical(i1, i2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LibrarySort.Random -> {
|
||||||
|
error("You're not supposed to be here...")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!category.isAscending()) sort *= -1
|
if (!category.isAscending()) sort *= -1
|
||||||
sort
|
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))
|
values.sortedWith(Comparator(sortFn))
|
||||||
}.toSortedMap { category, category2 ->
|
}.toSortedMap { category, category2 ->
|
||||||
// Force default category to always be at the top. This also for some reason fixed a bug where Default
|
when {
|
||||||
// category would disappear whenever a new category is added.
|
// Force default category to always be at the top. This also for some reason fixed a bug where Default
|
||||||
if (category.id == 0) {
|
// category would disappear whenever a new category is added.
|
||||||
-1
|
category.id == 0 -> -1
|
||||||
} else if (category2.id == 0) {
|
category2.id == 0 -> 1
|
||||||
1
|
else -> category.order.compareTo(category2.order)
|
||||||
} else {
|
|
||||||
category.order.compareTo(category2.order)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import dev.icerock.moko.resources.StringResource
|
import dev.icerock.moko.resources.StringResource
|
||||||
import eu.kanade.tachiyomi.R
|
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 eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
||||||
|
import yokai.i18n.MR
|
||||||
|
|
||||||
enum class LibrarySort(
|
enum class LibrarySort(
|
||||||
val mainValue: Int,
|
val mainValue: Int,
|
||||||
|
@ -33,7 +30,11 @@ enum class LibrarySort(
|
||||||
MR.strings.category,
|
MR.strings.category,
|
||||||
R.drawable.ic_label_outline_24dp,
|
R.drawable.ic_label_outline_24dp,
|
||||||
),
|
),
|
||||||
|
Random(
|
||||||
|
8,
|
||||||
|
MR.strings.random,
|
||||||
|
R.drawable.ic_shuffle_24dp,
|
||||||
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
val categoryValue: Char
|
val categoryValue: Char
|
||||||
|
@ -50,6 +51,7 @@ enum class LibrarySort(
|
||||||
LatestChapter -> "LATEST_CHAPTER"
|
LatestChapter -> "LATEST_CHAPTER"
|
||||||
DateFetched -> "CHAPTER_FETCH_DATE"
|
DateFetched -> "CHAPTER_FETCH_DATE"
|
||||||
DateAdded -> "DATE_ADDED"
|
DateAdded -> "DATE_ADDED"
|
||||||
|
Random -> "RANDOM"
|
||||||
else -> "ALPHABETICAL"
|
else -> "ALPHABETICAL"
|
||||||
}
|
}
|
||||||
return "$type,ASCENDING"
|
return "$type,ASCENDING"
|
||||||
|
@ -85,6 +87,7 @@ enum class LibrarySort(
|
||||||
"LATEST_CHAPTER" -> LatestChapter
|
"LATEST_CHAPTER" -> LatestChapter
|
||||||
"CHAPTER_FETCH_DATE" -> DateFetched
|
"CHAPTER_FETCH_DATE" -> DateFetched
|
||||||
"DATE_ADDED" -> DateAdded
|
"DATE_ADDED" -> DateAdded
|
||||||
|
"RANDOM" -> Random
|
||||||
else -> Title
|
else -> Title
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.koin.dsl.module
|
||||||
import yokai.domain.backup.BackupPreferences
|
import yokai.domain.backup.BackupPreferences
|
||||||
import yokai.domain.base.BasePreferences
|
import yokai.domain.base.BasePreferences
|
||||||
import yokai.domain.download.DownloadPreferences
|
import yokai.domain.download.DownloadPreferences
|
||||||
|
import yokai.domain.library.LibraryPreferences
|
||||||
import yokai.domain.recents.RecentsPreferences
|
import yokai.domain.recents.RecentsPreferences
|
||||||
import yokai.domain.source.SourcePreferences
|
import yokai.domain.source.SourcePreferences
|
||||||
import yokai.domain.storage.StoragePreferences
|
import yokai.domain.storage.StoragePreferences
|
||||||
|
@ -47,6 +48,8 @@ fun preferenceModule(application: Application) = module {
|
||||||
|
|
||||||
single { BackupPreferences(get()) }
|
single { BackupPreferences(get()) }
|
||||||
|
|
||||||
|
single { LibraryPreferences(get()) }
|
||||||
|
|
||||||
single {
|
single {
|
||||||
PreferencesHelper(
|
PreferencesHelper(
|
||||||
context = application,
|
context = application,
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
5
app/src/main/res/drawable/ic_shuffle_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_shuffle_24dp.xml
Normal 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>
|
|
@ -174,6 +174,7 @@
|
||||||
<string name="date_fetched">Date fetched</string>
|
<string name="date_fetched">Date fetched</string>
|
||||||
<string name="latest_chapter">Latest chapter</string>
|
<string name="latest_chapter">Latest chapter</string>
|
||||||
<string name="drag_and_drop">Drag & Drop</string>
|
<string name="drag_and_drop">Drag & Drop</string>
|
||||||
|
<string name="random">Random</string>
|
||||||
|
|
||||||
<!-- Library Display -->
|
<!-- Library Display -->
|
||||||
<string name="display_options">Display options</string>
|
<string name="display_options">Display options</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue