feat(library): show playtime per platform on game detail

Hero and library card show the set total. Fall back to the
row's own minutes when the API sends no total.
This commit is contained in:
lobo committed 2026-10-09 13:55:57 +02:00
1 parent 16651a1f56
commit f1a6bc0443
9 files changed
+178 -2

No files matched your search

+3
View File
@@ -18,6 +18,7 @@ import EditionsCard from '../components/EditionsCard.jsx';
import OwnersCard from '../components/people/OwnersCard.jsx';
import GameMergeDialog from '../components/GameMergeDialog.jsx';
import LinkGameDialog from '../components/LinkGameDialog.jsx';
import PlatformsCard from '../components/PlatformsCard.jsx';
import PlayingHint from '../components/PlayingHint.jsx';
import useCurrentUser from '../hooks/useCurrentUser.js';
import useGame from '../hooks/useGame.js';
@@ -110,6 +111,8 @@ export default function GameDetail() {
if (data.editions?.length) reload();
}}/>
<PlatformsCard game={data}/>
<EditionsCard game={data} auditor={auditor} onRequest={() => setLinking(true)} onChanged={reload}/>
<OwnersCard key={`owners-${data.appid}`} appid={data.appid}/>
+1 -1
View File
@@ -363,7 +363,7 @@ export default function GameLibrary() {
)}
<Badge variant="secondary" className="tabular-nums">
<Clock className="size-3"/>
{formatPlaytime(g.playtimeMinutes)}
{formatPlaytime(g.totalPlaytimeMinutes ?? g.playtimeMinutes)}
</Badge>
<ChevronRight className="size-4 text-muted-foreground"/>
</Link>
+10
View File
@@ -235,6 +235,16 @@ describe('GameLibrary short games', () => {
expect(screen.queryByText('Steam')).toBeNull();
});
it('showsTheSetTotalPlaytimeOnTheCard_AndTheOwnMinutesWithoutATotal', async () => {
answer([{appid: 220, name: 'Half-Life 2', playtimeMinutes: 600, totalPlaytimeMinutes: 3600, status: 'BACKLOG'},
{appid: 620, name: 'Portal 2', playtimeMinutes: 1200, status: 'BACKLOG'}]);
renderLibrary();
expect(await screen.findByText('60h')).toBeTruthy();
expect(screen.getByText('20h')).toBeTruthy();
expect(screen.queryByText('10h')).toBeNull();
});
it('leaves the hidden games with a status click', async () => {
const lib = renderLibrary('/library?hidden=true');
await waitFor(() => expect(fetch).toHaveBeenCalled());