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 bf5daae99e..8410cfb40c 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 @@ -27,6 +29,7 @@ import tachiyomi.domain.library.model.LibrarySort import tachiyomi.domain.library.model.sort 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 @@ -178,7 +181,19 @@ 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, ).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 }, 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 10875ff133..794dac4d0e 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 @@ -72,6 +72,7 @@ import tachiyomi.domain.track.model.Track import tachiyomi.source.local.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. @@ -300,10 +301,17 @@ class LibraryScreenModel( val item2Score = trackerScores[i2.libraryManga.id] ?: defaultTrackerScoreSortValue item1Score.compareTo(item2Score) } + LibrarySort.Type.Random -> { + error("Why Are We Still Here? Just To Suffer?") + } } } return mapValues { (key, value) -> + if (key.sort.type == LibrarySort.Type.Random) { + return@mapValues value.shuffled(Random(libraryPreferences.randomSortSeed().get())) + } + val comparator = key.sort.comparator() .let { if (key.sort.isAscending) it else it.reversed() } .thenComparator(sortAlphabetically) 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 e514e08988..85196f7711 100644 --- a/domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt +++ b/domain/src/main/java/tachiyomi/domain/category/interactor/SetSortModeForCategory.kt @@ -6,6 +6,7 @@ import tachiyomi.domain.category.repository.CategoryRepository 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, @@ -15,6 +16,9 @@ class SetSortModeForCategory( suspend fun await(categoryId: Long?, type: LibrarySort.Type, direction: LibrarySort.Direction) { 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 6a89d4e526..cbe769dcf0 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) companion object { fun valueOf(flag: Long): Type { @@ -77,6 +78,7 @@ data class LibrarySort( Type.ChapterFetchDate, Type.DateAdded, Type.TrackerMean, + Type.Random, ) } val directions by lazy { setOf(Direction.Ascending, Direction.Descending) } @@ -104,6 +106,7 @@ data class LibrarySort( "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 @@ -125,6 +128,7 @@ data class LibrarySort( 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" 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 437dc54bce..5a9d86182f 100644 --- a/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt +++ b/domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt @@ -26,6 +26,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 a3a2237822..11af8ebfb1 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 4 - LibrarySort.types.size shouldBe 9 + LibrarySort.types.size shouldBe 10 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 3f1a37d772..c58cb9845d 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 ffa81ddd61..f9d4923c5d 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 @@ -98,12 +98,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, )