import React from 'react'; import classNames from 'classnames'; import { isImageTypeSupported, isVideoTypeSupported, } from '../../util/GoogleChrome'; import { AttachmentType } from './types'; import { Image } from './Image'; import { Localizer } from '../../types/Util'; interface Props { attachments: Array; withContentAbove?: boolean; withContentBelow?: boolean; bottomOverlay?: boolean; i18n: Localizer; onError: () => void; onClickAttachment?: (attachment: AttachmentType) => void; } const MAX_WIDTH = 300; const MAX_HEIGHT = MAX_WIDTH * 1.5; const MIN_WIDTH = 200; const MIN_HEIGHT = 50; export class ImageGrid extends React.Component { // tslint:disable-next-line max-func-body-length */ public render() { const { attachments, bottomOverlay, i18n, onError, onClickAttachment, withContentAbove, withContentBelow, } = this.props; const curveTopLeft = !Boolean(withContentAbove); const curveTopRight = curveTopLeft; const curveBottom = !Boolean(withContentBelow); const curveBottomLeft = curveBottom; const curveBottomRight = curveBottom; if (!attachments || !attachments.length) { return null; } if (attachments.length === 1 || !areAllAttachmentsVisual(attachments)) { const { height, width } = getImageDimensions(attachments[0]); return (
{getAlt(attachments[0],
); } if (attachments.length === 2) { return (
{getAlt(attachments[0], {getAlt(attachments[1],
); } if (attachments.length === 3) { return (
{getAlt(attachments[0],
{getAlt(attachments[1], {getAlt(attachments[2],
); } if (attachments.length === 4) { return (
{getAlt(attachments[0], {getAlt(attachments[1],
{getAlt(attachments[2], {getAlt(attachments[3],
); } return (
{getAlt(attachments[0], {getAlt(attachments[1],
{getAlt(attachments[2], {getAlt(attachments[3], {getAlt(attachments[4], 5} overlayText={ attachments.length > 5 ? `+${attachments.length - 5}` : undefined } attachment={attachments[4]} url={getThumbnailUrl(attachments[4])} onClick={onClickAttachment} onError={onError} />
); } } function getThumbnailUrl(attachment: AttachmentType) { if (attachment.thumbnail) { return attachment.thumbnail.url; } return getUrl(attachment); } function getUrl(attachment: AttachmentType) { if (attachment.screenshot) { return attachment.screenshot.url; } return attachment.url; } export function isImage(attachments?: Array) { return ( attachments && attachments[0] && attachments[0].contentType && isImageTypeSupported(attachments[0].contentType) ); } export function isImageAttachment(attachment: AttachmentType) { return ( attachment && attachment.contentType && isImageTypeSupported(attachment.contentType) ); } export function hasImage(attachments?: Array) { return ( attachments && attachments[0] && (attachments[0].url || attachments[0].pending) ); } export function isVideo(attachments?: Array) { return attachments && isVideoAttachment(attachments[0]); } export function isVideoAttachment(attachment?: AttachmentType) { return ( attachment && attachment.contentType && isVideoTypeSupported(attachment.contentType) ); } export function hasVideoScreenshot(attachments?: Array) { const firstAttachment = attachments ? attachments[0] : null; return ( firstAttachment && firstAttachment.screenshot && firstAttachment.screenshot.url ); } type DimensionsType = { height: number; width: number; }; export function getImageDimensions(attachment: AttachmentType): DimensionsType { const { height, width } = attachment; if (!height || !width) { return { height: MIN_HEIGHT, width: MIN_WIDTH, }; } const aspectRatio = height / width; const targetWidth = Math.max(Math.min(MAX_WIDTH, width), MIN_WIDTH); const candidateHeight = Math.round(targetWidth * aspectRatio); return { width: targetWidth, height: Math.max(Math.min(MAX_HEIGHT, candidateHeight), MIN_HEIGHT), }; } export function areAllAttachmentsVisual( attachments?: Array ): boolean { if (!attachments) { return false; } const max = attachments.length; for (let i = 0; i < max; i += 1) { const attachment = attachments[i]; if (!isImageAttachment(attachment) && !isVideoAttachment(attachment)) { return false; } } return true; } export function getGridDimensions( attachments?: Array ): null | DimensionsType { if (!attachments || !attachments.length) { return null; } if (!isImage(attachments) && !isVideo(attachments)) { return null; } if (attachments.length === 1) { return getImageDimensions(attachments[0]); } if (attachments.length === 2) { return { height: 150, width: 300, }; } if (attachments.length === 4) { return { height: 300, width: 300, }; } return { height: 200, width: 300, }; } export function getAlt(attachment: AttachmentType, i18n: Localizer): string { return isVideoAttachment(attachment) ? i18n('videoAttachmentAlt') : i18n('imageAttachmentAlt'); }