From d154002109d88b860a545b0d37fe148fbd664611 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Mon, 12 Oct 2026 22:57:12 +0200 Subject: [PATCH] feat(core,app): open the library the way it was last arranged Filter, sort and franchise folding reset on every launch, so someone who browses by Recently added chose it again each time. They are kept in the desktop's own settings file, alongside the cache budget. --- crates/pstr-app/src/app.rs | 35 +++++++++++++++++++++++++--- crates/pstr-app/src/desktop_prefs.rs | 9 +++++++ crates/pstr-core/src/browse.rs | 3 ++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/crates/pstr-app/src/app.rs b/crates/pstr-app/src/app.rs index 3412765..caf47a5 100644 --- a/crates/pstr-app/src/app.rs +++ b/crates/pstr-app/src/app.rs @@ -382,6 +382,18 @@ pub struct LibraryView { stale: bool, } +impl LibraryView { + /// The view as the viewer last arranged it. + fn arranged(prefs: crate::desktop_prefs::DesktopPrefs) -> Self { + Self { + filter: prefs.filter, + sort: prefs.sort, + grouped: prefs.grouped, + ..Self::default() + } + } +} + impl Default for LibraryView { fn default() -> Self { Self { @@ -404,7 +416,8 @@ impl Default for LibraryView { } /// Which titles the grid shows. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "snake_case")] pub enum Filter { #[default] All, @@ -674,6 +687,7 @@ impl App { engine.connect(); engine.crawl_stale(); let settings = engine.metadata_config(); + let arranged = engine.desktop_prefs(); Ok(Self { engine, @@ -697,7 +711,7 @@ impl App { focus_search: false, shortcuts_open: false, osd: None, - view: LibraryView::default(), + view: LibraryView::arranged(arranged), loaded: false, form: ShareForm::default(), account: ui::account::AccountPanel::default(), @@ -736,6 +750,17 @@ impl App { } } + /// Keep how the library is arranged for the next launch: a viewer who + /// sorts by recently added does so every time, not once. + fn remember_arrangement(&self) { + let mut prefs = self.engine.desktop_prefs(); + let arranged = (self.view.filter, self.view.sort, self.view.grouped); + if (prefs.filter, prefs.sort, prefs.grouped) != arranged { + (prefs.filter, prefs.sort, prefs.grouped) = arranged; + self.engine.set_desktop_prefs(prefs); + } + } + /// Say that the playing file failed, with a button that opens it again /// where it stopped — a dropped connection is the usual cause, and the /// session refresh behind the next open is usually the cure. @@ -1506,8 +1531,12 @@ impl App { Action::SetShelf(filter, sort) => { self.view.filter = filter; self.view.sort = sort; + self.remember_arrangement(); + } + Action::SetGrouped(grouped) => { + self.view.grouped = grouped; + self.remember_arrangement(); } - Action::SetGrouped(grouped) => self.view.grouped = grouped, Action::Back => match self.page { Page::Title(_) => self.page = Page::Library, // Back out of a search before out of anything else: it is the diff --git a/crates/pstr-app/src/desktop_prefs.rs b/crates/pstr-app/src/desktop_prefs.rs index bfd0ff2..1fb2818 100644 --- a/crates/pstr-app/src/desktop_prefs.rs +++ b/crates/pstr-app/src/desktop_prefs.rs @@ -21,6 +21,10 @@ pub struct DesktopPrefs { pub hardware_decoding: bool, /// How much decrypted video the disk cache may keep. pub cache_gib: u32, + /// How the library was last arranged, so it opens that way. + pub filter: crate::app::Filter, + pub sort: pstr_core::browse::Sort, + pub grouped: bool, } impl Default for DesktopPrefs { @@ -28,6 +32,11 @@ impl Default for DesktopPrefs { Self { hardware_decoding: true, cache_gib: 4, + filter: crate::app::Filter::default(), + sort: pstr_core::browse::Sort::default(), + // On: a share holding a series and its three films is four tiles + // of the same picture otherwise. + grouped: true, } } } diff --git a/crates/pstr-core/src/browse.rs b/crates/pstr-core/src/browse.rs index 4c2eefc..529f398 100644 --- a/crates/pstr-core/src/browse.rs +++ b/crates/pstr-core/src/browse.rs @@ -11,7 +11,8 @@ use crate::library::{Library, Title, sort_name}; use crate::metadata::{MetadataRecord, TitleNames}; /// What order a grid is in. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "snake_case")] pub enum Sort { /// By the name shown, ignoring a leading article. #[default]