From d1e94e09d12e51f2ce5bdc6944076c32f93933b4 Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 11 Nov 2024 20:39:49 +0100 Subject: [PATCH] NF: remove bridge command from deck options --- proto/anki/frontend.proto | 6 +++ qt/aqt/deckoptions.py | 39 +++----------------- qt/aqt/mediasrv.py | 24 ++++++++++++ qt/aqt/webview.py | 3 ++ ts/routes/deck-options/[deckId]/+page.svelte | 20 +++++----- 5 files changed, 48 insertions(+), 44 deletions(-) diff --git a/proto/anki/frontend.proto b/proto/anki/frontend.proto index 7c69429ab69..7b8007629d0 100644 --- a/proto/anki/frontend.proto +++ b/proto/anki/frontend.proto @@ -22,6 +22,12 @@ service FrontendService { rpc ImportDone(generic.Empty) returns (generic.Empty); rpc SearchInBrowser(search.SearchNode) returns (generic.Empty); + + // The RPC Belows are sent by the deck options. + // Force closing the deck options. + rpc deckOptionsRequireClose(generic.Empty) returns (generic.Empty); + // Warns python that the deck option web view is ready to receive requests. + rpc deckOptionsReady(generic.Empty) returns (generic.Empty); } service BackendFrontendService {} diff --git a/qt/aqt/deckoptions.py b/qt/aqt/deckoptions.py index 9fec4719fab..07e58929c44 100644 --- a/qt/aqt/deckoptions.py +++ b/qt/aqt/deckoptions.py @@ -46,7 +46,6 @@ def _setup_ui(self) -> None: addCloseShortcut(self) self.web = AnkiWebView(kind=AnkiWebViewKind.DECK_OPTIONS) - self.web.set_bridge_command(self._on_bridge_cmd, self) self.web.load_sveltekit_page(f"deck-options/{self._deck['id']}") layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) @@ -58,46 +57,24 @@ def _setup_ui(self) -> None: without_unicode_isolation(tr.actions_options_for(val=self._deck["name"])) ) - def _on_bridge_cmd(self, cmd: str) -> None: - if cmd == "deck_options_ready": - self.deck_options_ready() - elif cmd == "confirmDiscardChanges": - self.confirm_discard_changes() - elif cmd == "_close": - self.require_close() - - def deck_options_ready(self): + def ready(self): self._ready = True gui_hooks.deck_options_did_load(self) def closeEvent(self, evt: QCloseEvent | None) -> None: - if self._close_event_has_cleaned_up: + if self._close_event_has_cleaned_up or not self._ready: + print(f"{self._ready=}, {self._close_event_has_cleaned_up=}") return super().closeEvent(evt) assert evt is not None + print("request js to handle it") evt.ignore() - self.check_pending_changes() + self.web.eval("anki.deckOptionsPendingChanges();") def require_close(self): """Close. Ensure the closeEvent is not ignored.""" self._close_event_has_cleaned_up = True self.close() - def confirm_discard_changes(self) -> None: - def callbackWithUserChoice(choice: int) -> None: - if choice == 0: - # The user accepted to discard current input. - self.require_close() - - ask_user_dialog( - tr.card_templates_discard_changes(), - callback=callbackWithUserChoice, - buttons=[ - QMessageBox.StandardButton.Discard, - (tr.adding_keep_editing(), QMessageBox.ButtonRole.RejectRole), - ], - parent=self, - ) - def reject(self) -> None: self.mw.col.set_wants_abort() self.web.cleanup() @@ -105,12 +82,6 @@ def reject(self) -> None: saveGeom(self, self.TITLE) QDialog.reject(self) - def check_pending_changes(self): - if self._ready: - self.web.eval("anki.deckOptionsPendingChanges();") - else: - self.require_close() - def confirm_deck_then_display_options(active_card: Card | None = None) -> None: decks = [aqt.mw.col.decks.current()] diff --git a/qt/aqt/mediasrv.py b/qt/aqt/mediasrv.py index 56c246942fe..462514261ec 100644 --- a/qt/aqt/mediasrv.py +++ b/qt/aqt/mediasrv.py @@ -75,6 +75,7 @@ class PageContext(enum.IntEnum): REVIEWER = enum.auto() PREVIEWER = enum.auto() CARD_LAYOUT = enum.auto() + DECK_OPTIONS = enum.auto() # something in /_anki/pages/ NON_LEGACY_PAGE = enum.auto() # Do not use this if you present user content (e.g. content from cards), as it's a @@ -574,6 +575,26 @@ def handle_on_main() -> None: return b"" +def deck_options_require_close() -> bytes: + def handle_on_main() -> None: + window = aqt.mw.app.activeWindow() + if isinstance(window, DeckOptionsDialog): + window.require_close() + + aqt.mw.taskman.run_on_main(handle_on_main) + return b"" + + +def deck_options_ready() -> bytes: + def handle_on_main() -> None: + window = aqt.mw.app.activeWindow() + if isinstance(window, DeckOptionsDialog): + window.ready() + + aqt.mw.taskman.run_on_main(handle_on_main) + return b"" + + post_handler_list = [ congrats_info, get_deck_configs_for_update, @@ -587,6 +608,8 @@ def handle_on_main() -> None: import_json_file, import_json_string, search_in_browser, + deck_options_require_close, + deck_options_ready, ] @@ -689,6 +712,7 @@ def warn() -> None: PageContext.NON_LEGACY_PAGE, PageContext.EDITOR, PageContext.ADDON_PAGE, + PageContext.DECK_OPTIONS, ]: pass elif context == PageContext.REVIEWER and request.path in ( diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index 65d294bf6f2..980e7a989ec 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -611,6 +611,7 @@ def stdHtml( # print(html) import aqt.browser.previewer import aqt.clayout + import aqt.deckoptions import aqt.editor import aqt.reviewer from aqt.mediasrv import PageContext @@ -623,6 +624,8 @@ def stdHtml( page_context = PageContext.PREVIEWER elif isinstance(context, aqt.clayout.CardLayout): page_context = PageContext.CARD_LAYOUT + elif isinstance(context, aqt.deckoptions.DeckOptionsDialog): + page_context = PageContext.DECK_OPTIONS else: page_context = PageContext.UNKNOWN self.setHtml(html, page_context) diff --git a/ts/routes/deck-options/[deckId]/+page.svelte b/ts/routes/deck-options/[deckId]/+page.svelte index c5064a9508e..08e056de56e 100644 --- a/ts/routes/deck-options/[deckId]/+page.svelte +++ b/ts/routes/deck-options/[deckId]/+page.svelte @@ -3,11 +3,13 @@ Copyright: Ankitects Pty Ltd and contributors License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -->