import {useState} from 'react'; import {useTranslation} from 'react-i18next'; import {Clock, ExternalLink, Eye, EyeOff, Gamepad2, Image as ImageIcon, ImageOff, Merge, PanelTop, PencilLine, RotateCcw, Timer} from 'lucide-react'; import {toast} from 'sonner'; import {Badge} from '@/components/ui/badge'; import {Button} from '@/components/ui/button'; import {Card} from '@/components/ui/card'; import GameCover from './GameCover.jsx'; import GameStatusBadge from './GameStatusBadge.jsx'; import ProfileArtMenu from './ProfileArtMenu.jsx'; import TimeToBeat from './TimeToBeat.jsx'; import useSaveAppearance from '../hooks/useSaveAppearance.js'; import {usePreferences} from '../context/PreferencesContext.jsx'; import {formatPlaytime} from '../utils/games.js'; import {setGameHidden} from '../utils/hiddenGames.js'; import {isSteamKey} from '../utils/manualGames.js'; import {platformLabel} from '../utils/platforms.js'; const SPEEDRUN_PREFIX = 'https://www.speedrun.com/'; export default function GameHeroCard({game, manual, auditor, profileStyle, onCorrect, onMerge, onHiddenChanged, onProfileStyleSaved}) { const {t} = useTranslation(); const {appearance} = usePreferences(); const saveAppearance = useSaveAppearance(); const [hiding, setHiding] = useState(false); const onSteam = isSteamKey(game.appid); // Core checks the link too; a link from the API must never run script. const speedrunUrl = typeof game.speedrunUrl === 'string' && game.speedrunUrl.startsWith(SPEEDRUN_PREFIX) ? game.speedrunUrl : null; const isBackground = appearance.backgroundAppid === game.appid; const isBanner = appearance.showBanner && appearance.bannerAppid === game.appid; const toggleHidden = async () => { const hidden = !game.hidden; setHiding(true); try { const response = await setGameHidden(game.appid, hidden); if (response.status === 401) return; if (!response.ok) { toast.error(t('GAME_DETAIL.HIDE_ERROR')); return; } onHiddenChanged(hidden); toast.success(t(hidden ? 'GAME_DETAIL.HIDDEN_TOAST' : 'GAME_DETAIL.SHOWN_TOAST')); } catch (err) { console.error('Hide game error:', err); toast.error(t('INFO.ERROR.NETWORK_FAILURE')); } finally { setHiding(false); } }; return (

{game.name ?? `App ${game.appid}`}

{t('GAME_DETAIL.PLAYTIME', {time: formatPlaytime(game.playtimeMinutes)})} {platformLabel(game) && ( {platformLabel(game)} )}
{speedrunUrl && ( )} {auditor && ( )} {auditor && ( )}
{/* Store page, background and banner need Steam art, so a game off Steam has none of them. Hide is here too: only a Steam game can be hidden. */} {onSteam &&
{isBackground ? ( ) : ( )} {isBanner ? ( ) : ( )} {profileStyle && ( )} {!manual && ( )}
}
); }