import { useI18n } from "../../../i18n"; import type { Post } from "../../../types/post"; import { ALBUM_GAP, ALBUM_MAX_HEIGHT } from "../../../constants/media"; import { AttachmentDownloadPill } from "../AttachmentDownloadPill"; import { BubbleImage } from "../BubbleImage"; import { useImageRatios } from "../hooks/useImageRatios"; import { useLightbox } from "../overlays/ImageLightbox"; import { autolink } from "../utils/autolink"; import { computeAlbumLayout } from "../utils/albumLayout"; import { postDisplayText } from "../utils/postText"; const MAX_VISIBLE = 4; export function AlbumBubble({ post }: { post: Post }) { const { openLightbox } = useLightbox(); const { lang } = useI18n(); const images = post.attachments; const text = postDisplayText(post, lang); const visible = images.slice(0, MAX_VISIBLE); const extra = images.length - MAX_VISIBLE; const sources = visible.map( (att) => att.thumbnailUrl ?? att.thumbUrl ?? att.url, ); const ratios = useImageRatios(visible, sources); const layout = computeAlbumLayout(ratios); return (
{/* aspect-ratio lives on the wrapper so the grid gets a *definite* height (inset-0) and its fr rows stretch instead of collapsing to content. */}
{visible.map((att, i) => { const isLastSlot = i === MAX_VISIBLE - 1 && extra > 0; const tile = layout?.tiles[i]; return (
{!isLastSlot ? ( ) : null}
); })}
{text ? (
{autolink(text)}
) : null}
); }