"use client" import { X } from "lucide-react" import Image from "next/image" import { useEffect, useRef, useState } from "react" interface FilePreviewListProps { files: File[] onRemoveFile: (fileToRemove: File) => void } export function FilePreviewList({ files, onRemoveFile }: FilePreviewListProps) { const [selectedImage, setSelectedImage] = useState(null) const [imageUrls, setImageUrls] = useState>(new Map()) const imageUrlsRef = useRef>(new Map()) // Create and cleanup object URLs when files change useEffect(() => { const currentUrls = imageUrlsRef.current const newUrls = new Map() files.forEach((file) => { if (file.type.startsWith("image/")) { // Reuse existing URL if file is already tracked const existingUrl = currentUrls.get(file) if (existingUrl) { newUrls.set(file, existingUrl) } else { newUrls.set(file, URL.createObjectURL(file)) } } }) // Revoke URLs for files that are no longer in the list currentUrls.forEach((url, file) => { if (!newUrls.has(file)) { URL.revokeObjectURL(url) } }) imageUrlsRef.current = newUrls setImageUrls(newUrls) }, [files]) // Cleanup all URLs on unmount only useEffect(() => { return () => { imageUrlsRef.current.forEach((url) => { URL.revokeObjectURL(url) }) } }, []) // Clear selected image if its URL was revoked useEffect(() => { if ( selectedImage && !Array.from(imageUrls.values()).includes(selectedImage) ) { setSelectedImage(null) } }, [imageUrls, selectedImage]) if (files.length === 0) return null return ( <>
{files.map((file, index) => { const imageUrl = imageUrls.get(file) || null return (
imageUrl && setSelectedImage(imageUrl) } > {file.type.startsWith("image/") && imageUrl ? ( {file.name} ) : (
{file.name}
)}
) })}
{/* Image Modal/Lightbox */} {selectedImage && (
setSelectedImage(null)} >
Full size preview of uploaded diagram or image e.stopPropagation()} />
)} ) }