import { useState, useMemo, useRef, useEffect } from 'react'; import { searchHuggys, Huggy } from '../../data/huggys'; interface HuggyMenuProps { onSelectHuggy: (huggy: Huggy) => void; onClose: () => void; } const INITIAL_DISPLAY_COUNT = 12; // Show more initially to ensure scrolling const LOAD_MORE_COUNT = 6; export default function HuggyMenu({ onSelectHuggy, onClose }: HuggyMenuProps) { const [searchQuery, setSearchQuery] = useState(''); const [displayCount, setDisplayCount] = useState(INITIAL_DISPLAY_COUNT); const [loadingImages, setLoadingImages] = useState>(new Set()); const scrollContainerRef = useRef(null); // Filter Huggys based on search query const filteredHuggys = useMemo(() => searchHuggys(searchQuery), [searchQuery]); // Get the Huggys to display (limited by displayCount) const displayedHuggys = filteredHuggys.slice(0, displayCount); const hasMore = displayCount < filteredHuggys.length; // Check if content overflows, if not load more automatically useEffect(() => { const scrollContainer = scrollContainerRef.current; if (!scrollContainer || !hasMore) return; const checkOverflow = () => { const { scrollHeight, clientHeight } = scrollContainer; // If content doesn't overflow (no scrollbar), load more if (scrollHeight <= clientHeight && hasMore) { setDisplayCount(prev => Math.min(prev + LOAD_MORE_COUNT, filteredHuggys.length)); } }; // Check after images load const timer = setTimeout(checkOverflow, 100); return () => clearTimeout(timer); }, [displayCount, hasMore, filteredHuggys.length]); // Infinite scroll: load more when scrolled near bottom useEffect(() => { const scrollContainer = scrollContainerRef.current; if (!scrollContainer) return; const handleScroll = () => { const { scrollTop, scrollHeight, clientHeight } = scrollContainer; const scrollPercentage = (scrollTop + clientHeight) / scrollHeight; // Load more when scrolled to 80% of content if (scrollPercentage > 0.8 && hasMore) { setDisplayCount(prev => Math.min(prev + LOAD_MORE_COUNT, filteredHuggys.length)); } }; scrollContainer.addEventListener('scroll', handleScroll); return () => scrollContainer.removeEventListener('scroll', handleScroll); }, [hasMore, filteredHuggys.length]); const handleHuggyClick = (huggy: Huggy) => { onSelectHuggy(huggy); onClose(); }; const handleImageLoad = (huggyId: string) => { setLoadingImages(prev => { const newSet = new Set(prev); newSet.delete(huggyId); return newSet; }); }; const handleImageLoadStart = (huggyId: string) => { setLoadingImages(prev => new Set(prev).add(huggyId)); }; // Reset display count when search changes const handleSearchChange = (e: React.ChangeEvent) => { setSearchQuery(e.target.value); setDisplayCount(INITIAL_DISPLAY_COUNT); }; return ( <> {/* Backdrop */}
{/* Huggy Menu */}
{ e.preventDefault(); e.stopPropagation(); }} onDrag={(e) => { e.preventDefault(); e.stopPropagation(); }} onDragOver={(e) => { e.preventDefault(); e.stopPropagation(); }} > {/* Search Bar */}
{/* Huggy Grid - Scrollable */}
{filteredHuggys.length === 0 ? (
No Huggys found
) : (
{displayedHuggys.map((huggy) => ( ))}
)}
{/* Summary Footer */}

Showing {displayedHuggys.length} of {filteredHuggys.length} Huggys

); }