import { LoaderCircle, X } from "lucide-react"; import { DownloadCloudIcon } from "../../icons/DownloadCloudIcon"; import { useEffect, useState } from "react"; import { createPortal } from "react-dom"; import { useI18n } from "../../../i18n"; import type { Attachment, Post } from "../../../types/post"; import { AttachmentDownloadPill } from "../AttachmentDownloadPill"; import { useLightbox } from "../overlays/ImageLightbox"; import { autolink } from "../utils/autolink"; import { downloadAttachment } from "../utils/downloadFile"; import { formatBytes } from "../utils/formatBytes"; import { postDisplayText } from "../utils/postText"; import { useToast } from "../../Toast"; const MAX_VISIBLE = 4; function albumGridClass(count: number) { const height = "h-[230px] min-[440px]:h-[250px] md:h-[300px] lg:h-[340px]"; if (count === 2) return `${height} grid grid-cols-1 grid-rows-2`; return `${height} grid grid-cols-2 grid-rows-2`; } function albumItemClass(index: number, count: number) { if (count === 3 && index === 0) return "row-span-2"; return ""; } function ImageListDownloadButton({ postId, attachment, }: { postId: string; attachment: Attachment; }) { const { t } = useI18n(); const { showToast } = useToast(); const [isDownloading, setIsDownloading] = useState(false); const handleDownload = async () => { if (isDownloading) return; setIsDownloading(true); try { await downloadAttachment(postId, attachment.id, attachment.filename); showToast(t("downloadOk")); } catch { showToast(t("downloadFail"), "error"); } finally { setIsDownloading(false); } }; return ( ); } function ImageListDialog({ postId, images, onClose, onPick, }: { postId: string; images: Attachment[]; onClose: () => void; onPick: (index: number) => void; }) { useEffect(() => { const onKey = (event: KeyboardEvent) => { if (event.key === "Escape") onClose(); }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [onClose]); return createPortal(