feat(images): report broken covers and achievement icons
Build, Test & Push Frontend / quality-check (push) Successful in 15s
Build, Test & Push Frontend / docker (push) Successful in 22s

This commit is contained in:
lobo committed 2026-09-26 12:07:47 +02:00
1 parent ca75e6a530
commit 42ed0afe51
9 files changed
+173 -9

No files matched your search

+14 -3
View File
@@ -21,6 +21,7 @@ import useSaveAppearance from '../hooks/useSaveAppearance.js';
import {usePreferences} from '../context/PreferencesContext.jsx';
import PageContainer from '../components/PageContainer.jsx';
import {apiFetch} from '../utils/api.js';
import {ACHIEVEMENT_ICONS, reportBrokenImage} from '../utils/brokenImages.js';
import {hasSession} from '../utils/auth.js';
import {isSteamKey} from '../utils/manualGames.js';
@@ -35,6 +36,18 @@ const formatUnlockedAt = (instant, locale) => {
}
};
function AchievementIcon({appid, src, unlocked}) {
const [failed, setFailed] = useState(false);
if (!src || failed) return <div className="size-12 rounded-md bg-muted"/>;
return (
<img src={src} alt="" className={cn('size-12 rounded-md', !unlocked && 'grayscale')}
onError={() => {
reportBrokenImage(appid, ACHIEVEMENT_ICONS);
setFailed(true);
}}/>
);
}
export default function GameDetail() {
const {t, i18n} = useTranslation();
const {appid} = useParams();
@@ -261,9 +274,7 @@ export default function GameDetail() {
a.unlocked ? 'border-primary/40' : 'opacity-60',
)}
>
{icon
? <img src={icon} alt="" className={cn('size-12 rounded-md', !a.unlocked && 'grayscale')}/>
: <div className="size-12 rounded-md bg-muted"/>}
<AchievementIcon key={icon} appid={data.appid} src={icon} unlocked={a.unlocked}/>
<div className="min-w-0 flex-1">
<div className="truncate font-medium">{a.displayName ?? a.apiName}</div>
{a.description && (