feat: move attachments outside of the message box
parent
d512f6911d
commit
7c80f9e233
@ -1,263 +1,142 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
areAllAttachmentsVisual,
|
areAllAttachmentsVisual,
|
||||||
AttachmentType,
|
AttachmentType,
|
||||||
AttachmentTypeWithPath,
|
AttachmentTypeWithPath,
|
||||||
getAlt,
|
getAlt,
|
||||||
getImageDimensionsInAttachment,
|
|
||||||
getThumbnailUrl,
|
getThumbnailUrl,
|
||||||
isVideoAttachment,
|
isVideoAttachment,
|
||||||
} from '../../types/Attachment';
|
} from '../../types/Attachment';
|
||||||
|
|
||||||
import { Image } from './Image';
|
import { Image } from './Image';
|
||||||
import { IsMessageVisibleContext } from './message/message-content/MessageContent';
|
import { IsMessageVisibleContext } from './message/message-content/MessageContent';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { THUMBNAIL_SIDE } from '../../types/attachments/VisualAttachment';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
attachments: Array<AttachmentTypeWithPath>;
|
attachments: Array<AttachmentTypeWithPath>;
|
||||||
bottomOverlay?: boolean;
|
|
||||||
onError: () => void;
|
onError: () => void;
|
||||||
onClickAttachment?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
|
onClickAttachment?: (attachment: AttachmentTypeWithPath | AttachmentType) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const StyledImageGrid = styled.div`
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--margins-sm);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledImageGridColumn = styled.div`
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--margins-sm);
|
||||||
|
`;
|
||||||
|
|
||||||
// tslint:disable: cyclomatic-complexity max-func-body-length use-simple-attributes
|
// tslint:disable: cyclomatic-complexity max-func-body-length use-simple-attributes
|
||||||
export const ImageGrid = (props: Props) => {
|
export const ImageGrid = (props: Props) => {
|
||||||
const { attachments, bottomOverlay, onError, onClickAttachment } = props;
|
const { attachments, onError, onClickAttachment } = props;
|
||||||
|
|
||||||
const isMessageVisible = useContext(IsMessageVisibleContext);
|
const isMessageVisible = useContext(IsMessageVisibleContext);
|
||||||
|
|
||||||
const withBottomOverlay = Boolean(bottomOverlay);
|
|
||||||
|
|
||||||
if (!attachments || !attachments.length) {
|
if (!attachments || !attachments.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachments.length === 1 || !areAllAttachmentsVisual(attachments)) {
|
const shared = {
|
||||||
const { height, width } = getImageDimensionsInAttachment(attachments[0]);
|
onClick: onClickAttachment,
|
||||||
|
onError: onError,
|
||||||
|
softCorners: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (attachments.length === 1 || !areAllAttachmentsVisual(attachments)) {
|
||||||
return (
|
return (
|
||||||
<div className={classNames('module-image-grid', 'module-image-grid--one-image')}>
|
<StyledImageGrid>
|
||||||
<Image
|
<Image
|
||||||
alt={getAlt(attachments[0])}
|
alt={getAlt(attachments[0])}
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
attachment={attachments[0]}
|
attachment={attachments[0]}
|
||||||
playIconOverlay={isVideoAttachment(attachments[0])}
|
playIconOverlay={isVideoAttachment(attachments[0])}
|
||||||
height={height}
|
height={THUMBNAIL_SIDE}
|
||||||
width={width}
|
width={THUMBNAIL_SIDE}
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={0}
|
attachmentIndex={0}
|
||||||
|
{...shared}
|
||||||
/>
|
/>
|
||||||
</div>
|
</StyledImageGrid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachments.length === 2) {
|
if (attachments.length === 2) {
|
||||||
|
// when we got 2 attachments we render them side by side with the full size of THUMBNAIL_SIDE
|
||||||
return (
|
return (
|
||||||
<div className="module-image-grid">
|
<StyledImageGrid>
|
||||||
<Image
|
<Image
|
||||||
alt={getAlt(attachments[0])}
|
alt={getAlt(attachments[0])}
|
||||||
attachment={attachments[0]}
|
attachment={attachments[0]}
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[0])}
|
playIconOverlay={isVideoAttachment(attachments[0])}
|
||||||
height={149}
|
height={THUMBNAIL_SIDE}
|
||||||
width={149}
|
width={THUMBNAIL_SIDE}
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={0}
|
attachmentIndex={0}
|
||||||
|
{...shared}
|
||||||
/>
|
/>
|
||||||
<Image
|
<Image
|
||||||
alt={getAlt(attachments[1])}
|
alt={getAlt(attachments[1])}
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[1])}
|
playIconOverlay={isVideoAttachment(attachments[1])}
|
||||||
height={149}
|
height={THUMBNAIL_SIDE}
|
||||||
width={149}
|
width={THUMBNAIL_SIDE}
|
||||||
attachment={attachments[1]}
|
attachment={attachments[1]}
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
|
url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={1}
|
attachmentIndex={1}
|
||||||
|
{...shared}
|
||||||
/>
|
/>
|
||||||
</div>
|
</StyledImageGrid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachments.length === 3) {
|
const moreMessagesOverlay = attachments.length > 3;
|
||||||
return (
|
const moreMessagesOverlayText = moreMessagesOverlay ? `+${attachments.length - 3}` : undefined;
|
||||||
<div className="module-image-grid">
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[0])}
|
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
attachment={attachments[0]}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[0])}
|
|
||||||
height={200}
|
|
||||||
width={199}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={0}
|
|
||||||
/>
|
|
||||||
<div className="module-image-grid__column">
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[1])}
|
|
||||||
height={99}
|
|
||||||
width={99}
|
|
||||||
attachment={attachments[1]}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[1])}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={1}
|
|
||||||
/>
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[2])}
|
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
height={99}
|
|
||||||
width={99}
|
|
||||||
attachment={attachments[2]}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[2])}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[2]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={2}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachments.length === 4) {
|
const columnImageSide = THUMBNAIL_SIDE / 2 - 5;
|
||||||
return (
|
|
||||||
<div className="module-image-grid">
|
|
||||||
<div className="module-image-grid__column">
|
|
||||||
<div className="module-image-grid__row">
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[0])}
|
|
||||||
attachment={attachments[0]}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[0])}
|
|
||||||
height={149}
|
|
||||||
width={149}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={0}
|
|
||||||
/>
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[1])}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[1])}
|
|
||||||
height={149}
|
|
||||||
width={149}
|
|
||||||
attachment={attachments[1]}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={1}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="module-image-grid__row">
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[2])}
|
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[2])}
|
|
||||||
height={149}
|
|
||||||
width={149}
|
|
||||||
attachment={attachments[2]}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[2]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={2}
|
|
||||||
/>
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[3])}
|
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[3])}
|
|
||||||
height={149}
|
|
||||||
width={149}
|
|
||||||
attachment={attachments[3]}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[3]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={3}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const moreMessagesOverlay = attachments.length > 5;
|
|
||||||
const moreMessagesOverlayText = moreMessagesOverlay ? `+${attachments.length - 5}` : undefined;
|
|
||||||
|
|
||||||
|
// we know only support having 3 attachments displayed at most.
|
||||||
return (
|
return (
|
||||||
<div className="module-image-grid">
|
<StyledImageGrid>
|
||||||
<div className="module-image-grid__column">
|
<Image
|
||||||
<div className="module-image-grid__row">
|
alt={getAlt(attachments[0])}
|
||||||
<Image
|
attachment={attachments[0]}
|
||||||
alt={getAlt(attachments[0])}
|
playIconOverlay={isVideoAttachment(attachments[0])}
|
||||||
attachment={attachments[0]}
|
height={THUMBNAIL_SIDE}
|
||||||
playIconOverlay={isVideoAttachment(attachments[0])}
|
width={THUMBNAIL_SIDE}
|
||||||
height={149}
|
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
||||||
width={149}
|
attachmentIndex={0}
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[0]) : undefined}
|
{...shared}
|
||||||
onClick={onClickAttachment}
|
/>
|
||||||
onError={onError}
|
<StyledImageGridColumn>
|
||||||
attachmentIndex={0}
|
<Image
|
||||||
/>
|
alt={getAlt(attachments[1])}
|
||||||
<Image
|
height={columnImageSide}
|
||||||
alt={getAlt(attachments[1])}
|
width={columnImageSide}
|
||||||
playIconOverlay={isVideoAttachment(attachments[1])}
|
attachment={attachments[1]}
|
||||||
height={149}
|
playIconOverlay={isVideoAttachment(attachments[1])}
|
||||||
width={149}
|
url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
|
||||||
attachment={attachments[1]}
|
attachmentIndex={1}
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[1]) : undefined}
|
{...shared}
|
||||||
onClick={onClickAttachment}
|
/>
|
||||||
onError={onError}
|
<Image
|
||||||
attachmentIndex={1}
|
alt={getAlt(attachments[2])}
|
||||||
/>
|
height={columnImageSide}
|
||||||
</div>
|
width={columnImageSide}
|
||||||
<div className="module-image-grid__row">
|
attachment={attachments[2]}
|
||||||
<Image
|
playIconOverlay={isVideoAttachment(attachments[2])}
|
||||||
alt={getAlt(attachments[2])}
|
url={isMessageVisible ? getThumbnailUrl(attachments[2]) : undefined}
|
||||||
bottomOverlay={withBottomOverlay}
|
attachmentIndex={2}
|
||||||
playIconOverlay={isVideoAttachment(attachments[2])}
|
darkOverlay={moreMessagesOverlay}
|
||||||
height={99}
|
overlayText={moreMessagesOverlayText}
|
||||||
width={99}
|
{...shared}
|
||||||
attachment={attachments[2]}
|
/>
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[2]) : undefined}
|
</StyledImageGridColumn>
|
||||||
onClick={onClickAttachment}
|
</StyledImageGrid>
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={2}
|
|
||||||
/>
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[3])}
|
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[3])}
|
|
||||||
height={99}
|
|
||||||
width={98}
|
|
||||||
attachment={attachments[3]}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[3]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={3}
|
|
||||||
/>
|
|
||||||
<Image
|
|
||||||
alt={getAlt(attachments[4])}
|
|
||||||
bottomOverlay={withBottomOverlay}
|
|
||||||
playIconOverlay={isVideoAttachment(attachments[4])}
|
|
||||||
height={99}
|
|
||||||
width={99}
|
|
||||||
darkOverlay={moreMessagesOverlay}
|
|
||||||
overlayText={moreMessagesOverlayText}
|
|
||||||
attachment={attachments[4]}
|
|
||||||
url={isMessageVisible ? getThumbnailUrl(attachments[4]) : undefined}
|
|
||||||
onClick={onClickAttachment}
|
|
||||||
onError={onError}
|
|
||||||
attachmentIndex={4}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue