feat: show mining frame toast on OSD and speed up stats session deletes

- Flash mined-frame screenshot as in-overlay image toast for OSD card notifications
- Batch cover art from stored DB blobs via POST /api/stats/covers (no extra AniList fetches)
- Show delete progress toast on stats home and sessions pages
- Refresh only affected rollups on session delete instead of full rebuild
- Rebuild lifetime summaries with aggregate SQL CTEs instead of per-session loop
This commit is contained in:
2026-06-04 22:00:51 -07:00
parent ea79e331fa
commit b343f1cf5c
45 changed files with 1199 additions and 209 deletions
+2 -23
View File
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { RetryingCoverImage } from '../common/RetryingCoverImage';
import { getStatsClient } from '../../hooks/useStatsApi';
interface AnimeCoverImageProps {
@@ -8,28 +8,7 @@ interface AnimeCoverImageProps {
}
export function AnimeCoverImage({ animeId, title, className = '' }: AnimeCoverImageProps) {
const [failed, setFailed] = useState(false);
const fallbackChar = title.charAt(0) || '?';
if (failed) {
return (
<div
className={`bg-ctp-surface2 flex items-center justify-center text-ctp-overlay2 text-2xl font-bold ${className}`}
>
{fallbackChar}
</div>
);
}
const src = getStatsClient().getAnimeCoverUrl(animeId);
return (
<img
src={src}
alt={title}
loading="lazy"
className={`object-cover bg-ctp-surface2 ${className}`}
onError={() => setFailed(true)}
/>
);
return <RetryingCoverImage src={src} alt={title} fallbackLabel={title} className={className} />;
}