mirror of
https://github.com/ankitects/anki.git
synced 2025-11-06 12:47:11 -05:00
Added: NextCardData
This commit is contained in:
parent
b6e07f5780
commit
aa42d87558
4 changed files with 66 additions and 12 deletions
|
|
@ -17,6 +17,7 @@ import "anki/deck_config.proto";
|
|||
service SchedulerService {
|
||||
rpc GetQueuedCards(GetQueuedCardsRequest) returns (QueuedCards);
|
||||
rpc AnswerCard(CardAnswer) returns (collection.OpChanges);
|
||||
rpc NextCardData(NextCardDataRequest) returns (NextCardDataResponse);
|
||||
rpc SchedTimingToday(generic.Empty) returns (SchedTimingTodayResponse);
|
||||
rpc StudiedToday(generic.Empty) returns (generic.String);
|
||||
rpc StudiedTodayMessage(StudiedTodayMessageRequest) returns (generic.String);
|
||||
|
|
@ -285,6 +286,21 @@ message CardAnswer {
|
|||
uint32 milliseconds_taken = 6;
|
||||
}
|
||||
|
||||
message NextCardDataRequest {
|
||||
optional CardAnswer answer = 1;
|
||||
}
|
||||
|
||||
message NextCardDataResponse {
|
||||
message NextCardData {
|
||||
string front = 1;
|
||||
string back = 2;
|
||||
|
||||
SchedulingStates states = 3;
|
||||
}
|
||||
|
||||
optional NextCardData next_card = 1;
|
||||
}
|
||||
|
||||
message CustomStudyRequest {
|
||||
message Cram {
|
||||
enum CramKind {
|
||||
|
|
|
|||
|
|
@ -696,6 +696,7 @@ exposed_backend_list = [
|
|||
"get_optimal_retention_parameters",
|
||||
"simulate_fsrs_review",
|
||||
"simulate_fsrs_workload",
|
||||
"next_card_data",
|
||||
# DeckConfigService
|
||||
"get_ignored_before_count",
|
||||
"get_retention_workload",
|
||||
|
|
@ -719,7 +720,6 @@ post_handlers = {
|
|||
for handler in exposed_backend_list
|
||||
}
|
||||
|
||||
|
||||
def _extract_collection_post_request(path: str) -> DynamicRequest | NotFound:
|
||||
if not aqt.mw.col:
|
||||
return NotFound(message=f"collection not open, ignore request for {path}")
|
||||
|
|
@ -766,6 +766,8 @@ def _check_dynamic_request_permissions():
|
|||
"/_anki/setSchedulingStates",
|
||||
"/_anki/i18nResources",
|
||||
"/_anki/congratsInfo",
|
||||
# TODO: Unsure about this
|
||||
"/_anki/nextCardData"
|
||||
):
|
||||
pass
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ mod states;
|
|||
use anki_proto::cards;
|
||||
use anki_proto::generic;
|
||||
use anki_proto::scheduler;
|
||||
use anki_proto::scheduler::next_card_data_response::NextCardData;
|
||||
use anki_proto::scheduler::ComputeFsrsParamsResponse;
|
||||
use anki_proto::scheduler::ComputeMemoryStateResponse;
|
||||
use anki_proto::scheduler::ComputeOptimalRetentionResponse;
|
||||
|
|
@ -14,6 +15,8 @@ use anki_proto::scheduler::FsrsBenchmarkResponse;
|
|||
use anki_proto::scheduler::FuzzDeltaRequest;
|
||||
use anki_proto::scheduler::FuzzDeltaResponse;
|
||||
use anki_proto::scheduler::GetOptimalRetentionParametersResponse;
|
||||
use anki_proto::scheduler::NextCardDataRequest;
|
||||
use anki_proto::scheduler::NextCardDataResponse;
|
||||
use anki_proto::scheduler::SimulateFsrsReviewRequest;
|
||||
use anki_proto::scheduler::SimulateFsrsReviewResponse;
|
||||
use anki_proto::scheduler::SimulateFsrsWorkloadResponse;
|
||||
|
|
@ -382,6 +385,30 @@ impl crate::services::SchedulerService for Collection {
|
|||
delta_days: self.get_fuzz_delta(input.card_id.into(), input.interval)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn next_card_data(&mut self, req: NextCardDataRequest) -> Result<NextCardDataResponse> {
|
||||
if let Some(answer) = req.answer {
|
||||
self.answer_card(&mut answer.into())?;
|
||||
}
|
||||
let queue = self.get_queued_cards(1, false)?;
|
||||
let next_card = queue.cards.first();
|
||||
if let Some(next_card) = next_card {
|
||||
let cid = next_card.card.id;
|
||||
|
||||
let render = self.render_existing_card(cid, false, false)?;
|
||||
|
||||
Ok(NextCardDataResponse {
|
||||
next_card: Some(NextCardData {
|
||||
front: render.question().to_string(),
|
||||
back: render.answer().to_string(),
|
||||
|
||||
states: Some(next_card.states.clone().into()),
|
||||
}),
|
||||
})
|
||||
} else {
|
||||
Ok(NextCardDataResponse::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::services::BackendSchedulerService for Backend {
|
||||
|
|
|
|||
|
|
@ -1,29 +1,38 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import { CardAnswer, SchedulingStates } from "@generated/anki/scheduler_pb";
|
||||
import { nextCardData } from "@generated/backend";
|
||||
import { bridgeCommand } from "@tslib/bridgecommand";
|
||||
import { writable } from "svelte/store";
|
||||
import { preloadAnswerImages } from "../../reviewer/images";
|
||||
|
||||
export function setupReviewer(iframe: HTMLIFrameElement) {
|
||||
const cardClass = writable("");
|
||||
let answer_html = "";
|
||||
let states: SchedulingStates | undefined;
|
||||
|
||||
function updateHtml(htmlString) {
|
||||
iframe.contentWindow?.postMessage({ type: "html", value: htmlString }, "*");
|
||||
}
|
||||
|
||||
function showQuestion(q, a, cc) {
|
||||
updateHtml(q);
|
||||
// html.set(q);
|
||||
cardClass.set(cc);
|
||||
preloadAnswerImages(a);
|
||||
async function showQuestion(answer: CardAnswer | null) {
|
||||
let resp = await nextCardData({
|
||||
answer: answer || undefined,
|
||||
});
|
||||
// TODO: "Congratulation screen" logic
|
||||
const question = resp.nextCard?.front || "";
|
||||
answer_html = resp.nextCard?.back || "";
|
||||
states = resp.nextCard?.states;
|
||||
console.log({ resp });
|
||||
updateHtml(question);
|
||||
}
|
||||
|
||||
function showAnswer() {
|
||||
updateHtml(answer_html);
|
||||
}
|
||||
|
||||
function onReady() {
|
||||
// TODO This should probably be a "ready" command now that it is part of the actual reviewer,
|
||||
// Currently this depends on the reviewer component mounting after the bottom-reviewer which it should but seems hacky.
|
||||
// Maybe use a counter with a counter.subscribe($counter == 2 then call("ready"))
|
||||
bridgeCommand("bottomReady");
|
||||
iframe.contentWindow?.postMessage({ type: "nightMode", value: true }, "*");
|
||||
showQuestion(null);
|
||||
}
|
||||
|
||||
iframe?.addEventListener("load", onReady);
|
||||
|
|
@ -46,8 +55,8 @@ export function setupReviewer(iframe: HTMLIFrameElement) {
|
|||
}
|
||||
});
|
||||
|
||||
globalThis._showAnswer = updateHtml;
|
||||
globalThis._showQuestion = showQuestion;
|
||||
globalThis._showAnswer = showAnswer;
|
||||
|
||||
return { cardClass };
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue