mirror of
https://github.com/ankitects/anki.git
synced 2025-11-14 16:47:12 -05:00
* Only collect card stats on the backend ... ... instead of rendering an HTML string using askama. * Add ts page Card Info * Update test for new `col.card_stats()` * Remove obsolete CardStats code * Use new ts page in `CardInfoDialog` * Align start and end instead of left and right Curiously, `text-align: start` does not work for `th` tags if assigned via classes. * Adopt ts refactorings after rebase #1405 and #1409 * Clean up `ts/card-info/BUILD.bazel` * Port card info logic from Rust to TS * Move repeated field to the top https://github.com/ankitects/anki/pull/1414#discussion_r725402730 * Convert pseudo classes to interfaces * CardInfoPage -> CardInfo * Make revlog in card info optional * Add legacy support for old card stats * Check for undefined instead of falsy * Make Revlog separate component * drop askama dependency (dae) * Fix nightmode for legacy card stats
141 lines
4.1 KiB
Svelte
141 lines
4.1 KiB
Svelte
<!--
|
|
Copyright: Ankitects Pty Ltd and contributors
|
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
-->
|
|
<script lang="ts">
|
|
import * as tr2 from "../lib/ftl";
|
|
import { Stats } from "../lib/proto";
|
|
import { Timestamp, timeSpan } from "../lib/time";
|
|
|
|
export let stats: Stats.CardStatsResponse;
|
|
|
|
type IStatsRevlogEntry = Stats.CardStatsResponse.IStatsRevlogEntry;
|
|
|
|
function reviewKindClass(entry: IStatsRevlogEntry): string {
|
|
switch (entry.reviewKind) {
|
|
case Stats.RevlogEntry.ReviewKind.LEARNING:
|
|
return "revlog-learn";
|
|
case Stats.RevlogEntry.ReviewKind.REVIEW:
|
|
return "revlog-review";
|
|
case Stats.RevlogEntry.ReviewKind.RELEARNING:
|
|
return "revlog-relearn";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function reviewKindLabel(entry: IStatsRevlogEntry): string {
|
|
switch (entry.reviewKind) {
|
|
case Stats.RevlogEntry.ReviewKind.LEARNING:
|
|
return tr2.cardStatsReviewLogTypeLearn();
|
|
case Stats.RevlogEntry.ReviewKind.REVIEW:
|
|
return tr2.cardStatsReviewLogTypeReview();
|
|
case Stats.RevlogEntry.ReviewKind.RELEARNING:
|
|
return tr2.cardStatsReviewLogTypeRelearn();
|
|
case Stats.RevlogEntry.ReviewKind.FILTERED:
|
|
return tr2.cardStatsReviewLogTypeFiltered();
|
|
case Stats.RevlogEntry.ReviewKind.MANUAL:
|
|
return tr2.cardStatsReviewLogTypeManual();
|
|
}
|
|
}
|
|
|
|
function ratingClass(entry: IStatsRevlogEntry): string {
|
|
if (entry.buttonChosen === 1) {
|
|
return "revlog-ease1";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
interface RevlogRow {
|
|
date: string;
|
|
time: string;
|
|
reviewKind: string;
|
|
reviewKindClass: string;
|
|
rating: number;
|
|
ratingClass: string;
|
|
interval: string;
|
|
ease: string;
|
|
takenSecs: string;
|
|
}
|
|
|
|
function revlogRowFromEntry(entry: IStatsRevlogEntry): RevlogRow {
|
|
const timestamp = new Timestamp(entry.time!);
|
|
return {
|
|
date: timestamp.dateString(),
|
|
time: timestamp.timeString(),
|
|
reviewKind: reviewKindLabel(entry),
|
|
reviewKindClass: reviewKindClass(entry),
|
|
rating: entry.buttonChosen!,
|
|
ratingClass: ratingClass(entry),
|
|
interval: timeSpan(entry.interval!),
|
|
ease: entry.ease ? `${entry.ease / 10}%` : "",
|
|
takenSecs: timeSpan(entry.takenSecs!, true),
|
|
};
|
|
}
|
|
|
|
const revlogRows: RevlogRow[] = stats.revlog.map((entry) =>
|
|
revlogRowFromEntry(entry)
|
|
);
|
|
</script>
|
|
|
|
{#if stats.revlog.length}
|
|
<div class="revlog-container">
|
|
<table class="revlog-table">
|
|
<tr>
|
|
<th>{tr2.cardStatsReviewLogDate()}</th>
|
|
<th>{tr2.cardStatsReviewLogType()}</th>
|
|
<th>{tr2.cardStatsReviewLogRating()}</th>
|
|
<th>{tr2.cardStatsInterval()}</th>
|
|
<th>{tr2.cardStatsEase()}</th>
|
|
<th>{tr2.cardStatsReviewLogTimeTaken()}</th>
|
|
</tr>
|
|
{#each revlogRows as row, _index}
|
|
<tr>
|
|
<td class="left"><b>{row.date}</b> @ {row.time}</td>
|
|
<td class="center {row.reviewKindClass}">
|
|
{row.reviewKind}
|
|
</td>
|
|
<td class="center {row.ratingClass}">{row.rating}</td>
|
|
<td class="center">{row.interval}</td>
|
|
<td class="center">{row.ease}</td>
|
|
<td class="right">{row.takenSecs}</td>
|
|
</tr>
|
|
{/each}
|
|
</table>
|
|
</div>
|
|
{/if}
|
|
|
|
<style>
|
|
.left {
|
|
text-align: start;
|
|
}
|
|
|
|
.right {
|
|
text-align: end;
|
|
}
|
|
|
|
.center {
|
|
text-align: center;
|
|
}
|
|
|
|
.revlog-container {
|
|
margin: 4em -2em 0 -2em;
|
|
}
|
|
|
|
.revlog-table {
|
|
width: 100%;
|
|
border-spacing: 2em 0em;
|
|
}
|
|
|
|
.revlog-learn {
|
|
color: var(--new-count);
|
|
}
|
|
|
|
.revlog-review {
|
|
color: var(--review-count);
|
|
}
|
|
|
|
.revlog-relearn,
|
|
.revlog-ease1 {
|
|
color: var(--learn-count);
|
|
}
|
|
</style>
|