signal-desktop/ts/components/conversation/AttachmentList.tsx

115 lines
3.2 KiB
TypeScript
Raw Normal View History

// Copyright 2018-2021 Signal Messenger, LLC
2020-10-30 20:34:04 +00:00
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { Image } from './Image';
import { StagedGenericAttachment } from './StagedGenericAttachment';
import { StagedPlaceholderAttachment } from './StagedPlaceholderAttachment';
2019-01-14 21:49:58 +00:00
import { LocalizerType } from '../../types/Util';
import {
areAllAttachmentsVisual,
AttachmentType,
getUrl,
isImageAttachment,
2019-01-14 21:49:58 +00:00
isVideoAttachment,
} from '../../types/Attachment';
2020-08-20 21:50:43 +00:00
export interface Props {
attachments: Array<AttachmentType>;
2019-01-14 21:49:58 +00:00
i18n: LocalizerType;
onClickAttachment: (attachment: AttachmentType) => void;
onCloseAttachment: (attachment: AttachmentType) => void;
onAddAttachment: () => void;
onClose: () => void;
}
const IMAGE_WIDTH = 120;
const IMAGE_HEIGHT = 120;
// This is a 1x1 black square.
const BLANK_VIDEO_THUMBNAIL =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR42mNiAAAABgADm78GJQAAAABJRU5ErkJggg==';
2020-09-14 19:51:27 +00:00
export const AttachmentList = ({
attachments,
i18n,
onAddAttachment,
onClickAttachment,
onCloseAttachment,
onClose,
}: Props): JSX.Element | null => {
if (!attachments.length) {
return null;
}
2019-01-14 21:49:58 +00:00
2020-09-14 19:51:27 +00:00
const allVisualAttachments = areAllAttachmentsVisual(attachments);
2020-09-14 19:51:27 +00:00
return (
<div className="module-attachments">
{attachments.length > 1 ? (
<div className="module-attachments__header">
<button
type="button"
onClick={onClose}
className="module-attachments__close-button"
aria-label={i18n('close')}
/>
</div>
) : null}
<div className="module-attachments__rail">
{(attachments || []).map((attachment, index) => {
const url = getUrl(attachment);
const key = url || attachment.fileName || index;
const isImage = isImageAttachment(attachment);
const isVideo = isVideoAttachment(attachment);
if (isImage || isVideo) {
2020-09-14 19:51:27 +00:00
const clickCallback =
attachments.length > 1 ? onClickAttachment : undefined;
2019-01-14 21:49:58 +00:00
const imageUrl =
isVideo && !attachment.screenshot ? BLANK_VIDEO_THUMBNAIL : url;
return (
2020-09-14 19:51:27 +00:00
<Image
key={key}
2020-09-14 19:51:27 +00:00
alt={i18n('stagedImageAttachment', [
url || attachment.fileName,
2020-09-14 19:51:27 +00:00
])}
i18n={i18n}
2020-09-14 19:51:27 +00:00
attachment={attachment}
softCorners
playIconOverlay={isVideo}
2020-09-14 19:51:27 +00:00
height={IMAGE_HEIGHT}
width={IMAGE_WIDTH}
url={imageUrl}
2020-09-14 19:51:27 +00:00
closeButton
onClick={clickCallback}
onClickClose={onCloseAttachment}
onError={() => {
onCloseAttachment(attachment);
}}
/>
);
2020-09-14 19:51:27 +00:00
}
return (
<StagedGenericAttachment
key={key}
2020-09-14 19:51:27 +00:00
attachment={attachment}
2019-11-07 21:36:16 +00:00
i18n={i18n}
2020-09-14 19:51:27 +00:00
onClose={onCloseAttachment}
2019-11-07 21:36:16 +00:00
/>
2020-09-14 19:51:27 +00:00
);
})}
{allVisualAttachments ? (
<StagedPlaceholderAttachment onClick={onAddAttachment} i18n={i18n} />
) : null}
</div>
2020-09-14 19:51:27 +00:00
</div>
);
};