// Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { useEffect, useState } from 'react'; import classNames from 'classnames'; import { Blurhash } from 'react-blurhash'; import type { AttachmentType } from '../types/Attachment'; import type { LocalizerType } from '../types/Util'; import { Spinner } from './Spinner'; import { TextAttachment } from './TextAttachment'; import { ThemeType } from '../types/Util'; import { defaultBlurHash, isDownloaded, hasNotResolved, isDownloading, } from '../types/Attachment'; import { getClassNamesFor } from '../util/getClassNamesFor'; export type PropsType = { readonly attachment?: AttachmentType; i18n: LocalizerType; readonly isThumbnail?: boolean; readonly label: string; readonly moduleClassName?: string; readonly queueStoryDownload: (storyId: string) => unknown; readonly storyId: string; }; export const StoryImage = ({ attachment, i18n, isThumbnail, label, moduleClassName, queueStoryDownload, storyId, }: PropsType): JSX.Element | null => { const [attachmentBroken, setAttachmentBroken] = useState(false); const shouldDownloadAttachment = !isDownloaded(attachment) && !isDownloading(attachment); useEffect(() => { if (shouldDownloadAttachment) { queueStoryDownload(storyId); } }, [queueStoryDownload, shouldDownloadAttachment, storyId]); if (!attachment) { return null; } const isPending = Boolean(attachment.pending); const isNotReadyToShow = hasNotResolved(attachment) || isPending; const getClassName = getClassNamesFor('StoryImage', moduleClassName); let storyElement: JSX.Element; if (attachment.textAttachment) { storyElement = ( ); } else if (isNotReadyToShow) { storyElement = ( ); } else if (attachmentBroken) { storyElement = (
); } else { storyElement = ( {label} setAttachmentBroken(true)} src={ isThumbnail && attachment.thumbnail ? attachment.thumbnail.url : attachment.url } /> ); } let spinner: JSX.Element | undefined; if (isPending) { spinner = (
); } return (
{storyElement} {spinner}
); };