mirror of
https://github.com/ankitects/anki.git
synced 2026-01-09 03:53:55 -05:00
Added: AutoAdvance
This commit is contained in:
parent
f3324b4a29
commit
549c58f3f3
4 changed files with 88 additions and 10 deletions
|
|
@ -327,6 +327,13 @@ message NextCardDataResponse {
|
||||||
repeated card_rendering.AVTag question_av_tags = 8;
|
repeated card_rendering.AVTag question_av_tags = 8;
|
||||||
repeated card_rendering.AVTag answer_av_tags = 9;
|
repeated card_rendering.AVTag answer_av_tags = 9;
|
||||||
|
|
||||||
|
float autoAdvanceQuestionSeconds = 16;
|
||||||
|
float autoAdvanceAnswerSeconds = 17;
|
||||||
|
bool autoAdvanceWaitForAudio = 20;
|
||||||
|
|
||||||
|
deck_config.DeckConfig.Config.QuestionAction autoAdvanceQuestionAction = 18;
|
||||||
|
deck_config.DeckConfig.Config.AnswerAction autoAdvanceAnswerAction = 19;
|
||||||
|
|
||||||
// TODO: We can probably make this a little faster by using oneof and
|
// TODO: We can probably make this a little faster by using oneof and
|
||||||
// preventing the partial_front and back being sent to svelte where it isn't
|
// preventing the partial_front and back being sent to svelte where it isn't
|
||||||
// used. Alternatively we can use a completely different message for both
|
// used. Alternatively we can use a completely different message for both
|
||||||
|
|
|
||||||
|
|
@ -500,6 +500,13 @@ impl crate::services::SchedulerService for Collection {
|
||||||
marked,
|
marked,
|
||||||
timer,
|
timer,
|
||||||
|
|
||||||
|
auto_advance_answer_seconds: deck_config.seconds_to_show_answer,
|
||||||
|
auto_advance_question_seconds: deck_config.seconds_to_show_question,
|
||||||
|
auto_advance_wait_for_audio: deck_config.wait_for_audio,
|
||||||
|
|
||||||
|
auto_advance_answer_action: deck_config.answer_action,
|
||||||
|
auto_advance_question_action: deck_config.question_action,
|
||||||
|
|
||||||
// Filled by python
|
// Filled by python
|
||||||
accept_enter: true,
|
accept_enter: true,
|
||||||
front: "".to_string(),
|
front: "".to_string(),
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
{ colour: tr.actionsFlagPurple(), shortcut: "Ctrl+7" },
|
{ colour: tr.actionsFlagPurple(), shortcut: "Ctrl+7" },
|
||||||
];
|
];
|
||||||
|
|
||||||
function todo() {
|
|
||||||
alert("Not yet implemented in new reviewer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const shortcuts: MoreMenuItemInfo[] = [
|
const shortcuts: MoreMenuItemInfo[] = [
|
||||||
{
|
{
|
||||||
name: tr.studyingBuryCard(),
|
name: tr.studyingBuryCard(),
|
||||||
|
|
@ -128,11 +124,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
{
|
{
|
||||||
name: tr.actionsAutoAdvance(),
|
name: tr.actionsAutoAdvance(),
|
||||||
shortcut: "Shift+A",
|
shortcut: "Shift+A",
|
||||||
onClick: todo /* checked: autoAdvanceEnabled */,
|
onClick: () => state.toggleAutoAdvance(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
$: current_flag = state.flag;
|
$: current_flag = state.flag;
|
||||||
|
// TOOD: Fix above capitals
|
||||||
|
$: autoAdvance = state.autoAdvance;
|
||||||
|
|
||||||
function prepKeycodeForShortcut(keycode: string) {
|
function prepKeycodeForShortcut(keycode: string) {
|
||||||
return keycode.replace("Ctrl", "Control");
|
return keycode.replace("Ctrl", "Control");
|
||||||
|
|
@ -212,11 +210,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
{#if shortcut == "hr"}
|
{#if shortcut == "hr"}
|
||||||
<hr />
|
<hr />
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
{@const highlighted = shortcut.shortcut == "Shift+A" && $autoAdvance}
|
||||||
style:background-color={shortcut.onClick == todo
|
<div style:background-color={highlighted ? "RGBA(0,255,0,0.25)" : ""}>
|
||||||
? "RGBA(255,0,0,0.25)"
|
|
||||||
: ""}
|
|
||||||
>
|
|
||||||
<MoreItem
|
<MoreItem
|
||||||
shortcut={shortcut.shortcut}
|
shortcut={shortcut.shortcut}
|
||||||
on:click={shortcut.onClick}
|
on:click={shortcut.onClick}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,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
|
||||||
import type { UndoStatus } from "@generated/anki/collection_pb";
|
import type { UndoStatus } from "@generated/anki/collection_pb";
|
||||||
|
import { DeckConfig_Config_AnswerAction, DeckConfig_Config_QuestionAction } from "@generated/anki/deck_config_pb";
|
||||||
import { ReviewerActionRequest_ReviewerAction } from "@generated/anki/frontend_pb";
|
import { ReviewerActionRequest_ReviewerAction } from "@generated/anki/frontend_pb";
|
||||||
import {
|
import {
|
||||||
BuryOrSuspendCardsRequest_Mode,
|
BuryOrSuspendCardsRequest_Mode,
|
||||||
|
|
@ -64,10 +65,35 @@ export class ReviewerState {
|
||||||
readonly tooltipShown = writable(false);
|
readonly tooltipShown = writable(false);
|
||||||
readonly flag = writable(0);
|
readonly flag = writable(0);
|
||||||
readonly marked = writable(false);
|
readonly marked = writable(false);
|
||||||
|
readonly autoAdvance = writable(false);
|
||||||
undoStatus: UndoStatus | undefined = undefined;
|
undoStatus: UndoStatus | undefined = undefined;
|
||||||
|
autoAdvanceQuestionTimeout: ReturnType<typeof setTimeout> | undefined;
|
||||||
|
autoAdvanceAnswerTimeout: ReturnType<typeof setTimeout> | undefined;
|
||||||
|
|
||||||
iframe: HTMLIFrameElement | undefined = undefined;
|
iframe: HTMLIFrameElement | undefined = undefined;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.autoAdvance.subscribe($autoAdvance => {
|
||||||
|
if (this._answerShown) {
|
||||||
|
this.updateAutoAdvanceAnswer();
|
||||||
|
} else {
|
||||||
|
this.updateAutoAdvanceQuestion();
|
||||||
|
}
|
||||||
|
if (!$autoAdvance) {
|
||||||
|
clearInterval(this.autoAdvanceQuestionTimeout);
|
||||||
|
clearInterval(this.autoAdvanceAnswerTimeout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleAutoAdvance() {
|
||||||
|
this.autoAdvance.update(($autoAdvance) => {
|
||||||
|
// Reversed because the $autoAdvance will be flipped by the return.
|
||||||
|
this.showTooltip($autoAdvance ? tr.actionsAutoAdvanceDeactivated() : tr.actionsAutoAdvanceActivated());
|
||||||
|
return !$autoAdvance;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async onReady() {
|
async onReady() {
|
||||||
const { json } = await getConfigJson({ val: "reviewerStorage" });
|
const { json } = await getConfigJson({ val: "reviewerStorage" });
|
||||||
this.sendInnerRequest({ type: "setstorage", json_buffer: json });
|
this.sendInnerRequest({ type: "setstorage", json_buffer: json });
|
||||||
|
|
@ -323,6 +349,47 @@ export class ReviewerState {
|
||||||
this.sendInnerRequest({ type: "html", value: htmlString, css, bodyclass });
|
this.sendInnerRequest({ type: "html", value: htmlString, css, bodyclass });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateAutoAdvanceQuestion() {
|
||||||
|
clearTimeout(this.autoAdvanceAnswerTimeout);
|
||||||
|
if (get(this.autoAdvance) && this._cardData!.autoAdvanceQuestionSeconds) {
|
||||||
|
const action = ({
|
||||||
|
[DeckConfig_Config_QuestionAction.SHOW_ANSWER]: () => {
|
||||||
|
this.showAnswer();
|
||||||
|
},
|
||||||
|
[DeckConfig_Config_QuestionAction.SHOW_REMINDER]: () => {
|
||||||
|
this.showTooltip(tr.studyingQuestionTimeElapsed());
|
||||||
|
},
|
||||||
|
})[this._cardData!.autoAdvanceQuestionAction];
|
||||||
|
|
||||||
|
this.autoAdvanceQuestionTimeout = setTimeout(action, this._cardData!.autoAdvanceQuestionSeconds * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAutoAdvanceAnswer() {
|
||||||
|
clearTimeout(this.autoAdvanceQuestionTimeout);
|
||||||
|
if (get(this.autoAdvance) && this._cardData?.autoAdvanceAnswerSeconds) {
|
||||||
|
const action = ({
|
||||||
|
[DeckConfig_Config_AnswerAction.ANSWER_AGAIN]: () => {
|
||||||
|
this.easeButtonPressed(0);
|
||||||
|
},
|
||||||
|
[DeckConfig_Config_AnswerAction.ANSWER_HARD]: () => {
|
||||||
|
this.easeButtonPressed(1);
|
||||||
|
},
|
||||||
|
[DeckConfig_Config_AnswerAction.ANSWER_GOOD]: () => {
|
||||||
|
this.easeButtonPressed(2);
|
||||||
|
},
|
||||||
|
[DeckConfig_Config_AnswerAction.BURY_CARD]: () => {
|
||||||
|
this.buryOrSuspendCurrentCard(false);
|
||||||
|
},
|
||||||
|
[DeckConfig_Config_AnswerAction.SHOW_REMINDER]: () => {
|
||||||
|
this.showTooltip(tr.studyingAnswerTimeElapsed());
|
||||||
|
},
|
||||||
|
})[this._cardData.autoAdvanceAnswerAction];
|
||||||
|
|
||||||
|
this.autoAdvanceAnswerTimeout = setTimeout(action, this._cardData.autoAdvanceAnswerSeconds * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async showQuestion(answer: CardAnswer | null) {
|
async showQuestion(answer: CardAnswer | null) {
|
||||||
if (answer !== null) {
|
if (answer !== null) {
|
||||||
this.setUndo(tr.actionsAnswerCard());
|
this.setUndo(tr.actionsAnswerCard());
|
||||||
|
|
@ -352,6 +419,7 @@ export class ReviewerState {
|
||||||
|
|
||||||
this.beginAnsweringMs = Date.now();
|
this.beginAnsweringMs = Date.now();
|
||||||
this.answerMs = undefined;
|
this.answerMs = undefined;
|
||||||
|
this.updateAutoAdvanceQuestion();
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentCard() {
|
get currentCard() {
|
||||||
|
|
@ -382,6 +450,7 @@ export class ReviewerState {
|
||||||
}
|
}
|
||||||
this.answerMs = Date.now();
|
this.answerMs = Date.now();
|
||||||
this.updateHtml(await this.showTypedAnswer(this._cardData?.back || ""));
|
this.updateHtml(await this.showTypedAnswer(this._cardData?.back || ""));
|
||||||
|
this.updateAutoAdvanceAnswer();
|
||||||
}
|
}
|
||||||
|
|
||||||
get _answerShown() {
|
get _answerShown() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue