// Copyright 2018 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { useEffect, useRef } from 'react'; import moment from 'moment'; import type { ItemClickEvent } from './types/ItemClickEvent'; import type { LocalizerType } from '../../../types/Util'; import type { MediaItemType } from '../../../types/MediaItem'; import type { SaveAttachmentActionCreatorType } from '../../../state/ducks/conversations'; import { AttachmentSection } from './AttachmentSection'; import { EmptyState } from './EmptyState'; import { Tabs } from '../../Tabs'; import { getMessageTimestamp } from '../../../util/getMessageTimestamp'; import { groupMediaItemsByDate } from './groupMediaItemsByDate'; import { missingCaseError } from '../../../util/missingCaseError'; enum TabViews { Media = 'Media', Documents = 'Documents', } export type Props = { conversationId: string; documents: Array; i18n: LocalizerType; loadMediaItems: (id: string) => unknown; media: Array; saveAttachment: SaveAttachmentActionCreatorType; showLightboxWithMedia: ( selectedIndex: number, media: Array ) => void; }; const MONTH_FORMAT = 'MMMM YYYY'; function MediaSection({ type, i18n, media, documents, saveAttachment, showLightboxWithMedia, }: Pick< Props, 'i18n' | 'media' | 'documents' | 'showLightboxWithMedia' | 'saveAttachment' > & { type: 'media' | 'documents' }): JSX.Element { const mediaItems = type === 'media' ? media : documents; if (!mediaItems || mediaItems.length === 0) { const label = (() => { switch (type) { case 'media': return i18n('icu:mediaEmptyState'); case 'documents': return i18n('icu:documentsEmptyState'); default: throw missingCaseError(type); } })(); return ; } const now = Date.now(); const sections = groupMediaItemsByDate(now, mediaItems).map(section => { const first = section.mediaItems[0]; const { message } = first; const date = moment(getMessageTimestamp(message)); function getHeader(): string { switch (section.type) { case 'yearMonth': return date.format(MONTH_FORMAT); case 'today': return i18n('icu:today'); case 'yesterday': return i18n('icu:yesterday'); case 'thisWeek': return i18n('icu:thisWeek'); case 'thisMonth': return i18n('icu:thisMonth'); default: throw missingCaseError(section); } } const header = getHeader(); return ( { switch (event.type) { case 'documents': { saveAttachment(event.attachment, event.message.sent_at); break; } case 'media': { showLightboxWithMedia(event.index, media); break; } default: throw new TypeError(`Unknown attachment type: '${event.type}'`); } }} /> ); }); return
{sections}
; } export function MediaGallery({ conversationId, documents, i18n, loadMediaItems, media, saveAttachment, showLightboxWithMedia, }: Props): JSX.Element { const focusRef = useRef(null); useEffect(() => { focusRef.current?.focus(); }, []); useEffect(() => { loadMediaItems(conversationId); }, [conversationId, loadMediaItems]); return (
{({ selectedTab }) => (
{selectedTab === TabViews.Media && ( )} {selectedTab === TabViews.Documents && ( )}
)}
); }