mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Add random sort option
This commit is contained in:
		@@ -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)
 | 
			
		||||
                    },
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -267,7 +267,7 @@ class LibraryScreenModel(
 | 
			
		||||
 | 
			
		||||
        fun LibrarySort.comparator(): Comparator<LibraryItem> = 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)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,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_search">Search</string>
 | 
			
		||||
    <string name="action_search_hint">Search…</string>
 | 
			
		||||
    <string name="action_search_settings">Search settings</string>
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Boolean>) {
 | 
			
		||||
    val checked by pref.collectAsState()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user