feat: generic attachments for messages components

pull/3170/head
yougotwill 9 months ago
parent bdbc48590e
commit bc86dd6c1f

@ -1,4 +1,3 @@
import classNames from 'classnames';
import { clone } from 'lodash'; import { clone } from 'lodash';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
@ -16,8 +15,6 @@ import {
import { import {
AttachmentType, AttachmentType,
AttachmentTypeWithPath, AttachmentTypeWithPath,
canDisplayImagePreview,
getExtensionForDisplay,
hasImage, hasImage,
hasVideoScreenshot, hasVideoScreenshot,
isAudio, isAudio,
@ -26,12 +23,12 @@ import {
} from '../../../../types/Attachment'; } from '../../../../types/Attachment';
import { saveAttachmentToDisk } from '../../../../util/attachmentsUtil'; import { saveAttachmentToDisk } from '../../../../util/attachmentsUtil';
import { MediaItemType } from '../../../lightbox/LightboxGallery'; import { MediaItemType } from '../../../lightbox/LightboxGallery';
import { Spinner } from '../../../loading';
import { AudioPlayerWithEncryptedFile } from '../../H5AudioPlayer'; import { AudioPlayerWithEncryptedFile } from '../../H5AudioPlayer';
import { ImageGrid } from '../../ImageGrid'; import { ImageGrid } from '../../ImageGrid';
import { ClickToTrustSender } from './ClickToTrustSender'; import { ClickToTrustSender } from './ClickToTrustSender';
import { MessageHighlighter } from './MessageHighlighter'; import { MessageHighlighter } from './MessageHighlighter';
import { useIsDetailMessageView } from '../../../../contexts/isDetailViewContext'; import { useIsDetailMessageView } from '../../../../contexts/isDetailViewContext';
import { MessageGenericAttachment } from './MessageGenericAttachment';
export type MessageAttachmentSelectorProps = Pick< export type MessageAttachmentSelectorProps = Pick<
MessageRenderingProps, MessageRenderingProps,
@ -62,10 +59,6 @@ const StyledImageGridContainer = styled.div<{
justify-content: ${props => (props.messageDirection === 'incoming' ? 'flex-start' : 'flex-end')}; justify-content: ${props => (props.messageDirection === 'incoming' ? 'flex-start' : 'flex-end')};
`; `;
const StyledGenericAttachmentContainer = styled(MessageHighlighter)<{ selected: boolean }>`
${props => props.selected && 'box-shadow: var(--drop-shadow);'}
`;
export const MessageAttachment = (props: Props) => { export const MessageAttachment = (props: Props) => {
const { messageId, imageBroken, handleImageError, highlight = false } = props; const { messageId, imageBroken, handleImageError, highlight = false } = props;
const isDetailView = useIsDetailMessageView(); const isDetailView = useIsDetailMessageView();
@ -130,17 +123,14 @@ export const MessageAttachment = (props: Props) => {
} }
const firstAttachment = attachments[0]; const firstAttachment = attachments[0];
const displayImage = canDisplayImagePreview(attachments);
if (!isTrustedForAttachmentDownload) { if (!isTrustedForAttachmentDownload) {
return <ClickToTrustSender messageId={messageId} />; return <ClickToTrustSender messageId={messageId} />;
} }
if ( if (
displayImage && (isImage(attachments) && hasImage(attachments)) ||
!imageBroken && (isVideo(attachments) && hasVideoScreenshot(attachments))
((isImage(attachments) && hasImage(attachments)) ||
(isVideo(attachments) && hasVideoScreenshot(attachments)))
) { ) {
// we use the carousel in the detail view // we use the carousel in the detail view
if (isDetailView) { if (isDetailView) {
@ -152,6 +142,8 @@ export const MessageAttachment = (props: Props) => {
<ImageGrid <ImageGrid
messageId={messageId} messageId={messageId}
attachments={attachments} attachments={attachments}
imageBroken={imageBroken}
highlight={highlight}
onError={handleImageError} onError={handleImageError}
onClickAttachment={onClickOnImageGrid} onClickAttachment={onClickOnImageGrid}
/> />
@ -181,48 +173,15 @@ export const MessageAttachment = (props: Props) => {
</MessageHighlighter> </MessageHighlighter>
); );
} }
const { pending, fileName, fileSize, contentType } = firstAttachment;
const extension = getExtensionForDisplay({ contentType, fileName });
return ( return (
<StyledGenericAttachmentContainer <MessageGenericAttachment
attachment={firstAttachment}
direction={direction}
highlight={highlight} highlight={highlight}
selected={selected} selected={selected}
className={'module-message__generic-attachment'}
onClick={onClickOnGenericAttachment} onClick={onClickOnGenericAttachment}
> />
{pending ? (
<div className="module-message__generic-attachment__spinner-container">
<Spinner size="small" />
</div>
) : (
<div className="module-message__generic-attachment__icon-container">
<div role="button" className="module-message__generic-attachment__icon">
{extension ? (
<div className="module-message__generic-attachment__icon__extension">{extension}</div>
) : null}
</div>
</div>
)}
<div className="module-message__generic-attachment__text">
<div
className={classNames(
'module-message__generic-attachment__file-name',
`module-message__generic-attachment__file-name--${direction}`
)}
>
{fileName}
</div>
<div
className={classNames(
'module-message__generic-attachment__file-size',
`module-message__generic-attachment__file-size--${direction}`
)}
>
{fileSize}
</div>
</div>
</StyledGenericAttachmentContainer>
); );
}; };

@ -0,0 +1,73 @@
import classNames from 'classnames';
import styled from 'styled-components';
import { PropsForAttachment } from '../../../../state/ducks/conversations';
import { AttachmentTypeWithPath, getExtensionForDisplay } from '../../../../types/Attachment';
import { Spinner } from '../../../loading';
import { MessageModelType } from '../../../../models/messageType';
import { MessageHighlighter } from './MessageHighlighter';
const StyledGenericAttachmentContainer = styled(MessageHighlighter)<{
highlight: boolean;
selected: boolean;
}>`
${props => props.selected && 'box-shadow: var(--drop-shadow);'}
`;
export function MessageGenericAttachment({
attachment,
direction,
highlight,
selected,
onClick,
}: {
attachment: PropsForAttachment | AttachmentTypeWithPath;
highlight: boolean;
selected: boolean;
direction?: MessageModelType;
onClick?: (e: any) => void;
}) {
// TODO add higher level pending or loading states
const { pending, fileName, fileSize, contentType } = attachment;
const extension = getExtensionForDisplay({ contentType, fileName });
return (
<StyledGenericAttachmentContainer
highlight={highlight}
selected={selected}
className={'module-message__generic-attachment'}
onClick={onClick}
>
{pending ? (
<div className="module-message__generic-attachment__spinner-container">
<Spinner size="small" />
</div>
) : (
<div className="module-message__generic-attachment__icon-container">
<div role="button" className="module-message__generic-attachment__icon">
{extension ? (
<div className="module-message__generic-attachment__icon__extension">{extension}</div>
) : null}
</div>
</div>
)}
<div className="module-message__generic-attachment__text">
<div
className={classNames(
'module-message__generic-attachment__file-name',
`module-message__generic-attachment__file-name--${direction}`
)}
>
{fileName}
</div>
<div
className={classNames(
'module-message__generic-attachment__file-size',
`module-message__generic-attachment__file-size--${direction}`
)}
>
{fileSize}
</div>
</div>
</StyledGenericAttachmentContainer>
);
}
Loading…
Cancel
Save