From 8adcf30b632c11627c54ad14f10638cf3f6ad403 Mon Sep 17 00:00:00 2001 From: Luc Mcgrady Date: Mon, 10 Nov 2025 10:04:54 +0000 Subject: [PATCH] Added: Undo --- qt/aqt/mediasrv.py | 2 ++ ts/routes/reviewer-inner/index.ts | 12 +++++++----- ts/routes/reviewer/reviewer.ts | 27 ++++++++++++++++++++++----- ts/routes/reviewer/reviewerRequest.ts | 2 ++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/qt/aqt/mediasrv.py b/qt/aqt/mediasrv.py index 2986aea43..b7462f568 100644 --- a/qt/aqt/mediasrv.py +++ b/qt/aqt/mediasrv.py @@ -734,6 +734,8 @@ exposed_backend_list = [ "get_custom_colours", "set_config_json", "get_config_json", + "undo", + "redo", # DeckService "get_deck_names", # I18nService diff --git a/ts/routes/reviewer-inner/index.ts b/ts/routes/reviewer-inner/index.ts index d94719d21..48b90077e 100644 --- a/ts/routes/reviewer-inner/index.ts +++ b/ts/routes/reviewer-inner/index.ts @@ -78,13 +78,15 @@ addEventListener("message", async (e: MessageEvent) => { }); addEventListener("keydown", (e) => { - if (e.key === "Enter") { - postParentMessage({ type: "keypress", key: e.key }); - } else if ( + const keyInfo: ReviewerRequest = { type: "keypress", key: e.key, ctrl: e.ctrlKey, shift: e.shiftKey }; + if ( e.key.length == 1 && "1234 ".includes(e.key) - && !document.activeElement?.matches("input[type=text], input[type=number], textarea") ) { - postParentMessage({ type: "keypress", key: e.key }); + if (!document.activeElement?.matches("input[type=text], input[type=number], textarea")) { + postParentMessage(keyInfo); + } + } else { + postParentMessage(keyInfo); } }); diff --git a/ts/routes/reviewer/reviewer.ts b/ts/routes/reviewer/reviewer.ts index e5516837a..7d6729499 100644 --- a/ts/routes/reviewer/reviewer.ts +++ b/ts/routes/reviewer/reviewer.ts @@ -1,7 +1,7 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { CardAnswer, type NextCardDataResponse_NextCardData } from "@generated/anki/scheduler_pb"; -import { compareAnswer, getConfigJson, nextCardData, playAvtags, setConfigJson } from "@generated/backend"; +import { compareAnswer, getConfigJson, nextCardData, playAvtags, redo, setConfigJson, undo } from "@generated/backend"; import { derived, get, writable } from "svelte/store"; import type { InnerReviewerRequest } from "../reviewer-inner/innerReviewerRequest"; import type { ReviewerRequest } from "./reviewerRequest"; @@ -33,6 +33,7 @@ export class ReviewerState { _cardData: NextCardDataResponse_NextCardData | undefined = undefined; beginAnsweringMs = Date.now(); readonly cardClass = writable(""); + readonly undoMessage = writable(""); readonly answerShown = writable(false); readonly cardData = writable(undefined); readonly answerButtons = derived(this.cardData, ($cardData) => $cardData?.answerButtons ?? []); @@ -59,7 +60,7 @@ export class ReviewerState { break; } case "keypress": { - this.handleKeyPress(e.data.key); + this.handleKeyPress(e.data.key, e.data.ctrl, e.data.shift); break; } case "setstorage": { @@ -77,7 +78,12 @@ export class ReviewerState { iframe.addEventListener("load", this.onReady.bind(this)); } - handleKeyPress(key: string) { + public refresh() { + this.showQuestion(null); + } + + async handleKeyPress(key: string, ctrl: boolean, shift: boolean) { + key = key.toLowerCase(); switch (key) { case "1": { this.easeButtonPressed(0); @@ -96,7 +102,7 @@ export class ReviewerState { break; } case " ": - case "Enter": { + case "enter": { if (!get(this.answerShown)) { this.showAnswer(); } else { @@ -104,11 +110,22 @@ export class ReviewerState { } break; } + case "z": { + if (ctrl) { + if (shift) { + redo({}); + } else { + await undo({}); + } + this.refresh(); + } + break; + } } } onKeyDown(e: KeyboardEvent) { - this.handleKeyPress(e.key); + this.handleKeyPress(e.key, e.ctrlKey, e.shiftKey); } public registerShortcuts() { diff --git a/ts/routes/reviewer/reviewerRequest.ts b/ts/routes/reviewer/reviewerRequest.ts index 8a3f04c9d..67c9d408c 100644 --- a/ts/routes/reviewer/reviewerRequest.ts +++ b/ts/routes/reviewer/reviewerRequest.ts @@ -14,6 +14,8 @@ interface UpdateTypedAnswerMessage { interface KeyPressMessage { type: "keypress"; key: string; + ctrl: boolean; + shift: boolean; } interface SetStorageMessage {