Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deck options without bridge #3571

Merged
merged 7 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ AMBOSS MD Inc. <https://www.amboss.com/>
Aristotelis P. <https://glutanimate.com/contact>
Erez Volk <[email protected]>
zjosua <[email protected]>
Arthur Milchior <[email protected]>
Yngve Hoiseth <[email protected]>
Arthur Milchior <[email protected]>
Ijgnd
Yoonchae Lee <[email protected]>
Evandro Coan <github.com/evandrocoan>
Expand Down
5 changes: 5 additions & 0 deletions proto/anki/frontend.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ service FrontendService {
rpc ImportDone(generic.Empty) returns (generic.Empty);

rpc SearchInBrowser(search.SearchNode) returns (generic.Empty);

// 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 {}
Expand Down
41 changes: 6 additions & 35 deletions qt/aqt/deckoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from aqt.utils import (
KeyboardModifiersPressed,
addCloseShortcut,
ask_user_dialog,
disable_help_button,
restoreGeom,
saveGeom,
Expand Down Expand Up @@ -46,7 +45,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)
Expand All @@ -58,56 +56,29 @@ 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 == "deckOptionsReady":
self._ready = True
gui_hooks.deck_options_did_load(self)
elif cmd == "confirmDiscardChanges":
self.confirm_discard_changes()
elif cmd == "_close":
self._close()
def set_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:
return super().closeEvent(evt)
assert evt is not None
evt.ignore()
self.check_pending_changes()
self.web.eval("anki.deckOptionsPendingChanges();")

def _close(self):
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._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()
self.web = None # type: ignore
saveGeom(self, self.TITLE)
QDialog.reject(self)

def check_pending_changes(self):
if self._ready:
self.web.eval("anki.deckOptionsPendingChanges();")
else:
self._close()


def confirm_deck_then_display_options(active_card: Card | None = None) -> None:
decks = [aqt.mw.col.decks.current()]
Expand Down
34 changes: 29 additions & 5 deletions qt/aqt/mediasrv.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.set_ready()

aqt.mw.taskman.run_on_main(handle_on_main)
return b""


post_handler_list = [
congrats_info,
get_deck_configs_for_update,
Expand All @@ -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,
]


Expand Down Expand Up @@ -685,11 +708,12 @@ def warn() -> None:
aqt.mw.taskman.run_on_main(warn)
abort(403)

if (
context == PageContext.NON_LEGACY_PAGE
or context == PageContext.EDITOR
or context == PageContext.ADDON_PAGE
):
if context in [
PageContext.NON_LEGACY_PAGE,
PageContext.EDITOR,
PageContext.ADDON_PAGE,
PageContext.DECK_OPTIONS,
]:
pass
elif context == PageContext.REVIEWER and request.path in (
"/_anki/getSchedulingStatesWithContext",
Expand Down
3 changes: 3 additions & 0 deletions qt/aqt/webview.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
20 changes: 10 additions & 10 deletions ts/routes/deck-options/[deckId]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,26 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import * as tr from "@generated/ftl";

import { onMount } from "svelte";
import DeckOptionsPage from "../DeckOptionsPage.svelte";
import { commitEditing } from "../lib";
import type { PageData } from "./$types";
import { bridgeCommand, bridgeCommandsAvailable } from "@tslib/bridgecommand";
import { deckOptionsRequireClose, deckOptionsReady } from "@generated/backend";

export let data: PageData;
let page: DeckOptionsPage;

globalThis.anki ||= {};
globalThis.anki.deckOptionsPendingChanges = async (): Promise<void> => {
await commitEditing();
if (bridgeCommandsAvailable()) {
if (await data.state.isModified()) {
bridgeCommand("confirmDiscardChanges");
} else {
bridgeCommand("_close");
}
if (
!(await data.state.isModified()) ||
confirm(tr.cardTemplatesDiscardChanges())
) {
// Either there was no change, or the user accepted to discard the changes.
deckOptionsRequireClose({});
}
};

Expand All @@ -29,9 +31,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
resolve(page);
});
data.state.resolveOriginalConfigs();
if (bridgeCommandsAvailable()) {
bridgeCommand("deckOptionsReady");
}
deckOptionsReady({});
});
</script>

Expand Down