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,
)