"use client"; import { useEffect, useRef, useState } from "react"; import { cn } from "@/lib/utils"; type Props = { gradient: string; label?: string | undefined; className?: string | undefined; src?: string | undefined; previewUrl?: string | undefined; }; export function Thumbnail({ gradient, label, className, src, previewUrl, }: Props) { const [imgFailed, setImgFailed] = useState(false); const [isNearViewport, setIsNearViewport] = useState(false); const rootRef = useRef(null); const showImage = src && !imgFailed; const showPreviewFrame = !showImage && previewUrl && isNearViewport; useEffect(() => { if (!previewUrl || showImage) return; const el = rootRef.current; if (!el) return; if (!("IntersectionObserver" in window)) { setIsNearViewport(true); return; } const observer = new IntersectionObserver( ([entry]) => { if (!entry?.isIntersecting) return; setIsNearViewport(true); observer.disconnect(); }, { rootMargin: "500px 0px" }, ); observer.observe(el); return () => observer.disconnect(); }, [previewUrl, showImage]); return (
{showImage ? ( // biome-ignore lint/performance/noImgElement: Template thumbnails may be generated preview images. {label setImgFailed(true)} className="absolute inset-0 h-full w-full object-cover" /> ) : showPreviewFrame ? ( <>