feat(ui): make stat numbers clickable to open games
Build, Test & Push Frontend / quality-check (push) Successful in 28s
Build, Test & Push Frontend / docker (push) Successful in 26s

StatDrill context holds one dialog for a page. StatCount wraps a number:
total and status counts link to the library filter, other numbers open
StatGamesDialog. DrillRow and DrillButton support drill-down in tag bars
(genres, platforms, moods) and other stat displays. Dialog shows 40 games
per page with bottom-sheet layout on phones, handles pagination and errors
(403 not shared, 401 expired, 400 bad argument).
This commit is contained in:
lobo committed 2026-10-03 18:51:59 +02:00
1 parent ed5df8c40d
commit 777ba87fd6
31 files changed
+1026 -261

No files matched your search

+17
View File
@@ -31,6 +31,10 @@ To Be Played is split into three repositories:
- **Your stats** (`/stats`): totals and statuses; the pile in hours, in weeks at your pace of the last 90 days and in
years of full-time work, and its oldest unplayed game; most played and most loyal games; top genres and moods;
trips to the moon, the longest gaming day, games started but under one hour; finished games per year; games per platform.
- **Click a number** (stats page, dashboard, public profile, landing page, Pile Points): a number, bar, row or year
opens the games behind it in a dialog (a bottom sheet on phones), 40 per page with "Load more". In your own
views the status counts and the pile link to the library with the filter instead. Not clickable: sums (playtime),
averages, rates and the moon trips. The list always uses the same rules as the number.
- **Pile Points** (`/points`): points for playing games off your pile (start, finish by time to beat, 100 %, month and
streak bonuses; Core checks proof of play), spent in a small shop on an avatar border, a badge, a premium accent, a
banner frame, an effect for 100 % games and an animated page or banner background (CSS and SVG in `effects.css`, two canvas engines in `EffectCanvas`; layers follow the mouse and the phone tilt, on iPhone after the switch in the settings),
@@ -208,6 +212,19 @@ flowchart LR
with `src/test/fetchRoutes.js`, which fails a test on any request without a route.
- `src/utils/brokenImages.js` reports pictures that fail to load (`GameCover`, achievement icons on the game
detail page) to Core.
- The games behind a number: pages wrap their content in `StatDrillProvider` (`source` own, profile, community or
points), which renders one `StatGamesDialog`. Numbers call `useStatDrill()` / `StatCount`; outside a provider they
are plain text. `src/utils/statGames.js` builds the four endpoint URLs.
```mermaid
flowchart LR
Number["Number, bar or row"] --> Provider["StatDrillProvider"]
Provider --> Dialog["StatGamesDialog"]
Dialog -->|own| Own["Core /api/library/stats/games"]
Dialog -->|"profile + ticket"| Profile["Core /api/public/profiles/library/stats/games"]
Dialog -->|community| Community["Core /api/stats/public/games"]
Dialog -->|points| Points["Core /api/rewards/.../games"]
```
- `useLibrarySync` polls Core's `/api/library/sync-status` while a Steam sync runs, then loads the data again.
- The bookmarklet hands its list over in the URL fragment (base64url JSON), which the browser sends to no server.
The import page reads it once and removes it from the URL. `RequireSession` keeps the fragment on the way