From 0ab795bfa3fd1ce1ae582fbcf8533b363868905d Mon Sep 17 00:00:00 2001 From: Jack Hamilton Date: Thu, 10 Oct 2024 23:50:23 -0500 Subject: [PATCH] Add random sort option --- .../library/LibrarySettingsDialog.kt | 58 ++++++++++++------- .../ui/library/LibraryScreenModel.kt | 15 +++-- .../domain/library/model/LibrarySortMode.kt | 4 ++ .../moko-resources/base/strings.xml | 1 + .../core/components/SettingsItems.kt | 25 ++++++++ 5 files changed, 78 insertions(+), 25 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 bf5daae99..6fe1164c2 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 @@ -29,6 +31,7 @@ import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.i18n.MR import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.HeadingItem +import tachiyomi.presentation.core.components.NondirectionalSortItem import tachiyomi.presentation.core.components.SettingsChipRow import tachiyomi.presentation.core.components.SliderItem import tachiyomi.presentation.core.components.SortItem @@ -178,27 +181,42 @@ 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) -> - SortItem( - label = stringResource(titleRes), - sortDescending = sortDescending.takeIf { sortingMode == mode }, - onClick = { - val isTogglingDirection = sortingMode == mode - val direction = when { - isTogglingDirection -> if (sortDescending) { - LibrarySort.Direction.Ascending - } else { - LibrarySort.Direction.Descending - } - else -> if (sortDescending) { - LibrarySort.Direction.Descending - } else { - LibrarySort.Direction.Ascending - } - } - screenModel.setSort(category, mode, direction) - }, - ) + when(mode) { + LibrarySort.Type.Random -> { + NondirectionalSortItem( + label = stringResource(titleRes), + enabled = sortingMode == LibrarySort.Type.Random, + enabledIcon = Icons.Default.Refresh, + onClick = { + screenModel.setSort(category, mode, LibrarySort.Direction.Ascending) + }, + ) + } + else -> { + SortItem( + label = stringResource(titleRes), + sortDescending = sortDescending.takeIf { sortingMode == mode }, + onClick = { + val isTogglingDirection = sortingMode == mode + val direction = when { + isTogglingDirection -> if (sortDescending) { + LibrarySort.Direction.Ascending + } else { + LibrarySort.Direction.Descending + } + 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 10875ff13..96a73b9c1 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 @@ -267,7 +267,7 @@ class LibraryScreenModel( fun LibrarySort.comparator(): Comparator = Comparator { i1, i2 -> when (this.type) { - LibrarySort.Type.Alphabetical -> { + LibrarySort.Type.Alphabetical, LibrarySort.Type.Random -> { sortAlphabetically(i1, i2) } LibrarySort.Type.LastRead -> { @@ -304,11 +304,16 @@ class LibraryScreenModel( } return mapValues { (key, value) -> - val comparator = key.sort.comparator() - .let { if (key.sort.isAscending) it else it.reversed() } - .thenComparator(sortAlphabetically) + when (key.sort.type) { + LibrarySort.Type.Random -> value.shuffled() + else -> { + val comparator = key.sort.comparator() + .let { if (key.sort.isAscending) it else it.reversed() } + .thenComparator(sortAlphabetically) - value.sortedWith(comparator) + value.sortedWith(comparator) + } + } } } 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 6a89d4e52..33aa32005 100644 --- a/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt +++ b/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt @@ -31,6 +31,7 @@ data class LibrarySort( data object ChapterFetchDate : Type(0b00011000) data object DateAdded : Type(0b00011100) data object TrackerMean : Type(0b000100000) + data object Random : Type(0b000100100) 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/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml index 3f1a37d77..c58cb9845 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 ffa81ddd6..3810c49c3 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 @@ -17,6 +17,7 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowDownward import androidx.compose.material.icons.filled.ArrowUpward +import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.rounded.CheckBox import androidx.compose.material.icons.rounded.CheckBoxOutlineBlank import androidx.compose.material.icons.rounded.DisabledByDefault @@ -115,6 +116,30 @@ fun SortItem(label: String, sortDescending: Boolean?, onClick: () -> Unit) { ) } +@Composable +fun NondirectionalSortItem(label: String, enabled: Boolean, enabledIcon: ImageVector, onClick: () -> Unit) { + val icon = when(enabled) { + true -> enabledIcon + false -> null + } + + BaseSettingsItem( + label = label, + widget = { + if (icon != null) { + Icon( + imageVector = icon, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + ) + } else { + Spacer(modifier = Modifier.size(24.dp)) + } + }, + onClick = onClick, + ) +} + @Composable fun CheckboxItem(label: String, pref: Preference) { val checked by pref.collectAsState()