import React, { useState, useCallback, useEffect } from 'react' const FALLBACK_MD = 'https://files.skinbase.org/default/missing_md.webp' const FALLBACK_LG = 'https://files.skinbase.org/default/missing_lg.webp' const FALLBACK_XL = 'https://files.skinbase.org/default/missing_xl.webp' export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl, onOpenViewer, hasPrev, hasNext, onPrev, onNext }) { const [isLoaded, setIsLoaded] = useState(false) const mdSource = presentMd?.url || artwork?.thumbs?.md?.url || null const lgSource = presentLg?.url || artwork?.thumbs?.lg?.url || null const xlSource = presentXl?.url || artwork?.thumbs?.xl?.url || null const md = mdSource || FALLBACK_MD const lg = lgSource || FALLBACK_LG const xl = xlSource || FALLBACK_XL const hasRealArtworkImage = Boolean(mdSource || lgSource || xlSource) const blurBackdropSrc = mdSource || lgSource || xlSource || null const dbWidth = Number(artwork?.width) const dbHeight = Number(artwork?.height) const hasDbDims = dbWidth > 0 && dbHeight > 0 // Natural dimensions — seeded from DB if available, otherwise probed from // the xl thumbnail (largest available, never upscaled past the original). const [naturalDims, setNaturalDims] = useState( hasDbDims ? { w: dbWidth, h: dbHeight } : null ) // Probe the xl image to discover real dimensions when DB has none useEffect(() => { if (naturalDims || !xlSource) return const img = new Image() img.onload = () => { if (img.naturalWidth > 0 && img.naturalHeight > 0) { setNaturalDims({ w: img.naturalWidth, h: img.naturalHeight }) } } img.src = xlSource }, [xlSource, naturalDims]) const aspectRatio = naturalDims ? `${naturalDims.w} / ${naturalDims.h}` : '16 / 9' const srcSet = `${md} 640w, ${lg} 1280w, ${xl} 1920w` return (
{blurBackdropSrc && ( <>
)}
{hasPrev && ( )}
{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault() onOpenViewer() } } : undefined} > {artwork?.title {artwork?.title setIsLoaded(true)} onError={(event) => { event.currentTarget.src = FALLBACK_LG }} /> {onOpenViewer && ( )}
{hasRealArtworkImage && (
)}
{hasNext && ( )}
) }