Added: Undo

This commit is contained in:
Luc Mcgrady 2025-11-10 10:04:54 +00:00
parent 7f256566c8
commit 8adcf30b63
No known key found for this signature in database
GPG key ID: 4F3D7A0B17CC3D9C
4 changed files with 33 additions and 10 deletions

View file

@ -734,6 +734,8 @@ exposed_backend_list = [
"get_custom_colours",
"set_config_json",
"get_config_json",
"undo",
"redo",
# DeckService
"get_deck_names",
# I18nService

View file

@ -78,13 +78,15 @@ addEventListener("message", async (e: MessageEvent<InnerReviewerRequest>) => {
});
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);
}
});

View file

@ -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<NextCardDataResponse_NextCardData | undefined>(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() {

View file

@ -14,6 +14,8 @@ interface UpdateTypedAnswerMessage {
interface KeyPressMessage {
type: "keypress";
key: string;
ctrl: boolean;
shift: boolean;
}
interface SetStorageMessage {