Added: Undo state

This commit is contained in:
Luc Mcgrady 2025-11-12 21:45:00 +00:00
parent 7c683819a2
commit 9f47d7beb1
No known key found for this signature in database
GPG key ID: 4F3D7A0B17CC3D9C
4 changed files with 27 additions and 3 deletions

View file

@ -756,6 +756,7 @@ exposed_backend_list = [
"get_custom_colours", "get_custom_colours",
"set_config_json", "set_config_json",
"get_config_json", "get_config_json",
"get_undo_status",
"undo", "undo",
"redo", "redo",
# DeckService # DeckService

View file

@ -2,7 +2,7 @@
Copyright: Ankitects Pty Ltd and contributors Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script> <script lang="ts">
import "./index.scss"; import "./index.scss";
import { onMount } from "svelte"; import { onMount } from "svelte";
@ -10,13 +10,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import ReviewerBottom from "./reviewer-bottom/ReviewerBottom.svelte"; import ReviewerBottom from "./reviewer-bottom/ReviewerBottom.svelte";
import Reviewer from "./Reviewer.svelte"; import Reviewer from "./Reviewer.svelte";
import { _blockDefaultDragDropBehavior } from "../../reviewer"; import { _blockDefaultDragDropBehavior } from "../../reviewer";
import type { PageData } from "./$types";
export let data: PageData;
const state = new ReviewerState(); const state = new ReviewerState();
onMount(() => { onMount(() => {
updateNightMode(); updateNightMode();
globalThis.anki ??= {}; globalThis.anki ??= {};
globalThis.anki.changeReceived = () => state.showQuestion(null); globalThis.anki.changeReceived = () => state.showQuestion(null);
_blockDefaultDragDropBehavior(); _blockDefaultDragDropBehavior();
state.undoStatus = data.initialUndoStatus;
}); });
$: cardData = state.cardData; $: cardData = state.cardData;
$: flag = $cardData?.queue?.cards[0].card?.flags; $: flag = $cardData?.queue?.cards[0].card?.flags;

View file

@ -0,0 +1,9 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { getUndoStatus } from "@generated/backend";
import type { PageLoad } from "./$types";
export const load = (async () => {
const initialUndoStatus = await getUndoStatus({});
return { initialUndoStatus };
}) satisfies PageLoad;

View file

@ -1,5 +1,6 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { UndoStatus } from "@generated/anki/collection_pb";
import { import {
BuryOrSuspendCardsRequest_Mode, BuryOrSuspendCardsRequest_Mode,
CardAnswer, CardAnswer,
@ -59,6 +60,7 @@ export class ReviewerState {
tooltipMessageTimeout: ReturnType<typeof setTimeout> | undefined; tooltipMessageTimeout: ReturnType<typeof setTimeout> | undefined;
readonly tooltipMessage = writable(""); readonly tooltipMessage = writable("");
readonly tooltipShown = writable(false); readonly tooltipShown = writable(false);
undoStatus: UndoStatus | undefined = undefined;
iframe: HTMLIFrameElement | undefined = undefined; iframe: HTMLIFrameElement | undefined = undefined;
@ -222,12 +224,16 @@ export class ReviewerState {
} }
case "z": { case "z": {
if (ctrl) { if (ctrl) {
if (shift) { if (shift && this.undoStatus?.redo) {
const op = await redo({}); const op = await redo({});
this.showTooltip(tr.undoActionRedone({ action: op.operation })); this.showTooltip(tr.undoActionRedone({ action: op.operation }));
} else { this.undoStatus = op.newStatus;
} else if (this.undoStatus?.undo) {
const op = await undo({}); const op = await undo({});
this.showTooltip(tr.undoActionUndone({ action: op.operation })); this.showTooltip(tr.undoActionUndone({ action: op.operation }));
this.undoStatus = op.newStatus;
} else {
this.showTooltip(shift ? tr.actionsNothingToRedo() : tr.actionsNothingToUndo());
} }
this.refresh(); this.refresh();
} }
@ -261,6 +267,10 @@ export class ReviewerState {
} }
async showQuestion(answer: CardAnswer | null) { async showQuestion(answer: CardAnswer | null) {
if (answer !== null && this.undoStatus) {
this.undoStatus.undo = tr.actionsAnswerCard();
}
const resp = await nextCardData({ const resp = await nextCardData({
answer: answer || undefined, answer: answer || undefined,
}); });