import React, { useEffect, useRef, useState } from 'react'; import { Download, Maximize2, Check, MessageSquare, Star, Heart } from 'lucide-react'; import { useTheme } from '../../../contexts/ThemeContext'; import { AuthenticatedImage } from '../../common'; import type { BaseGalleryLayoutProps } from './BaseGalleryLayout'; import type { Photo } from '../../../types'; interface MasonryPhotoProps { photo: Photo; isSelected: boolean; isSelectionMode: boolean; onClick: (e: React.MouseEvent) => void; onDownload: (e: React.MouseEvent) => void; onToggleSelect: () => void; style?: React.CSSProperties; allowDownloads?: boolean; feedbackEnabled?: boolean; } const MasonryPhoto: React.FC = ({ photo, isSelected, isSelectionMode, onClick, onDownload, onToggleSelect, style, allowDownloads = true, feedbackEnabled = false }) => { const [imageHeight, setImageHeight] = useState(200); // Generate random heights for masonry effect useEffect(() => { const heights = [200, 250, 300, 350, 400]; const randomHeight = heights[Math.floor(Math.random() * heights.length)]; setImageHeight(randomHeight); }, [photo.id]); return (
{/* Feedback Indicators */} {feedbackEnabled && (photo.comment_count > 0 || photo.average_rating > 0 || photo.like_count > 0) && (
{photo.comment_count > 0 && (
{photo.comment_count}
)} {photo.average_rating > 0 && (
{Number(photo.average_rating).toFixed(1)}
)} {photo.like_count > 0 && (
{photo.like_count}
)}
)}
{!isSelectionMode && ( <> {allowDownloads && ( )} )}
{/* Selection Checkbox (visible on hover or when selected) */} {photo.type === 'collage' && (
Collage
)}
); }; export const MasonryGalleryLayout: React.FC = ({ photos, onPhotoClick, onDownload, selectedPhotos = new Set(), isSelectionMode = false, onPhotoSelect, allowDownloads = true, feedbackEnabled = false }) => { const { theme } = useTheme(); const containerRef = useRef(null); const [columns, setColumns] = useState(3); const gallerySettings = theme.gallerySettings || {}; const gutter = gallerySettings.masonryGutter || 16; // Calculate number of columns based on container width useEffect(() => { const updateColumns = () => { if (containerRef.current) { const width = containerRef.current.offsetWidth; if (width < 640) setColumns(2); else if (width < 1024) setColumns(3); else if (width < 1280) setColumns(4); else setColumns(5); } }; updateColumns(); window.addEventListener('resize', updateColumns); return () => window.removeEventListener('resize', updateColumns); }, []); // Distribute photos across columns const photoColumns: Photo[][] = Array.from({ length: columns }, () => []); photos.forEach((photo, index) => { photoColumns[index % columns].push(photo); }); return (
{photoColumns.map((column, columnIndex) => (
{column.map((photo) => { const originalIndex = photos.findIndex(p => p.id === photo.id); return ( onPhotoClick(originalIndex)} onDownload={(e) => onDownload(photo, e)} onToggleSelect={() => onPhotoSelect && onPhotoSelect(photo.id)} allowDownloads={allowDownloads} feedbackEnabled={feedbackEnabled} /> ); })}
))}
); };