Stats UI: per-anime progress rows, status chips, on-hold, streak, detail line

- server: /api/stats top_anime rows enriched — poster, total eps, cur_ep,
  last_seen, status (finished/ongoing/hold heuristic), pace (ep/day),
  sub/dub watch-time split, rewatches (backward jump >60s); new on_hold
  + best_streak top-level keys; optional ?slug= filter (json_extract)
- frontend: 'Most watched' rows = poster + meta + status chip + completion
  bar (ongoing -> hold -> finished order); stat cards swap in on-hold and
  best streak, errors demoted to a one-liner; anime detail page gets a
  progress line (E12/24 · 4h 30m · 2.1 ep/day · status); history cards
  dim + label 'on hold' after 7 days; savePos now includes total eps
- css: .chip, .stat-anime rows, .card.hold, .detail-prog; drop dead .stat-row
- test: test_stats asserts the new fields + slug filter
This commit is contained in:
jozamudi committed 2026-08-24 17:30:01 +00:00
1 parent 2f373b9bba
commit 1be3f4f307
4 files changed
+155 -41

No files matched your search

+14 -4
View File
@@ -58,10 +58,20 @@ h2 { margin: 0.4rem 0; }
.wk-col { display: flex; flex-direction: column; align-items: center; gap: .2rem; }
.wk-bar { width: 26px; background: var(--acc); border-radius: 4px; }
.wk-day { font-size: .7rem; color: var(--muted); }
.stat-row { display: grid; grid-template-columns: minmax(0, 1fr) auto 90px; gap: .8rem;
align-items: center; margin: .35rem 0; }
.stat-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-row .bar { margin-top: 0; }
.chip { font-size: .7rem; padding: .1rem .5rem; border-radius: 99px; border: 1px solid var(--bd);
color: var(--muted); white-space: nowrap; }
.chip.on { color: var(--acc); border-color: var(--acc); }
.chip.fin { background: var(--acc); border-color: var(--acc); color: #140b02; font-weight: 600; }
.stat-anime { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: .3rem .8rem;
align-items: center; padding: .55rem; background: var(--card); border: 1px solid var(--bd);
border-radius: 10px; margin: .55rem 0; }
.stat-anime img, .sa-ph { grid-row: span 2; width: 44px; aspect-ratio: 2/3; object-fit: cover;
border-radius: 6px; background: var(--bd); }
.sa-top { display: flex; gap: .8rem; align-items: baseline; min-width: 0; }
.sa-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-anime .bar { grid-column: 2 / 4; margin-top: 0; }
.card.hold { opacity: .55; }
.detail-prog { margin-top: .1rem; font-size: .85rem; }
.mini-info { display: flex; flex-direction: column; padding: .5rem; }
.mini-meta { font-size: .75rem; color: var(--muted); margin-top: .1rem; }
@media (max-width: 640px) {