diff --git a/qt/aqt/mediasrv.py b/qt/aqt/mediasrv.py index 898a05b25..aab4e58c0 100644 --- a/qt/aqt/mediasrv.py +++ b/qt/aqt/mediasrv.py @@ -763,6 +763,7 @@ exposed_backend_list = [ "get_retention_workload", # CardsService "set_flag", + "compare_answer", ] diff --git a/ts/routes/reviewer-inner/index.ts b/ts/routes/reviewer-inner/index.ts index dc32fac87..ba70ffde3 100644 --- a/ts/routes/reviewer-inner/index.ts +++ b/ts/routes/reviewer-inner/index.ts @@ -65,3 +65,14 @@ function pycmd(cmd: string) { } } globalThis.pycmd = pycmd; + +function _typeAnsPress() { + const elem = document.getElementById("typeans")! as HTMLInputElement; + let key = (window.event as KeyboardEvent).key; + key = key.length == 1 ? key : ""; + window.parent.postMessage( + { type: "typed", value: elem.value + key } satisfies ReviewerRequest, + "*", + ); +} +globalThis._typeAnsPress = _typeAnsPress; diff --git a/ts/routes/reviewer/reviewer.ts b/ts/routes/reviewer/reviewer.ts index 40149c457..1fa8e526a 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 { nextCardData, playAvtags } from "@generated/backend"; +import { compareAnswer, nextCardData, playAvtags } from "@generated/backend"; import { derived, get, writable } from "svelte/store"; import type { InnerReviewerRequest } from "../reviewer-inner/innerReviewerRequest"; import type { ReviewerRequest } from "./reviewerRequest"; @@ -25,6 +25,8 @@ export function updateNightMode() { } } +const typedAnswerRegex = /\[\[type:(.+?:)?(.+?)\]\]/m; + export class ReviewerState { answerHtml = ""; currentTypedAnswer = ""; @@ -125,12 +127,27 @@ export class ReviewerState { return this._cardData?.queue?.cards[0]; } - public showAnswer() { + async showTypedAnswer(html: string) { + if (!this._cardData?.typedAnswer) { + return html; + } + const compareAnswerResp = await compareAnswer({ + expected: this._cardData?.typedAnswer, + provided: this.currentTypedAnswer, + combining: false, + }); + const display = compareAnswerResp.val; + + console.log({ typedAnswerRegex, html, display }); + return html.replace(typedAnswerRegex, display); + } + + public async showAnswer() { this.answerShown.set(true); if (this._cardData?.autoplay) { playAvtags({ tags: this._cardData!.answerAvTags }); } - this.updateHtml(this._cardData?.back || ""); + this.updateHtml(await this.showTypedAnswer(this._cardData?.back || "")); } public easeButtonPressed(rating: number) {