import React, { useState, useRef, useEffect } from "react"; import { useDebounce } from "../../../hooks/useDebounce"; import { useInfiniteScroll } from "../../../hooks/useInfiniteScroll"; import { useOpenverse } from "../../../hooks/useOpenverse"; import { useGenerator } from "../../../context/GeneratorContext"; import { SearchBar, ImageCard, ImageGrid, ImageList, ImageSkeleton, EmptyState, ErrorMessage, } from "../../shared"; import { initialsAvatar } from "../../../utils/helpers"; const PROVIDER_ID = "openverse"; export default function OpenverseGallery() { const [query, setQuery] = useState(""); const debouncedQuery = useDebounce(query, 500); const { viewMode, itemsPerPage, loadMoreMode, getFilters, selectAll, setPreviewImageList } = useGenerator(); const filters = getFilters(PROVIDER_ID); const hasMoreRef = useRef(true); const loadingRef = useRef(false); const { page, loadMore, resetPage, observerTarget } = useInfiniteScroll(1, { hasMoreRef, loadingRef, }); const { images, loading, scrollLoading, error, hasMore } = useOpenverse( debouncedQuery, page, filters, itemsPerPage ); useEffect(() => { hasMoreRef.current = loadMoreMode === "auto" ? hasMore : false; loadingRef.current = scrollLoading; }, [hasMore, scrollLoading, loadMoreMode]); // Reset page when filters or settings change useEffect(() => { resetPage(1); }, [filters.license, filters.source, filters.orientation, itemsPerPage, resetPage]); // Handle bulk select all useEffect(() => { const handleBulkSelect = (e) => { if (e.detail.providerId === PROVIDER_ID && images.length > 0) { const imageData = {}; images.forEach((img) => { const key = `${PROVIDER_ID}:${img.id}`; imageData[key] = { importUrl: img.url, imageSrc: img.thumbnail || img.url, imageAlt: img.title || "Openverse image", author: { url: img.creator_url, avatar: initialsAvatar(img.creator || "Unknown"), name: img.creator || "Unknown", }, previewUrl: img.foreign_landing_url, }; }); selectAll(PROVIDER_ID, images.map((img) => String(img.id)), imageData); } }; window.addEventListener('bulkSelectAll', handleBulkSelect); return () => window.removeEventListener('bulkSelectAll', handleBulkSelect); }, [images, selectAll]); useEffect(() => { if (images.length > 0) { const list = images.map((img, idx) => ({ imageSrc: img.url, imageAlt: img.title || "Openverse image", previewUrl: img.foreign_landing_url, author: { url: img.creator_url, avatar: initialsAvatar(img.creator || "Unknown"), name: img.creator || "Unknown" }, importUrl: img.url, downloadOptions: [{ label: "Original", url: img.url }].filter(o => o.url), providerId: PROVIDER_ID, imageId: String(img.id), providerBadge: "Openverse", index: idx, })); setPreviewImageList(list); } }, [images, setPreviewImageList]); const handleSearchChange = (value) => { setQuery(value); resetPage(1); }; const isEmpty = !loading && !error && images.length === 0; return (
Loading more images...
)} {!loading && !scrollLoading && images.length > 0 && !hasMore && (No more results.
)}