mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Added: Remaining
This commit is contained in:
parent
7e92c40169
commit
992c8ad731
4 changed files with 114 additions and 75 deletions
|
@ -259,8 +259,6 @@ class Reviewer:
|
||||||
if self._reps is None:
|
if self._reps is None:
|
||||||
self._initWeb()
|
self._initWeb()
|
||||||
|
|
||||||
self._showQuestion()
|
|
||||||
|
|
||||||
def _get_next_v3_card(self) -> None:
|
def _get_next_v3_card(self) -> None:
|
||||||
assert isinstance(self.mw.col.sched, V3Scheduler)
|
assert isinstance(self.mw.col.sched, V3Scheduler)
|
||||||
output = self.mw.col.sched.get_queued_cards()
|
output = self.mw.col.sched.get_queued_cards()
|
||||||
|
@ -676,6 +674,9 @@ class Reviewer:
|
||||||
self.mw.onEditCurrent()
|
self.mw.onEditCurrent()
|
||||||
elif url == "more":
|
elif url == "more":
|
||||||
self.showContextMenu()
|
self.showContextMenu()
|
||||||
|
elif url == "bottomReady":
|
||||||
|
self._showQuestion()
|
||||||
|
self._remaining()
|
||||||
elif url.startswith("play:"):
|
elif url.startswith("play:"):
|
||||||
play_clicked_audio(url, self.card)
|
play_clicked_audio(url, self.card)
|
||||||
elif url.startswith("updateToolbar"):
|
elif url.startswith("updateToolbar"):
|
||||||
|
@ -866,15 +867,8 @@ timerStopped = false;
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
counts: list[int | str]
|
counts: list[int | str]
|
||||||
idx, counts_ = self._v3.counts()
|
idx, counts = self._v3.counts()
|
||||||
counts = cast(list[Union[int, str]], counts_)
|
self.bottom.web.eval(f"_updateRemaining({json.dumps(counts)},{idx})")
|
||||||
counts[idx] = f"<u>{counts[idx]}</u>"
|
|
||||||
|
|
||||||
return f"""
|
|
||||||
<span class=new-count>{counts[0]}</span> +
|
|
||||||
<span class=learn-count>{counts[1]}</span> +
|
|
||||||
<span class=review-count>{counts[2]}</span>
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _defaultEase(self) -> Literal[2, 3]:
|
def _defaultEase(self) -> Literal[2, 3]:
|
||||||
return 3
|
return 3
|
||||||
|
|
|
@ -1,69 +1,85 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
import { bridgeCommand } from "@tslib/bridgecommand";
|
||||||
import ReviewerBottom from "./ReviewerBottom.svelte";
|
import ReviewerBottom from "./ReviewerBottom.svelte";
|
||||||
import "./index.scss"
|
import "./index.scss"
|
||||||
|
|
||||||
let timerStopped = false;
|
globalThis.answerButtons = writable<AnswerButtonInfo[]>([])
|
||||||
|
globalThis.remaining = writable<[number, number, number]>([0, 0, 0])
|
||||||
|
globalThis.remainingIndex = writable<number>(-1)
|
||||||
|
|
||||||
let maxTime = 0;
|
onMount(() => {
|
||||||
|
let timerStopped = false;
|
||||||
|
|
||||||
function updateTime(): void {
|
let maxTime = 0;
|
||||||
const timeNode = document.getElementById("time");
|
|
||||||
if (maxTime === 0) {
|
|
||||||
timeNode.textContent = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
globalThis.time = Math.min(maxTime, globalThis.time);
|
|
||||||
const m = Math.floor(globalThis.time / 60);
|
|
||||||
const s = globalThis.time % 60;
|
|
||||||
const sStr = String(s).padStart(2, "0");
|
|
||||||
const timeString = `${m}:${sStr}`;
|
|
||||||
|
|
||||||
if (maxTime === time) {
|
function updateTime(): void {
|
||||||
timeNode.innerHTML = `<font color=red>${timeString}</font>`;
|
const timeNode = document.getElementById("time");
|
||||||
} else {
|
if (maxTime === 0) {
|
||||||
timeNode.textContent = timeString;
|
timeNode.textContent = "";
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
let intervalId: number | undefined;
|
|
||||||
let answerButtons = writable<AnswerButtonInfo[]>([])
|
|
||||||
|
|
||||||
function _showQuestion(txt: string, maxTime_: number): void {
|
|
||||||
_showAnswer([]);
|
|
||||||
globalThis.time = 0;
|
|
||||||
maxTime = maxTime_;
|
|
||||||
// updateTime();
|
|
||||||
|
|
||||||
if (intervalId !== undefined) {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
}
|
|
||||||
|
|
||||||
intervalId = setInterval(function() {
|
|
||||||
if (!timerStopped) {
|
|
||||||
globalThis.time += 1;
|
|
||||||
//updateTime();
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
globalThis.time = Math.min(maxTime, globalThis.time);
|
||||||
}
|
const m = Math.floor(globalThis.time / 60);
|
||||||
|
const s = globalThis.time % 60;
|
||||||
|
const sStr = String(s).padStart(2, "0");
|
||||||
|
const timeString = `${m}:${sStr}`;
|
||||||
|
|
||||||
function _showAnswer(info: AnswerButtonInfo[], stopTimer = false): void {
|
if (maxTime === time) {
|
||||||
console.log(info)
|
timeNode.innerHTML = `<font color=red>${timeString}</font>`;
|
||||||
answerButtons.set(info);
|
} else {
|
||||||
timerStopped = stopTimer;
|
timeNode.textContent = timeString;
|
||||||
}
|
}
|
||||||
|
|
||||||
globalThis._showQuestion = _showQuestion;
|
|
||||||
globalThis._showAnswer = _showAnswer;
|
|
||||||
|
|
||||||
function selectedAnswerButton(): string | undefined {
|
|
||||||
const node = document.activeElement as HTMLElement;
|
|
||||||
if (!node) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
return node.dataset.ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let intervalId: number | undefined;
|
||||||
|
|
||||||
|
|
||||||
|
function _showQuestion(txt: string, maxTime_: number): void {
|
||||||
|
_showAnswer([]);
|
||||||
|
globalThis.time = 0;
|
||||||
|
maxTime = maxTime_;
|
||||||
|
// updateTime();
|
||||||
|
|
||||||
|
if (intervalId !== undefined) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
intervalId = setInterval(function() {
|
||||||
|
if (!timerStopped) {
|
||||||
|
globalThis.time += 1;
|
||||||
|
//updateTime();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _showAnswer(info: AnswerButtonInfo[], stopTimer = false): void {
|
||||||
|
console.log(info)
|
||||||
|
globalThis.answerButtons.set(info);
|
||||||
|
timerStopped = stopTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _updateRemaining(counts: [number, number, number], idx: number) {
|
||||||
|
globalThis.remaining.set(counts)
|
||||||
|
globalThis.remainingIndex.set(idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
globalThis._showQuestion = _showQuestion;
|
||||||
|
globalThis._showAnswer = _showAnswer;
|
||||||
|
globalThis._updateRemaining = _updateRemaining;
|
||||||
|
|
||||||
|
function selectedAnswerButton(): string | undefined {
|
||||||
|
const node = document.activeElement as HTMLElement;
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return node.dataset.ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
bridgeCommand("bottomReady");
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ReviewerBottom {answerButtons}></ReviewerBottom>
|
|
||||||
|
<ReviewerBottom answerButtons={globalThis.answerButtons} remaining={globalThis.remaining} remainingIndex={globalThis.remainingIndex}></ReviewerBottom>
|
12
ts/routes/reviewer-bottom/RemainingNumber.svelte
Normal file
12
ts/routes/reviewer-bottom/RemainingNumber.svelte
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let underlined: boolean
|
||||||
|
export let cls: string
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span class={cls}>
|
||||||
|
{#if underlined}
|
||||||
|
<u><slot/></u>
|
||||||
|
{:else}
|
||||||
|
<slot/>
|
||||||
|
{/if}
|
||||||
|
</span>
|
|
@ -3,9 +3,13 @@
|
||||||
import AnswerButton from "./AnswerButton.svelte";
|
import AnswerButton from "./AnswerButton.svelte";
|
||||||
import { bridgeCommand } from "@tslib/bridgecommand";
|
import { bridgeCommand } from "@tslib/bridgecommand";
|
||||||
import * as tr from "@generated/ftl";
|
import * as tr from "@generated/ftl";
|
||||||
|
import RemainingNumber from "./RemainingNumber.svelte";
|
||||||
|
|
||||||
export let answerButtons: Writable<AnswerButtonInfo[]>
|
export let answerButtons: Writable<AnswerButtonInfo[]>
|
||||||
$: console.log($answerButtons)
|
export let remaining: Writable<number[]>
|
||||||
|
export let remainingIndex: Writable<number>
|
||||||
|
|
||||||
|
$: console.log($remaining)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="outer fancy">
|
<div id="outer fancy">
|
||||||
|
@ -13,14 +17,21 @@
|
||||||
<div>
|
<div>
|
||||||
<button title={tr.actionsShortcutKey({val: "E"})} on:click={()=>bridgeCommand("edit")}>{tr.studyingEdit()}</button>
|
<button title={tr.actionsShortcutKey({val: "E"})} on:click={()=>bridgeCommand("edit")}>{tr.studyingEdit()}</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="review-buttons">
|
||||||
{#if $answerButtons.length}
|
<span>
|
||||||
{#each $answerButtons as answerButton}
|
<RemainingNumber cls="new-count" underlined={$remainingIndex === 0}>{$remaining[0]}</RemainingNumber> +
|
||||||
<AnswerButton info={answerButton}></AnswerButton>
|
<RemainingNumber cls="learn-count" underlined={$remainingIndex === 1}>{$remaining[1]}</RemainingNumber> +
|
||||||
{/each}
|
<RemainingNumber cls="review-count" underlined={$remainingIndex === 2}>{$remaining[2]}</RemainingNumber>
|
||||||
{:else}
|
</span>
|
||||||
<button on:click={()=>bridgeCommand("ans")}>{tr.studyingShowAnswer()}</button>
|
<div>
|
||||||
{/if}
|
{#if $answerButtons.length}
|
||||||
|
{#each $answerButtons as answerButton}
|
||||||
|
<AnswerButton info={answerButton}></AnswerButton>
|
||||||
|
{/each}
|
||||||
|
{:else}
|
||||||
|
<button on:click={()=>bridgeCommand("ans")}>{tr.studyingShowAnswer()}</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button on:click={()=>bridgeCommand("more")} title={tr.actionsShortcutKey({val: "M"})}>{tr.studyingMore()}↧</button>
|
<button on:click={()=>bridgeCommand("more")} title={tr.actionsShortcutKey({val: "M"})}>{tr.studyingMore()}↧</button>
|
||||||
|
@ -35,4 +46,10 @@
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: auto 1fr auto;
|
||||||
justify-items: center;
|
justify-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.review-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue