Spaces:
Paused
Paused
| "use client"; | |
| import { useEffect, useMemo, useState } from "react"; | |
| import { cn } from "@/lib/utils"; | |
| type ImageThumbnailProps = { | |
| src: string; | |
| thumbnailSrc?: string; | |
| alt?: string; | |
| className?: string; | |
| imageClassName?: string; | |
| }; | |
| export function getImageThumbnailUrl(src: string) { | |
| const marker = "/images/"; | |
| const index = src.indexOf(marker); | |
| if (index < 0) return src; | |
| return `${src.slice(0, index)}/image-thumbnails/${src.slice(index + marker.length)}`; | |
| } | |
| export function ImageThumbnail({ src, thumbnailSrc, alt = "", className, imageClassName }: ImageThumbnailProps) { | |
| const initialSrc = useMemo(() => thumbnailSrc || getImageThumbnailUrl(src), [src, thumbnailSrc]); | |
| const [currentSrc, setCurrentSrc] = useState(initialSrc); | |
| useEffect(() => { | |
| setCurrentSrc(initialSrc); | |
| }, [initialSrc]); | |
| return ( | |
| <span className={cn("block overflow-hidden bg-stone-100", className)}> | |
| <img | |
| src={currentSrc} | |
| alt={alt} | |
| className={cn("h-full w-full object-cover", imageClassName)} | |
| loading="lazy" | |
| decoding="async" | |
| onError={() => { | |
| if (currentSrc !== src) { | |
| setCurrentSrc(src); | |
| } | |
| }} | |
| /> | |
| </span> | |
| ); | |
| } | |