diff --git a/proto/backend.proto b/proto/backend.proto index e56d4e6ad..543524f35 100644 --- a/proto/backend.proto +++ b/proto/backend.proto @@ -643,12 +643,15 @@ message Deck { } message DeckCommon { - bool collapsed = 1; - uint32 last_day_studied = 2; - int32 new_studied = 3; - int32 review_studied = 4; - int32 learning_studied = 5; - int32 secs_studied = 6; + bool study_collapsed = 1; + bool browser_collapsed = 2; + + uint32 last_day_studied = 3; + int32 new_studied = 4; + int32 review_studied = 5; + int32 learning_studied = 6; + int32 secs_studied = 7; + bytes other = 16; } diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index cc7810784..1f44e4b2f 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -1170,9 +1170,7 @@ QTableView {{ gridline-color: {grid} }} ":/icons/deck.svg", set_filter(), toggle_expand(), - not self.mw.col.decks.get(node.deck_id).get( - "browserCollapsed", False - ), + not node.collapsed, ) root.addChild(item) newhead = head + node.name + "::" diff --git a/rslib/src/decks/schema11.rs b/rslib/src/decks/schema11.rs index 48a41b76d..b39168400 100644 --- a/rslib/src/decks/schema11.rs +++ b/rslib/src/decks/schema11.rs @@ -89,7 +89,10 @@ pub struct DeckCommonSchema11 { pub(crate) usn: Usn, #[serde(flatten)] pub(crate) today: DeckTodaySchema11, - collapsed: bool, + #[serde(rename = "collapsed")] + study_collapsed: bool, + #[serde(default, rename = "browserCollapsed")] + browser_collapsed: bool, #[serde(default)] desc: String, #[serde(rename = "dyn")] @@ -209,7 +212,8 @@ impl Default for NormalDeckSchema11 { mtime: TimestampSecs(0), name: "".to_string(), usn: Usn(0), - collapsed: false, + study_collapsed: false, + browser_collapsed: false, desc: "".to_string(), today: Default::default(), other: Default::default(), @@ -255,7 +259,8 @@ impl From<&DeckCommonSchema11> for DeckCommon { serde_json::to_vec(&common.other).unwrap_or_default() }; DeckCommon { - collapsed: common.collapsed, + study_collapsed: common.study_collapsed, + browser_collapsed: common.browser_collapsed, last_day_studied: common.today.new.day as u32, new_studied: common.today.new.amount, review_studied: common.today.rev.amount, @@ -338,7 +343,8 @@ impl From for DeckCommonSchema11 { name: deck.name.replace("\x1f", "::"), usn: deck.usn, today: (&deck).into(), - collapsed: deck.common.collapsed, + study_collapsed: deck.common.study_collapsed, + browser_collapsed: deck.common.browser_collapsed, dynamic: if matches!(deck.kind, DeckKind::Filtered(_)) { 1 } else { diff --git a/rslib/src/decks/tree.rs b/rslib/src/decks/tree.rs index dc79029be..c0097d8e3 100644 --- a/rslib/src/decks/tree.rs +++ b/rslib/src/decks/tree.rs @@ -1,8 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +use super::Deck; use crate::{backend_proto::DeckTreeNode, collection::Collection, decks::DeckID, err::Result}; -use std::iter::Peekable; +use std::{collections::HashMap, iter::Peekable}; // fixme: handle mixed case of parents @@ -50,10 +51,34 @@ fn add_child_nodes( } } +fn add_collapsed(node: &mut DeckTreeNode, decks: &HashMap, browser: bool) { + if let Some(deck) = decks.get(&DeckID(node.deck_id)) { + node.collapsed = if browser { + deck.common.browser_collapsed + } else { + deck.common.study_collapsed + }; + } + for child in &mut node.children { + add_collapsed(child, decks, browser); + } +} + impl Collection { pub fn deck_tree(&self) -> Result { let names = self.storage.get_all_deck_names()?; - Ok(deck_names_to_tree(names)) + let mut tree = deck_names_to_tree(names); + + let decks_map: HashMap<_, _> = self + .storage + .get_all_decks()? + .into_iter() + .map(|d| (d.id, d)) + .collect(); + + add_collapsed(&mut tree, &decks_map, true); + + Ok(tree) } } diff --git a/rslib/src/storage/deck/mod.rs b/rslib/src/storage/deck/mod.rs index c8d28c13e..1f102f539 100644 --- a/rslib/src/storage/deck/mod.rs +++ b/rslib/src/storage/deck/mod.rs @@ -52,7 +52,7 @@ impl SqliteStorage { .collect() } - /// Get all deck names in human-readable form (::) + /// Get all deck names in sorted, human-readable form (::) pub(crate) fn get_all_deck_names(&self) -> Result> { self.db .prepare("select id, name from decks order by name")?