mirror of
https://github.com/ankitects/anki.git
synced 2025-11-06 04:37:22 -05:00
Added: TypeAnswer replacement
This commit is contained in:
parent
cf9c265570
commit
bbf575e491
4 changed files with 50 additions and 3 deletions
|
|
@ -306,6 +306,7 @@ message NextCardDataResponse {
|
|||
string css = 5;
|
||||
string body_class = 6;
|
||||
bool autoplay = 7;
|
||||
optional string typed_answer = 12;
|
||||
|
||||
repeated card_rendering.AVTag question_av_tags = 8;
|
||||
repeated card_rendering.AVTag answer_av_tags = 9;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
mod answering;
|
||||
mod states;
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use anki_proto::cards;
|
||||
use anki_proto::generic;
|
||||
use anki_proto::scheduler;
|
||||
|
|
@ -25,6 +27,7 @@ use fsrs::ComputeParametersInput;
|
|||
use fsrs::FSRSItem;
|
||||
use fsrs::FSRSReview;
|
||||
use fsrs::FSRS;
|
||||
use regex::Regex;
|
||||
|
||||
use crate::backend::Backend;
|
||||
use crate::card_rendering::service::rendered_nodes_to_proto;
|
||||
|
|
@ -34,7 +37,9 @@ use crate::scheduler::new::NewCardDueOrder;
|
|||
use crate::scheduler::states::CardState;
|
||||
use crate::scheduler::states::SchedulingStates;
|
||||
use crate::search::SortMode;
|
||||
use crate::services::NotesService;
|
||||
use crate::stats::studied_today;
|
||||
use crate::template::RenderedNode;
|
||||
|
||||
impl crate::services::SchedulerService for Collection {
|
||||
/// This behaves like _updateCutoff() in older code - it also unburies at
|
||||
|
|
@ -411,16 +416,48 @@ impl crate::services::SchedulerService for Collection {
|
|||
|
||||
let config = self.deck_config_for_card(&next_card.card)?;
|
||||
|
||||
// Typed answer replacements
|
||||
static ANSWER_REGEX: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"\[\[type:(.+?:)?(.+?)\]\]").unwrap());
|
||||
|
||||
const ANSWER_HTML: &str = "<center>
|
||||
<input type=text id=typeans onkeypress=\"_typeAnsPress();\"
|
||||
style=\"font-family: '{self.typeFont}'; font-size: {self.typeSize}px;\">
|
||||
</center>";
|
||||
|
||||
let mut q_nodes = render.qnodes;
|
||||
let typed_answer_parent_node = q_nodes.iter_mut().find_map(|node| {
|
||||
if let RenderedNode::Text { text } = node {
|
||||
let mut out = None;
|
||||
*text = ANSWER_REGEX
|
||||
.replace(text, |cap: ®ex::Captures<'_>| {
|
||||
out = Some(cap[2].to_string());
|
||||
ANSWER_HTML
|
||||
})
|
||||
.to_string();
|
||||
out
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
let typed_answer = typed_answer_parent_node.map(|field| {
|
||||
let note = self.get_note(next_card.card.note_id.into()).unwrap();
|
||||
let notetype = self.get_notetype(note.notetype_id.into()).unwrap().unwrap();
|
||||
note.fields[notetype.get_field_ord(&field).unwrap()].clone()
|
||||
});
|
||||
|
||||
Ok(NextCardDataResponse {
|
||||
next_card: Some(NextCardData {
|
||||
queue: Some(queue.into()),
|
||||
|
||||
css: render.css.clone(),
|
||||
partial_front: rendered_nodes_to_proto(render.qnodes),
|
||||
partial_front: rendered_nodes_to_proto(q_nodes),
|
||||
partial_back: rendered_nodes_to_proto(render.anodes),
|
||||
|
||||
answer_buttons,
|
||||
autoplay: !config.inner.disable_autoplay,
|
||||
typed_answer,
|
||||
|
||||
// Filled by python
|
||||
front: "".to_string(),
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export function updateNightMode() {
|
|||
|
||||
export class ReviewerState {
|
||||
answerHtml = "";
|
||||
currentTypedAnswer = "";
|
||||
_cardData: NextCardDataResponse_NextCardData | undefined = undefined;
|
||||
beginAnsweringMs = Date.now();
|
||||
readonly cardClass = writable("");
|
||||
|
|
@ -42,13 +43,16 @@ export class ReviewerState {
|
|||
addEventListener("message", this.onMessage.bind(this));
|
||||
}
|
||||
|
||||
onMessage(e: MessageEvent<ReviewerRequest>) {
|
||||
async onMessage(e: MessageEvent<ReviewerRequest>) {
|
||||
switch (e.data.type) {
|
||||
case "audio": {
|
||||
const tags = get(this.answerShown) ? this._cardData!.answerAvTags : this._cardData!.questionAvTags;
|
||||
playAvtags({ tags: [tags[e.data.index]] });
|
||||
break;
|
||||
}
|
||||
case "typed": {
|
||||
this.currentTypedAnswer = e.data.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,4 +6,9 @@ interface AudioMessage {
|
|||
index: number;
|
||||
}
|
||||
|
||||
export type ReviewerRequest = AudioMessage;
|
||||
interface CompareTypedAnswerMessage {
|
||||
type: "typed";
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type ReviewerRequest = AudioMessage | CompareTypedAnswerMessage;
|
||||
|
|
|
|||
Loading…
Reference in a new issue