fix(subtitle): restore known and JLPT token annotations

This commit is contained in:
2026-03-19 18:03:20 -07:00
parent 1b5f0c6999
commit 43a0d11446
16 changed files with 258 additions and 43 deletions

View File

@@ -82,6 +82,10 @@ export function EpisodeList({
ep.totalYomitanLookupCount,
ep.totalTokensSeen,
);
const progressPct =
ep.durationMs > 0 && ep.endedMediaMs != null
? Math.min(100, Math.round((ep.endedMediaMs / ep.durationMs) * 100))
: null;
return (
<Fragment key={ep.videoId}>
@@ -99,17 +103,17 @@ export function EpisodeList({
{ep.canonicalTitle}
</td>
<td className="py-2 pr-3 text-right">
{ep.durationMs > 0 ? (
{progressPct != null ? (
<span
className={
ep.totalActiveMs >= ep.durationMs * 0.85
progressPct >= 85
? 'text-ctp-green'
: ep.totalActiveMs >= ep.durationMs * 0.5
: progressPct >= 50
? 'text-ctp-peach'
: 'text-ctp-overlay2'
}
>
{Math.min(100, Math.round((ep.totalActiveMs / ep.durationMs) * 100))}%
{progressPct}%
</span>
) : (
<span className="text-ctp-overlay2">{'\u2014'}</span>

View File

@@ -21,6 +21,7 @@ test('EpisodeList renders explicit episode detail button alongside quick peek ro
episode: 9,
season: 1,
durationMs: 1,
endedMediaMs: null,
watched: 0,
canonicalTitle: 'Episode 9',
totalSessions: 1,

View File

@@ -87,11 +87,12 @@ test('EpisodeList renders per-episode Yomitan lookup rate', () => {
videoId: 9,
episode: 9,
season: 1,
durationMs: 1,
durationMs: 100,
endedMediaMs: 6,
watched: 0,
canonicalTitle: 'Episode 9',
totalSessions: 1,
totalActiveMs: 1,
totalActiveMs: 90,
totalCards: 1,
totalTokensSeen: 350,
totalYomitanLookupCount: 7,
@@ -103,6 +104,8 @@ test('EpisodeList renders per-episode Yomitan lookup rate', () => {
assert.match(markup, /Lookup Rate/);
assert.match(markup, /2\.0 \/ 100 tokens/);
assert.match(markup, /6%/);
assert.doesNotMatch(markup, /90%/);
});
test('AnimeOverviewStats renders aggregate Yomitan lookup metrics', () => {

View File

@@ -212,6 +212,7 @@ export interface AnimeEpisode {
episode: number | null;
season: number | null;
durationMs: number;
endedMediaMs: number | null;
watched: number;
canonicalTitle: string;
totalSessions: number;