Ensure deck browser fetches collection data in the background

This commit is contained in:
Damien Elmes 2023-12-10 12:33:43 +10:00
parent 6b3381afef
commit e9a8b676a7

View file

@ -10,7 +10,7 @@ from typing import Any
import aqt import aqt
import aqt.operations import aqt.operations
from anki.collection import OpChanges from anki.collection import Collection, OpChanges
from anki.decks import DeckCollapseScope, DeckId, DeckTreeNode from anki.decks import DeckCollapseScope, DeckId, DeckTreeNode
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.deckoptions import display_options_for_deck_id from aqt.deckoptions import display_options_for_deck_id
@ -34,6 +34,16 @@ class DeckBrowserBottomBar:
self.deck_browser = deck_browser 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 @dataclass
class DeckBrowserContent: class DeckBrowserContent:
"""Stores sections of HTML content that the deck browser will be """Stores sections of HTML content that the deck browser will be
@ -54,7 +64,7 @@ class RenderDeckNodeContext:
class DeckBrowser: class DeckBrowser:
_dueTree: DeckTreeNode _render_data: RenderData
def __init__(self, mw: AnkiQt) -> None: def __init__(self, mw: AnkiQt) -> None:
self.mw = mw self.mw = mw
@ -147,27 +157,36 @@ class DeckBrowser:
def _renderPage(self, reuse: bool = False) -> None: def _renderPage(self, reuse: bool = False) -> None:
if not reuse: if not reuse:
def success(tree: DeckTreeNode) -> None: def get_data(col: Collection) -> RenderData:
self._dueTree = tree 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) self.__renderPage(None)
return
QueryOp( QueryOp(
parent=self.mw, parent=self.mw,
op=lambda col: col.sched.deck_due_tree(), op=get_data,
success=success, success=success,
).run_in_background() ).run_in_background()
else: else:
self.web.evalWithCallback("window.pageYOffset", self.__renderPage) self.web.evalWithCallback("window.pageYOffset", self.__renderPage)
def __renderPage(self, offset: int | None) -> None: def __renderPage(self, offset: int | None) -> None:
data = self._render_data
content = DeckBrowserContent( content = DeckBrowserContent(
tree=self._renderDeckTree(self._dueTree), tree=self._renderDeckTree(data.tree),
stats=self._renderStats(), stats=self._renderStats(data.studied_today),
) )
gui_hooks.deck_browser_will_render_content(self, content) gui_hooks.deck_browser_will_render_content(self, content)
self.web.stdHtml( 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"], css=["css/deckbrowser.css"],
js=[ js=[
"js/vendor/jquery.min.js", "js/vendor/jquery.min.js",
@ -184,10 +203,8 @@ class DeckBrowser:
def _scrollToOffset(self, offset: int) -> None: def _scrollToOffset(self, offset: int) -> None:
self.web.eval("window.scrollTo(0, %d, 'instant');" % offset) self.web.eval("window.scrollTo(0, %d, 'instant');" % offset)
def _renderStats(self) -> str: def _renderStats(self, today: str) -> str:
return '<div id="studiedToday"><span>{}</span></div>'.format( return '<div id="studiedToday"><span>{}</span></div>'.format(today)
self.mw.col.studied_today(),
)
def _renderDeckTree(self, top: DeckTreeNode) -> str: def _renderDeckTree(self, top: DeckTreeNode) -> str:
buf = """ buf = """
@ -203,7 +220,7 @@ class DeckBrowser:
) )
buf += self._topLevelDragRow() 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: for child in top.children:
buf += self._render_deck_node(child, ctx) buf += self._render_deck_node(child, ctx)
@ -320,7 +337,7 @@ class DeckBrowser:
display_options_for_deck_id(did) display_options_for_deck_id(did)
def _collapse(self, did: DeckId) -> None: 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: if node:
node.collapsed = not node.collapsed node.collapsed = not node.collapsed
set_deck_collapsed( set_deck_collapsed(
@ -375,8 +392,8 @@ class DeckBrowser:
###################################################################### ######################################################################
def _v1_upgrade_message(self) -> str: def _v1_upgrade_message(self, required: bool) -> str:
if self.mw.col.sched_ver() == 2 and self.mw.col.v3_scheduler(): if not required:
return "" return ""
update_required = tr.scheduling_update_required().replace("V2", "v3") update_required = tr.scheduling_update_required().replace("V2", "v3")