Commit Graph

15 Commits

Author SHA1 Message Date
51b38f615d refactor(stats): replace animePerDay type with librarySummary 2026-04-09 22:19:29 -07:00
70d52248f8 fix(stats): address CodeRabbit review on PR #50
- Guard episode deletion against double-submit with an isDeletingRef +
  setIsDeleting pair threaded through buildDeleteEpisodeHandler, and
  disable the MediaHeader delete button while a request is in flight.
- Restore MediaHeader title truncation by adding min-w-0 flex-1 to the
  h2 so long titles shrink instead of pushing the delete button away.
- Normalize the headword in FrequencyRankTable before comparing it to
  the (hiragana-normalized) reading so katakana-only entries like カレー
  no longer render a redundant 【かれー】. Test strengthened to reject
  any bracketed reading, not just the literal.
- Rewrite confirmBucketDelete copy to include the "and all associated
  data" warning and handle singular/plural cleanly.
- Run Prettier across the stats files CI was complaining about
  (EpisodeDetail, WatchTimeChart, SessionsTab + test, FrequencyRankTable
  + test, session-grouping test) to clear the format:check:stats gate.
2026-04-09 21:48:43 -07:00
42cc35dcd6 feat(stats): drop seek markers from session timeline
Seek-forward / seek-backward events cluttered sessions with lots of
rewinds — a single episode could show dozens of << and >> icons
overlapping the card and pause markers. Stop requesting them from the
backend, drop them from buildSessionChartEvents, remove the seek
variant from SessionChartMarker, and strip the matching ReferenceLines,
overlay marker, popover branch, and legend entry from SessionDetail.
2026-04-09 21:28:20 -07:00
c5e778d7d2 feat(stats): use generic title wording for mixed-source library
The stats dashboard now supports both anime series and YouTube videos
in the same library, so the anime-only copy no longer fits. Rename
user-visible labels ("Active Anime", "Search anime…", "Anime — Per
Day", "Episodes per Anime", "Words In Multiple Anime", etc.) to use
"Title"/"Library" wording that covers either source.

Data-model names (animeId, animeCount, useAnimeLibrary) stay as-is;
this pass only touches strings the user actually reads.
2026-04-09 01:55:49 -07:00
b1acbae580 refactor(stats): drop unused LibraryTab and useMediaLibrary
The live "Library" tab renders AnimeTab via App.tsx; LibraryTab and its
useMediaLibrary hook were never wired in. Remove them so the dead code
doesn't mislead readers, and drop the collapsible-library-group item
from the feedback-pass changelog since it targeted dead code.
2026-04-09 01:55:37 -07:00
b080add6ce feat(stats): unify chart theme and add gridlines for legibility 2026-04-09 01:24:48 -07:00
b4aea0f77e feat(stats): roll up same-episode sessions within a day
Group sessions for the same video inside each day header so repeated
viewings of an episode collapse into a single expandable bucket with
aggregate active time and card counts. Multi-session buckets get a
dedicated delete action that wipes every session in the group via the
bulk delete endpoint; singleton buckets continue to render the existing
SessionRow flow unchanged.

Delete confirmation copy lives in delete-confirm for parity with the
other bulk-delete flows, and the bucket delete path is extracted into a
pure buildBucketDeleteHandler factory so it can be unit-tested without
rendering the tab. MediaSessionList is intentionally untouched -- it is
already scoped to a single video and doesn't need rollup.
2026-04-09 01:19:30 -07:00
6dcf7d9234 feat(stats): add groupSessionsByVideo helper for episode rollups
Pure TS helper that buckets SessionSummary[] by videoId for the
Sessions tab collapsible UI (Task 8). Null videoIds become singleton
buckets keyed by sessionId. Covered by 4 node:test cases.
2026-04-09 01:09:49 -07:00
cfb2396791 feat(stats): collapsible series groups in library tab 2026-04-09 01:07:25 -07:00
8e25e19cac feat(stats): delete episode from library detail view
Add Delete Episode button to MediaDetailView/MediaHeader; extract
buildDeleteEpisodeHandler for testability. Add refresh() to
useMediaLibrary (version-bump pattern) and call it in LibraryTab's
onBack so the list reloads after a delete.
2026-04-09 01:01:13 -07:00
20976d63f0 fix(stats): hide cards deleted from Anki in episode detail
Filters out noteIds whose Anki note no longer exists, drops card events
that have no surviving noteIds, and shows a muted footer counting hidden
cards. Loading-state guard (noteInfosLoaded) prevents premature filtering
before ankiNotesInfo resolves.
2026-04-09 00:53:39 -07:00
c1bc92f254 fix(stats): collapse word and reading into one column in Top 50 table 2026-04-09 00:48:15 -07:00
364f7aacb7 feat(stats): expose 365d trends range in dashboard UI
Add '365d' to the client TrendRange union, the TimeRange hook type, and
the DateRangeSelector segmented control so users can select a 365-day
window in the trends dashboard.
2026-04-09 00:44:31 -07:00
5feed360ca feat: add app-owned YouTube subtitle flow with absPlayer-style parsing (#31)
* fix: harden preload argv parsing for popup windows

* fix: align youtube playback with shared overlay startup

* fix: unwrap mpv youtube streams for anki media mining

* docs: update docs for youtube subtitle and mining flow

* refactor: unify cli and runtime wiring for startup and youtube flow

* feat: update subtitle sidebar overlay behavior

* chore: add shared log-file source for diagnostics

* fix(ci): add changelog fragment for immersion changes

* fix: address CodeRabbit review feedback

* fix: persist canonical title from youtube metadata

* style: format stats library tab

* fix: address latest review feedback

* style: format stats library files

* test: stub launcher youtube deps in CI

* test: isolate launcher youtube flow deps

* test: stub launcher youtube deps in failing case

* test: force x11 backend in launcher ci harness

* test: address latest review feedback

* fix(launcher): preserve user YouTube ytdl raw options

* docs(backlog): update task tracking notes

* fix(immersion): special-case youtube media paths in runtime and tracking

* feat(stats): improve YouTube media metadata and picker key handling

* fix(ci): format stats media library hook

* fix: address latest CodeRabbit review items

* docs: update youtube release notes and docs

* feat: auto-load youtube subtitles before manual picker

* fix: restore app-owned youtube subtitle flow

* docs: update youtube playback docs and config copy

* refactor: remove legacy youtube launcher mode plumbing

* fix: refine youtube subtitle startup binding

* docs: clarify youtube subtitle startup behavior

* fix: address PR #31 latest review follow-ups

* fix: address PR #31 follow-up review comments

* test: harden youtube picker test harness

* udpate backlog

* fix: add timeout to youtube metadata probe

* docs: refresh youtube and stats docs

* update backlog

* update backlog

* chore: release v0.9.0
2026-03-24 00:01:24 -07:00
6749ff843c feat(stats): add v1 immersion stats dashboard (#19) 2026-03-20 02:43:28 -07:00