// Copyright 2018 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { useMemo } from 'react'; import { CurveType, Image } from './Image'; import { StagedGenericAttachment } from './StagedGenericAttachment'; import { StagedPlaceholderAttachment } from './StagedPlaceholderAttachment'; import type { LocalizerType } from '../../types/Util'; import type { AttachmentForUIType, AttachmentDraftType, } from '../../types/Attachment'; import { areAllAttachmentsVisual, canDisplayImage, isImageAttachment, isVideoAttachment, } from '../../types/Attachment'; export type Props = Readonly<{ attachments: ReadonlyArray; canEditImages?: boolean; i18n: LocalizerType; onAddAttachment?: () => void; onClickAttachment?: (attachment: T) => void; onClose?: () => void; onCloseAttachment: (attachment: T) => void; }>; const IMAGE_WIDTH = 120; const IMAGE_HEIGHT = 120; // This is a 1x1 black square. const BLANK_VIDEO_THUMBNAIL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR42mNiAAAABgADm78GJQAAAABJRU5ErkJggg=='; function getUrl( attachment: AttachmentForUIType | AttachmentDraftType ): string | undefined { if (attachment.pending) { return undefined; } if ('screenshot' in attachment) { return attachment.screenshot?.url || attachment.url; } return attachment.url; } export function AttachmentList< T extends AttachmentForUIType | AttachmentDraftType, >({ attachments, canEditImages, i18n, onAddAttachment, onClickAttachment, onCloseAttachment, onClose, }: Props): JSX.Element | null { const attachmentsForUI = useMemo(() => { return attachments.map((attachment: T): AttachmentForUIType => { // Already ForUI attachment if ('isPermanentlyUndownloadable' in attachment) { return attachment; } // Draft return { ...attachment, isPermanentlyUndownloadable: false, }; }); }, [attachments]); if (!attachments.length) { return null; } const allVisualAttachments = areAllAttachmentsVisual(attachments); return (
{onClose && attachments.length > 1 ? (
) : null}
{attachments.map((attachment, index) => { const url = getUrl(attachment); const forUI = attachmentsForUI[index]; const key = url || attachment.path || attachment.fileName || index; const isImage = isImageAttachment(attachment); const isVideo = isVideoAttachment(attachment); const closeAttachment = () => onCloseAttachment(attachment); if ( (isImage && canDisplayImage([attachment])) || isVideo || attachment.pending ) { const imageUrl = url || (isVideo ? BLANK_VIDEO_THUMBNAIL : undefined); const clickAttachment = onClickAttachment ? () => onClickAttachment(attachment) : undefined; const imgElement = ( {i18n('icu:stagedImageAttachment', ); if (isImage && canEditImages) { return (
{imgElement}
); } return imgElement; } return ( ); })} {allVisualAttachments && onAddAttachment ? ( ) : null}
); }