From e9a8b676a733406145a9263754b330f5aa58cda2 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 10 Dec 2023 12:33:43 +1000 Subject: [PATCH] Ensure deck browser fetches collection data in the background --- qt/aqt/deckbrowser.py | 51 ++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/qt/aqt/deckbrowser.py b/qt/aqt/deckbrowser.py index a2c4f8444..2b7272ac5 100644 --- a/qt/aqt/deckbrowser.py +++ b/qt/aqt/deckbrowser.py @@ -10,7 +10,7 @@ from typing import Any import aqt import aqt.operations -from anki.collection import OpChanges +from anki.collection import Collection, OpChanges from anki.decks import DeckCollapseScope, DeckId, DeckTreeNode from aqt import AnkiQt, gui_hooks from aqt.deckoptions import display_options_for_deck_id @@ -34,6 +34,16 @@ class DeckBrowserBottomBar: self.deck_browser = deck_browser +@dataclass +class RenderData: + """Data from collection that is required to show the page.""" + + tree: DeckTreeNode + current_deck_id: DeckId + studied_today: str + sched_upgrade_required: bool + + @dataclass class DeckBrowserContent: """Stores sections of HTML content that the deck browser will be @@ -54,7 +64,7 @@ class RenderDeckNodeContext: class DeckBrowser: - _dueTree: DeckTreeNode + _render_data: RenderData def __init__(self, mw: AnkiQt) -> None: self.mw = mw @@ -147,27 +157,36 @@ class DeckBrowser: def _renderPage(self, reuse: bool = False) -> None: if not reuse: - def success(tree: DeckTreeNode) -> None: - self._dueTree = tree + def get_data(col: Collection) -> RenderData: + return RenderData( + tree=col.sched.deck_due_tree(), + current_deck_id=col.decks.get_current_id(), + studied_today=col.studied_today(), + sched_upgrade_required=not col.v3_scheduler(), + ) + + def success(output: RenderData) -> None: + self._render_data = output self.__renderPage(None) - return QueryOp( parent=self.mw, - op=lambda col: col.sched.deck_due_tree(), + op=get_data, success=success, ).run_in_background() else: self.web.evalWithCallback("window.pageYOffset", self.__renderPage) def __renderPage(self, offset: int | None) -> None: + data = self._render_data content = DeckBrowserContent( - tree=self._renderDeckTree(self._dueTree), - stats=self._renderStats(), + tree=self._renderDeckTree(data.tree), + stats=self._renderStats(data.studied_today), ) gui_hooks.deck_browser_will_render_content(self, content) self.web.stdHtml( - self._v1_upgrade_message() + self._body % content.__dict__, + self._v1_upgrade_message(data.sched_upgrade_required) + + self._body % content.__dict__, css=["css/deckbrowser.css"], js=[ "js/vendor/jquery.min.js", @@ -184,10 +203,8 @@ class DeckBrowser: def _scrollToOffset(self, offset: int) -> None: self.web.eval("window.scrollTo(0, %d, 'instant');" % offset) - def _renderStats(self) -> str: - return '
{}
'.format( - self.mw.col.studied_today(), - ) + def _renderStats(self, today: str) -> str: + return '
{}
'.format(today) def _renderDeckTree(self, top: DeckTreeNode) -> str: buf = """ @@ -203,7 +220,7 @@ class DeckBrowser: ) buf += self._topLevelDragRow() - ctx = RenderDeckNodeContext(current_deck_id=self.mw.col.conf["curDeck"]) + ctx = RenderDeckNodeContext(current_deck_id=self._render_data.current_deck_id) for child in top.children: buf += self._render_deck_node(child, ctx) @@ -320,7 +337,7 @@ class DeckBrowser: display_options_for_deck_id(did) def _collapse(self, did: DeckId) -> None: - node = self.mw.col.decks.find_deck_in_tree(self._dueTree, did) + node = self.mw.col.decks.find_deck_in_tree(self._render_data.tree, did) if node: node.collapsed = not node.collapsed set_deck_collapsed( @@ -375,8 +392,8 @@ class DeckBrowser: ###################################################################### - def _v1_upgrade_message(self) -> str: - if self.mw.col.sched_ver() == 2 and self.mw.col.v3_scheduler(): + def _v1_upgrade_message(self, required: bool) -> str: + if not required: return "" update_required = tr.scheduling_update_required().replace("V2", "v3")