import { DownloadIcon, FileIcon, Maximize2Icon, PaperclipIcon, PlayIcon } from "lucide-react";
import { useMemo } from "react";
import MetadataSection from "@/components/MemoMetadata/MetadataSection";
import { cn } from "@/lib/utils";
import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
import { getAttachmentUrl } from "@/utils/attachment";
import AttachmentCard from "./AttachmentCard";
import AudioAttachmentItem from "./AudioAttachmentItem";
import { getAttachmentMetadata, isImageAttachment, isVideoAttachment, separateAttachments } from "./attachmentHelpers";
interface AttachmentListViewProps {
attachments: Attachment[];
onImagePreview?: (urls: string[], index: number) => void;
}
const AttachmentMeta = ({ attachment }: { attachment: Attachment }) => {
const { fileTypeLabel, fileSizeLabel } = getAttachmentMetadata(attachment);
return (
{fileTypeLabel}
{fileSizeLabel && (
<>
•
{fileSizeLabel}
>
)}
);
};
const DocumentItem = ({ attachment }: { attachment: Attachment }) => {
return (
);
};
interface VisualItemProps {
attachment: Attachment;
featured?: boolean;
}
const ImageItem = ({ attachment, onImageClick, featured = false }: VisualItemProps & { onImageClick?: (url: string) => void }) => {
const handleClick = () => {
onImageClick?.(getAttachmentUrl(attachment));
};
return (
);
};
const ImageGallery = ({ attachments, onImageClick }: { attachments: Attachment[]; onImageClick?: (url: string) => void }) => {
if (attachments.length === 1) {
return (
);
}
return (
{attachments.map((attachment) => (
))}
);
};
const VideoItem = ({ attachment }: VisualItemProps) => (
);
const VideoList = ({ attachments }: { attachments: Attachment[] }) => (
{attachments.map((attachment) => (
))}
);
const VisualSection = ({ attachments, onImageClick }: { attachments: Attachment[]; onImageClick?: (url: string) => void }) => {
const images = attachments.filter(isImageAttachment);
const videos = attachments.filter(isVideoAttachment);
return (
{images.length > 0 &&
}
{videos.length > 0 && (
)}
);
};
const AudioList = ({ attachments }: { attachments: Attachment[] }) => (
{attachments.map((attachment) => (
))}
);
const DocsList = ({ attachments }: { attachments: Attachment[] }) => (
{attachments.map((attachment) => (
))}
);
const Divider = () => ;
const AttachmentListView = ({ attachments, onImagePreview }: AttachmentListViewProps) => {
const { visual, audio, docs } = useMemo(() => separateAttachments(attachments), [attachments]);
const imageAttachments = useMemo(() => visual.filter(isImageAttachment), [visual]);
const imageUrls = useMemo(() => imageAttachments.map(getAttachmentUrl), [imageAttachments]);
const hasVisual = visual.length > 0;
const hasAudio = audio.length > 0;
const hasDocs = docs.length > 0;
const sectionCount = [hasVisual, hasAudio, hasDocs].filter(Boolean).length;
if (attachments.length === 0) {
return null;
}
const handleImageClick = (imgUrl: string) => {
const index = imageUrls.findIndex((url) => url === imgUrl);
onImagePreview?.(imageUrls, index >= 0 ? index : 0);
};
return (
{hasVisual && }
{hasVisual && sectionCount > 1 && }
{hasAudio && }
{hasAudio && hasDocs && }
{hasDocs && }
);
};
export default AttachmentListView;