From 660a87bb944e5beb6e743d4fb73fa9e11084b656 Mon Sep 17 00:00:00 2001 From: TheBobBobs <84781603+TheBobBobs@users.noreply.github.com> Date: Sat, 23 Aug 2025 20:42:36 +0000 Subject: [PATCH] feat: add random sorting (#1029) * feat: add random sorting * fix: improve randomness of random sort --- src/tagstudio/core/library/alchemy/enums.py | 8 +++++++- src/tagstudio/core/library/alchemy/library.py | 2 ++ src/tagstudio/resources/translations/en.json | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tagstudio/core/library/alchemy/enums.py b/src/tagstudio/core/library/alchemy/enums.py index a51271e5..76f7fa12 100644 --- a/src/tagstudio/core/library/alchemy/enums.py +++ b/src/tagstudio/core/library/alchemy/enums.py @@ -1,4 +1,5 @@ import enum +import random from dataclasses import dataclass, replace from pathlib import Path @@ -69,6 +70,7 @@ class SortingModeEnum(enum.Enum): DATE_ADDED = "file.date_added" FILE_NAME = "generic.filename" PATH = "file.path" + RANDOM = "sorting.mode.random" @dataclass @@ -78,6 +80,7 @@ class BrowsingState: page_index: int = 0 sorting_mode: SortingModeEnum = SortingModeEnum.DATE_ADDED ascending: bool = True + random_seed: float = 0 query: str | None = None @@ -133,7 +136,10 @@ class BrowsingState: return replace(self, page_index=index) def with_sorting_mode(self, mode: SortingModeEnum) -> "BrowsingState": - return replace(self, sorting_mode=mode) + seed = self.random_seed + if mode == SortingModeEnum.RANDOM: + seed = random.random() + return replace(self, sorting_mode=mode, random_seed=seed) def with_sorting_direction(self, ascending: bool) -> "BrowsingState": return replace(self, ascending=ascending) diff --git a/src/tagstudio/core/library/alchemy/library.py b/src/tagstudio/core/library/alchemy/library.py index 0ec05709..bdc0dad4 100644 --- a/src/tagstudio/core/library/alchemy/library.py +++ b/src/tagstudio/core/library/alchemy/library.py @@ -921,6 +921,8 @@ class Library: sort_on = func.lower(Entry.filename) case SortingModeEnum.PATH: sort_on = func.lower(Entry.path) + case SortingModeEnum.RANDOM: + sort_on = func.sin(Entry.id * search.random_seed) statement = statement.order_by(asc(sort_on) if search.ascending else desc(sort_on)) if page_size is not None: diff --git a/src/tagstudio/resources/translations/en.json b/src/tagstudio/resources/translations/en.json index 1b3bf63b..62e6d90a 100644 --- a/src/tagstudio/resources/translations/en.json +++ b/src/tagstudio/resources/translations/en.json @@ -264,6 +264,7 @@ "settings.title": "Settings", "sorting.direction.ascending": "Ascending", "sorting.direction.descending": "Descending", + "sorting.mode.random": "Random", "splash.opening_library": "Opening Library \"{library_path}\"...", "status.deleted_file_plural": "Deleted {count} files!", "status.deleted_file_singular": "Deleted 1 file!",