mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-25 14:19:27 +03:00
Added random library sort
Co-authored-by: Jack Hamilton <4615800+jackhamilton@users.noreply.github.com> Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
This commit is contained in:
parent
0f4a190ff0
commit
cd4c19585d
12 changed files with 81 additions and 4 deletions
|
@ -6,6 +6,8 @@ import androidx.compose.foundation.layout.ColumnScope
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -27,6 +29,7 @@ import tachiyomi.domain.library.anime.model.sort
|
|||
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.BaseSortItem
|
||||
import tachiyomi.presentation.core.components.CheckboxItem
|
||||
import tachiyomi.presentation.core.components.HeadingItem
|
||||
import tachiyomi.presentation.core.components.SettingsChipRow
|
||||
|
@ -183,7 +186,19 @@ private fun ColumnScope.SortPage(
|
|||
MR.strings.action_sort_episode_fetch_date to AnimeLibrarySort.Type.EpisodeFetchDate,
|
||||
MR.strings.action_sort_date_added to AnimeLibrarySort.Type.DateAdded,
|
||||
MR.strings.action_sort_airing_time to AnimeLibrarySort.Type.AiringTime,
|
||||
MR.strings.action_sort_random to AnimeLibrarySort.Type.Random,
|
||||
).plus(trackerSortOption).map { (titleRes, mode) ->
|
||||
if (mode == AnimeLibrarySort.Type.Random) {
|
||||
BaseSortItem(
|
||||
label = stringResource(titleRes),
|
||||
icon = Icons.Default.Refresh
|
||||
.takeIf { sortingMode == AnimeLibrarySort.Type.Random },
|
||||
onClick = {
|
||||
screenModel.setSort(category, mode, AnimeLibrarySort.Direction.Ascending)
|
||||
},
|
||||
)
|
||||
return@map
|
||||
}
|
||||
SortItem(
|
||||
label = stringResource(titleRes),
|
||||
sortDescending = sortDescending.takeIf { sortingMode == mode },
|
||||
|
|
|
@ -6,6 +6,8 @@ import androidx.compose.foundation.layout.ColumnScope
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Refresh
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -27,6 +29,7 @@ import tachiyomi.domain.library.manga.model.sort
|
|||
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.BaseSortItem
|
||||
import tachiyomi.presentation.core.components.CheckboxItem
|
||||
import tachiyomi.presentation.core.components.HeadingItem
|
||||
import tachiyomi.presentation.core.components.SettingsChipRow
|
||||
|
@ -182,7 +185,19 @@ private fun ColumnScope.SortPage(
|
|||
MR.strings.action_sort_latest_chapter to MangaLibrarySort.Type.LatestChapter,
|
||||
MR.strings.action_sort_chapter_fetch_date to MangaLibrarySort.Type.ChapterFetchDate,
|
||||
MR.strings.action_sort_date_added to MangaLibrarySort.Type.DateAdded,
|
||||
MR.strings.action_sort_random to MangaLibrarySort.Type.Random,
|
||||
).plus(trackerSortOption).map { (titleRes, mode) ->
|
||||
if (mode == MangaLibrarySort.Type.Random) {
|
||||
BaseSortItem(
|
||||
label = stringResource(titleRes),
|
||||
icon = Icons.Default.Refresh
|
||||
.takeIf { sortingMode == MangaLibrarySort.Type.Random },
|
||||
onClick = {
|
||||
screenModel.setSort(category, mode, MangaLibrarySort.Direction.Ascending)
|
||||
},
|
||||
)
|
||||
return@map
|
||||
}
|
||||
SortItem(
|
||||
label = stringResource(titleRes),
|
||||
sortDescending = sortDescending.takeIf { sortingMode == mode },
|
||||
|
|
|
@ -72,6 +72,7 @@ import tachiyomi.domain.track.anime.model.AnimeTrack
|
|||
import tachiyomi.source.local.entries.anime.isLocal
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Typealias for the library anime, using the category as keys, and list of anime as values.
|
||||
|
@ -314,10 +315,17 @@ class AnimeLibraryScreenModel(
|
|||
)
|
||||
else -> i1.libraryAnime.unseenCount.compareTo(i2.libraryAnime.unseenCount)
|
||||
}
|
||||
AnimeLibrarySort.Type.Random -> {
|
||||
error("Why Are We Still Here? Just To Suffer?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mapValues { (key, value) ->
|
||||
if (key.sort.type == AnimeLibrarySort.Type.Random) {
|
||||
return@mapValues value.shuffled(Random(libraryPreferences.randomAnimeSortSeed().get()))
|
||||
}
|
||||
|
||||
val comparator = key.sort.comparator()
|
||||
.let { if (key.sort.isAscending) it else it.reversed() }
|
||||
.thenComparator(sortAlphabetically)
|
||||
|
|
|
@ -72,6 +72,7 @@ import tachiyomi.domain.track.manga.model.MangaTrack
|
|||
import tachiyomi.source.local.entries.manga.isLocal
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Typealias for the library manga, using the category as keys, and list of manga as values.
|
||||
|
@ -305,10 +306,17 @@ class MangaLibraryScreenModel(
|
|||
val item2Score = trackerScores[i2.libraryManga.id] ?: defaultTrackerScoreSortValue
|
||||
item1Score.compareTo(item2Score)
|
||||
}
|
||||
MangaLibrarySort.Type.Random -> {
|
||||
error("Why Are We Still Here? Just To Suffer?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mapValues { (key, value) ->
|
||||
if (key.sort.type == MangaLibrarySort.Type.Random) {
|
||||
return@mapValues value.shuffled(Random(libraryPreferences.randomMangaSortSeed().get()))
|
||||
}
|
||||
|
||||
val comparator = key.sort.comparator()
|
||||
.let { if (key.sort.isAscending) it else it.reversed() }
|
||||
.thenComparator(sortAlphabetically)
|
||||
|
|
|
@ -6,6 +6,7 @@ import tachiyomi.domain.category.model.CategoryUpdate
|
|||
import tachiyomi.domain.library.anime.model.AnimeLibrarySort
|
||||
import tachiyomi.domain.library.model.plus
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import kotlin.random.Random
|
||||
|
||||
class SetSortModeForAnimeCategory(
|
||||
private val preferences: LibraryPreferences,
|
||||
|
@ -19,6 +20,9 @@ class SetSortModeForAnimeCategory(
|
|||
) {
|
||||
val category = categoryId?.let { categoryRepository.getAnimeCategory(it) }
|
||||
val flags = (category?.flags ?: 0) + type + direction
|
||||
if (type == AnimeLibrarySort.Type.Random) {
|
||||
preferences.randomAnimeSortSeed().set(Random.nextInt())
|
||||
}
|
||||
if (category != null && preferences.categorizedDisplaySettings().get()) {
|
||||
categoryRepository.updatePartialAnimeCategory(
|
||||
CategoryUpdate(
|
||||
|
|
|
@ -6,6 +6,7 @@ import tachiyomi.domain.category.model.CategoryUpdate
|
|||
import tachiyomi.domain.library.manga.model.MangaLibrarySort
|
||||
import tachiyomi.domain.library.model.plus
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import kotlin.random.Random
|
||||
|
||||
class SetSortModeForMangaCategory(
|
||||
private val preferences: LibraryPreferences,
|
||||
|
@ -19,6 +20,9 @@ class SetSortModeForMangaCategory(
|
|||
) {
|
||||
val category = categoryId?.let { categoryRepository.getMangaCategory(it) }
|
||||
val flags = (category?.flags ?: 0) + type + direction
|
||||
if (type == MangaLibrarySort.Type.Random) {
|
||||
preferences.randomMangaSortSeed().set(Random.nextInt())
|
||||
}
|
||||
if (category != null && preferences.categorizedDisplaySettings().get()) {
|
||||
categoryRepository.updatePartialMangaCategory(
|
||||
CategoryUpdate(
|
||||
|
|
|
@ -34,6 +34,7 @@ data class AnimeLibrarySort(
|
|||
data object DateAdded : Type(0b00011100)
|
||||
data object TrackerMean : Type(0b000100000)
|
||||
data object AiringTime : Type(0b00110000)
|
||||
data object Random : Type(0b00111100)
|
||||
|
||||
companion object {
|
||||
fun valueOf(flag: Long): Type {
|
||||
|
@ -81,6 +82,7 @@ data class AnimeLibrarySort(
|
|||
Type.DateAdded,
|
||||
Type.TrackerMean,
|
||||
Type.AiringTime,
|
||||
Type.Random,
|
||||
)
|
||||
}
|
||||
val directions by lazy { setOf(Direction.Ascending, Direction.Descending) }
|
||||
|
@ -109,6 +111,7 @@ data class AnimeLibrarySort(
|
|||
"DATE_ADDED" -> Type.DateAdded
|
||||
"TRACKER_MEAN" -> Type.TrackerMean
|
||||
"AIRING_TIME" -> Type.AiringTime
|
||||
"RANDOM" -> Type.Random
|
||||
else -> Type.Alphabetical
|
||||
}
|
||||
val ascending = if (values[1] == "ASCENDING") Direction.Ascending else Direction.Descending
|
||||
|
@ -131,6 +134,7 @@ data class AnimeLibrarySort(
|
|||
Type.DateAdded -> "DATE_ADDED"
|
||||
Type.TrackerMean -> "TRACKER_MEAN"
|
||||
Type.AiringTime -> "AIRING_TIME"
|
||||
Type.Random -> "RANDOM"
|
||||
}
|
||||
val direction = if (direction == Direction.Ascending) "ASCENDING" else "DESCENDING"
|
||||
return "$type,$direction"
|
||||
|
|
|
@ -33,6 +33,7 @@ data class MangaLibrarySort(
|
|||
data object ChapterFetchDate : Type(0b00011000)
|
||||
data object DateAdded : Type(0b00011100)
|
||||
data object TrackerMean : Type(0b000100000)
|
||||
data object Random : Type(0b00111100)
|
||||
|
||||
companion object {
|
||||
fun valueOf(flag: Long): Type {
|
||||
|
@ -79,6 +80,7 @@ data class MangaLibrarySort(
|
|||
Type.ChapterFetchDate,
|
||||
Type.DateAdded,
|
||||
Type.TrackerMean,
|
||||
Type.Random,
|
||||
)
|
||||
}
|
||||
val directions by lazy { setOf(Direction.Ascending, Direction.Descending) }
|
||||
|
@ -106,6 +108,7 @@ data class MangaLibrarySort(
|
|||
"CHAPTER_FETCH_DATE" -> Type.ChapterFetchDate
|
||||
"DATE_ADDED" -> Type.DateAdded
|
||||
"TRACKER_MEAN" -> Type.TrackerMean
|
||||
"RANDOM" -> Type.Random
|
||||
else -> Type.Alphabetical
|
||||
}
|
||||
val ascending = if (values[1] == "ASCENDING") Direction.Ascending else Direction.Descending
|
||||
|
@ -127,6 +130,7 @@ data class MangaLibrarySort(
|
|||
Type.ChapterFetchDate -> "CHAPTER_FETCH_DATE"
|
||||
Type.DateAdded -> "DATE_ADDED"
|
||||
Type.TrackerMean -> "TRACKER_MEAN"
|
||||
Type.Random -> "RANDOM"
|
||||
}
|
||||
val direction = if (direction == Direction.Ascending) "ASCENDING" else "DESCENDING"
|
||||
return "$type,$direction"
|
||||
|
|
|
@ -89,6 +89,11 @@ class LibraryPreferences(
|
|||
|
||||
fun autoClearItemCache() = preferenceStore.getBoolean("auto_clear_chapter_cache", false)
|
||||
|
||||
// Random Sort Seed
|
||||
|
||||
fun randomAnimeSortSeed() = preferenceStore.getInt("library_random_anime_sort_seed", 0)
|
||||
fun randomMangaSortSeed() = preferenceStore.getInt("library_random_manga_sort_seed", 0)
|
||||
|
||||
// Mixture Columns
|
||||
|
||||
fun animePortraitColumns() = preferenceStore.getInt("pref_animelib_columns_portrait_key", 0)
|
||||
|
|
|
@ -14,9 +14,9 @@ class LibraryFlagsTest {
|
|||
@Test
|
||||
fun `Check the amount of flags`() {
|
||||
LibraryDisplayMode.values.size shouldBe 4
|
||||
MangaLibrarySort.types.size shouldBe 9
|
||||
MangaLibrarySort.types.size shouldBe 10
|
||||
MangaLibrarySort.directions.size shouldBe 2
|
||||
AnimeLibrarySort.types.size shouldBe 10
|
||||
AnimeLibrarySort.types.size shouldBe 11
|
||||
AnimeLibrarySort.directions.size shouldBe 2
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<string name="action_sort_chapter_fetch_date">Chapter fetch date</string>
|
||||
<string name="action_sort_date_added">Date added</string>
|
||||
<string name="action_sort_tracker_score">Tracker score</string>
|
||||
<string name="action_sort_random">Random</string>
|
||||
<string name="action_sort_airing_time">Airing time</string>
|
||||
<string name="action_search">Search</string>
|
||||
<string name="action_search_hint">Search…</string>
|
||||
|
|
|
@ -122,12 +122,21 @@ fun SortItem(
|
|||
null -> null
|
||||
}
|
||||
|
||||
BaseSortItem(
|
||||
label = label,
|
||||
icon = arrowIcon,
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BaseSortItem(label: String, icon: ImageVector?, onClick: () -> Unit) {
|
||||
BaseSettingsItem(
|
||||
label = label,
|
||||
widget = {
|
||||
if (arrowIcon != null) {
|
||||
if (icon != null) {
|
||||
Icon(
|
||||
imageVector = arrowIcon,
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue