minor fixes

This commit is contained in:
2026-04-09 08:50:36 +02:00
parent 23d363a50c
commit a2457f4e49
75 changed files with 3848 additions and 387 deletions

View File

@@ -6,6 +6,9 @@ const FALLBACK_XL = 'https://files.skinbase.org/default/missing_xl.webp'
export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl, mediaWidth = null, mediaHeight = null, mediaKey = 'cover', onOpenViewer, hasPrev, hasNext, onPrev, onNext }) {
const [isLoaded, setIsLoaded] = useState(false)
const [mainImageMode, setMainImageMode] = useState('primary')
const [previewImageMode, setPreviewImageMode] = useState('primary')
const [showBackdrop, setShowBackdrop] = useState(true)
const mdSource = presentMd?.url || artwork?.thumbs?.md?.url || null
const lgSource = presentLg?.url || artwork?.thumbs?.lg?.url || null
@@ -17,6 +20,19 @@ export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl,
const hasRealArtworkImage = Boolean(mdSource || lgSource || xlSource)
const blurBackdropSrc = mdSource || lgSource || xlSource || null
const primaryMainSrc = lgSource || xlSource || mdSource || FALLBACK_LG
const primaryPreviewSrc = mdSource || lgSource || xlSource || FALLBACK_MD
const srcSet = [
mdSource ? `${mdSource} 640w` : null,
lgSource ? `${lgSource} 1280w` : null,
xlSource ? `${xlSource} 1920w` : null,
].filter(Boolean).join(', ')
const resolvedMainSrc = mainImageMode === 'fallback'
? FALLBACK_LG
: (mainImageMode === 'hidden' ? null : primaryMainSrc)
const resolvedPreviewSrc = previewImageMode === 'fallback'
? FALLBACK_MD
: (previewImageMode === 'hidden' ? null : primaryPreviewSrc)
const dbWidth = Number(mediaWidth ?? artwork?.width)
const dbHeight = Number(mediaHeight ?? artwork?.height)
@@ -30,6 +46,10 @@ export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl,
useEffect(() => {
setIsLoaded(false)
setMainImageMode('primary')
setPreviewImageMode('primary')
setShowBackdrop(true)
if (hasDbDims) {
setNaturalDims({ w: dbWidth, h: dbHeight })
return
@@ -47,16 +67,15 @@ export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl,
setNaturalDims({ w: img.naturalWidth, h: img.naturalHeight })
}
}
img.onerror = null
img.src = xlSource
}, [xlSource, naturalDims])
const aspectRatio = naturalDims ? `${naturalDims.w} / ${naturalDims.h}` : '16 / 9'
const srcSet = `${md} 640w, ${lg} 1280w, ${xl} 1920w`
return (
<figure className="relative w-full overflow-hidden rounded-[2rem] border border-white/10 bg-gradient-to-b from-nova-950 via-nova-900 to-nova-900 p-2 shadow-[0_35px_90px_-35px_rgba(15,23,36,0.9)] sm:p-4">
{blurBackdropSrc && (
{blurBackdropSrc && showBackdrop && (
<>
<img
src={blurBackdropSrc}
@@ -65,6 +84,10 @@ export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl,
className="pointer-events-none absolute inset-0 h-full w-full scale-110 object-cover opacity-30 blur-3xl"
loading="eager"
decoding="async"
onError={(event) => {
event.currentTarget.onerror = null
setShowBackdrop(false)
}}
/>
<div className="pointer-events-none absolute inset-0 bg-gradient-to-b from-nova-950/55 via-nova-900/40 to-nova-950/70" />
<div className="pointer-events-none absolute inset-0 backdrop-blur-sm" />
@@ -102,29 +125,52 @@ export default function ArtworkHero({ artwork, presentMd, presentLg, presentXl,
}
} : undefined}
>
<img
src={md}
alt={artwork?.title ?? 'Artwork'}
className="absolute inset-0 h-full w-full object-contain rounded-xl"
loading="eager"
decoding="async"
fetchPriority="high"
/>
{resolvedPreviewSrc ? (
<img
src={resolvedPreviewSrc}
alt={artwork?.title ?? 'Artwork'}
className="absolute inset-0 h-full w-full object-contain rounded-xl"
loading="eager"
decoding="async"
fetchPriority="high"
onError={(event) => {
event.currentTarget.onerror = null
<img
src={lg}
srcSet={srcSet}
sizes="(min-width: 1536px) 1400px, (min-width: 1024px) 92vw, 100vw"
alt={artwork?.title ?? 'Artwork'}
className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-500 ${isLoaded ? 'opacity-100' : 'opacity-0'}`}
loading="eager"
decoding="async"
fetchPriority="high"
onLoad={() => setIsLoaded(true)}
onError={(event) => {
event.currentTarget.src = FALLBACK_LG
}}
/>
if (previewImageMode === 'primary') {
setPreviewImageMode('fallback')
return
}
setPreviewImageMode('hidden')
}}
/>
) : null}
{resolvedMainSrc ? (
<img
src={resolvedMainSrc}
srcSet={mainImageMode === 'primary' && srcSet !== '' ? srcSet : undefined}
sizes={mainImageMode === 'primary' && srcSet !== '' ? '(min-width: 1536px) 1400px, (min-width: 1024px) 92vw, 100vw' : undefined}
alt={artwork?.title ?? 'Artwork'}
className={`absolute inset-0 h-full w-full object-contain transition-opacity duration-500 ${isLoaded ? 'opacity-100' : 'opacity-0'}`}
loading="eager"
decoding="async"
fetchPriority="high"
onLoad={() => setIsLoaded(true)}
onError={(event) => {
event.currentTarget.onerror = null
if (mainImageMode === 'primary') {
setMainImageMode('fallback')
setIsLoaded(false)
return
}
setMainImageMode('hidden')
setIsLoaded(true)
}}
/>
) : null}
{onOpenViewer && (
<button