From dacea90f102df4c1edcf376f98ddfdbab06d2de3 Mon Sep 17 00:00:00 2001 From: Jack Hamilton Date: Sun, 13 Oct 2024 02:51:34 -0500 Subject: [PATCH] Added random library sort (mihonapp/mihon#1317) Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> (cherry picked from commit a72db41bf1746db095fd27bbbce9765c06453581) --- .../library/LibrarySettingsDialog.kt | 22 ++++++++++++++++++- .../ui/library/LibraryScreenModel.kt | 20 ++++++++++------- .../interactor/SetSortModeForCategory.kt | 4 ++++ .../domain/library/model/LibrarySortMode.kt | 9 +++++++- .../library/service/LibraryPreferences.kt | 2 ++ .../domain/library/model/LibraryFlagsTest.kt | 2 +- .../moko-resources/base/strings.xml | 1 + .../core/components/SettingsItems.kt | 13 +++++++++-- 8 files changed, 60 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt b/app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt index a1a6aa9ac..88f083061 100644 --- a/app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt +++ b/app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt @@ -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 @@ -37,6 +39,7 @@ import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.i18n.MR import tachiyomi.i18n.kmk.KMR import tachiyomi.i18n.sy.SYMR +import tachiyomi.presentation.core.components.BaseSortItem import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.HeadingItem import tachiyomi.presentation.core.components.IconItem @@ -228,6 +231,7 @@ private fun ColumnScope.SortPage( MR.strings.action_sort_latest_chapter to LibrarySort.Type.LatestChapter, MR.strings.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate, MR.strings.action_sort_date_added to LibrarySort.Type.DateAdded, + MR.strings.action_sort_random to LibrarySort.Type.Random, // SY --> if (hasSortTags) { SYMR.strings.tag_sorting to LibrarySort.Type.TagList @@ -235,7 +239,19 @@ private fun ColumnScope.SortPage( null }, // SY <-- + MR.strings.action_sort_random to LibrarySort.Type.Random, ).plus(trackerSortOption).map { (titleRes, mode) -> + if (mode == LibrarySort.Type.Random) { + BaseSortItem( + label = stringResource(titleRes), + icon = Icons.Default.Refresh + .takeIf { sortingMode == LibrarySort.Type.Random }, + onClick = { + screenModel.setSort(category, mode, LibrarySort.Direction.Ascending) + }, + ) + return@map + } SortItem( label = stringResource(titleRes), sortDescending = sortDescending.takeIf { sortingMode == mode }, @@ -247,7 +263,11 @@ private fun ColumnScope.SortPage( } else { LibrarySort.Direction.Descending } - else -> if (sortDescending) LibrarySort.Direction.Descending else LibrarySort.Direction.Ascending + else -> if (sortDescending) { + LibrarySort.Direction.Descending + } else { + LibrarySort.Direction.Ascending + } } screenModel.setSort(category, mode, direction) }, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt index 9562ed928..da44d0c8c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt @@ -119,6 +119,7 @@ import tachiyomi.source.local.LocalSource import tachiyomi.source.local.isLocal import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import kotlin.random.Random import tachiyomi.domain.source.model.Source as DomainSource /** @@ -461,6 +462,9 @@ class LibraryScreenModel( val item2Score = trackerScores[i2.libraryManga.id] ?: defaultTrackerScoreSortValue item1Score.compareTo(item2Score) } + LibrarySort.Type.Random -> { + error("Why Are We Still Here? Just To Suffer?") + } // SY --> LibrarySort.Type.TagList -> { val manga1IndexOfTag = listOfTags.indexOfFirst { @@ -476,14 +480,14 @@ class LibraryScreenModel( } return mapValues { (key, value) -> - val comparator = key.sort.comparator() - .let { - if (/* SY --> */ groupSort?.isAscending ?: /* SY <-- */ key.sort.isAscending) { - it - } else { - it.reversed() - } - } + // SY --> + val sort = groupSort ?: key.sort + if (sort.type == LibrarySort.Type.Random) { + return@mapValues value.shuffled(Random(libraryPreferences.randomSortSeed().get())) + } + val comparator = sort.comparator() + // SY <-- + .let { if (/* SY --> */ sort.isAscending /* SY <-- */) it else it.reversed() } .thenComparator(sortAlphabetically) value.sortedWith(comparator) diff --git a/domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt b/domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt index db923561b..70fc057ec 100644 --- a/domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt +++ b/domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt @@ -7,6 +7,7 @@ import tachiyomi.domain.library.model.LibraryGroup import tachiyomi.domain.library.model.LibrarySort import tachiyomi.domain.library.model.plus import tachiyomi.domain.library.service.LibraryPreferences +import kotlin.random.Random class SetSortModeForCategory( private val preferences: LibraryPreferences, @@ -22,6 +23,9 @@ class SetSortModeForCategory( // SY <-- val category = categoryId?.let { categoryRepository.get(it) } val flags = (category?.flags ?: 0) + type + direction + if (type == LibrarySort.Type.Random) { + preferences.randomSortSeed().set(Random.nextInt()) + } if (category != null && preferences.categorizedDisplaySettings().get()) { categoryRepository.updatePartial( CategoryUpdate( diff --git a/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt b/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt index ea79cbba7..e615d703e 100644 --- a/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt +++ b/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt @@ -30,7 +30,8 @@ data class LibrarySort( data object LatestChapter : Type(0b00010100) data object ChapterFetchDate : Type(0b00011000) data object DateAdded : Type(0b00011100) - data object TrackerMean : Type(0b000100000) + data object TrackerMean : Type(0b00100000) + data object Random : Type(0b00111100) // SY --> data object TagList : Type(0b00100100) @@ -81,7 +82,9 @@ data class LibrarySort( Type.ChapterFetchDate, Type.DateAdded, Type.TrackerMean, + Type.Random, /* SY -->*/ Type.TagList, /* SY <--*/ + Type.Random, ) } val directions by lazy { setOf(Direction.Ascending, Direction.Descending) } @@ -109,9 +112,11 @@ data class LibrarySort( "CHAPTER_FETCH_DATE" -> Type.ChapterFetchDate "DATE_ADDED" -> Type.DateAdded "TRACKER_MEAN" -> Type.TrackerMean + "RANDOM" -> Type.Random // SY --> "TAG_LIST" -> Type.TagList // SY <-- + "RANDOM" -> Type.Random else -> Type.Alphabetical } val ascending = if (values[1] == "ASCENDING") Direction.Ascending else Direction.Descending @@ -133,9 +138,11 @@ data class LibrarySort( Type.ChapterFetchDate -> "CHAPTER_FETCH_DATE" Type.DateAdded -> "DATE_ADDED" Type.TrackerMean -> "TRACKER_MEAN" + Type.Random -> "RANDOM" // SY --> Type.TagList -> "TAG_LIST" // SY <-- + Type.Random -> "RANDOM" } val direction = if (direction == Direction.Ascending) "ASCENDING" else "DESCENDING" return "$type,$direction" diff --git a/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt b/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt index d8a16c78e..29a209921 100644 --- a/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt +++ b/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt @@ -28,6 +28,8 @@ class LibraryPreferences( LibrarySort.Serializer::deserialize, ) + fun randomSortSeed() = preferenceStore.getInt("library_random_sort_seed", 0) + fun portraitColumns() = preferenceStore.getInt("pref_library_columns_portrait_key", 0) fun landscapeColumns() = preferenceStore.getInt("pref_library_columns_landscape_key", 0) diff --git a/domain/src/test/java/tachiyomi/domain/library/model/LibraryFlagsTest.kt b/domain/src/test/java/tachiyomi/domain/library/model/LibraryFlagsTest.kt index 7e6c79cd1..5e7b557fc 100644 --- a/domain/src/test/java/tachiyomi/domain/library/model/LibraryFlagsTest.kt +++ b/domain/src/test/java/tachiyomi/domain/library/model/LibraryFlagsTest.kt @@ -12,7 +12,7 @@ class LibraryFlagsTest { @Test fun `Check the amount of flags`() { LibraryDisplayMode.values.size shouldBe 5 - LibrarySort.types.size shouldBe 10 + LibrarySort.types.size shouldBe 11 LibrarySort.directions.size shouldBe 2 } diff --git a/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml index f8d9c2bf3..45a5f4bcc 100644 --- a/i18n/src/commonMain/moko-resources/base/strings.xml +++ b/i18n/src/commonMain/moko-resources/base/strings.xml @@ -69,6 +69,7 @@ Chapter fetch date Date added Tracker score + Random Search Search… Search settings diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt index d317351c1..6832a28da 100644 --- a/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt +++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt @@ -100,12 +100,21 @@ fun SortItem(label: String, sortDescending: Boolean?, onClick: () -> Unit) { 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, )