UNPKG

stream-chat-react-native-core

Version:

The official React Native and Expo components for Stream Chat, a service for building chat applications

77 lines (69 loc) 2.99 kB
import { useMemo } from 'react'; import { type Attachment, isAudioAttachment, isFileAttachment, isScrapedContent, type MessageResponse, } from 'stream-chat'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { getDateString } from '../../../utils/i18n/getDateString'; /** * A single file/audio attachment paired with the message it belongs to. The file attachment list * renders one row per attachment, so a message with multiple file attachments yields multiple rows. */ export type FileAttachmentTile = { attachment: Attachment; message: MessageResponse }; export type FileAttachmentSection = { data: FileAttachmentTile[]; title: string }; /** * Gathers the file/audio attachments from a message, excluding scraped/OG link-preview content. */ const getFileAttachments = (message: MessageResponse): Attachment[] => (message.attachments ?? []).filter( (attachment) => // We provide mime_type here to avoid attachments with mime_type being categorized as file (isFileAttachment(attachment, attachment?.mime_type ? [attachment.mime_type] : []) || isAudioAttachment(attachment)) && !isScrapedContent(attachment), ); /** * Gathers and filters the file/audio attachments from a list of messages, then groups them into * newest-first month sections for the file attachment list. Each section's `data` is a flat list * of `{ attachment, message }` tiles; messages without renderable file attachments are skipped. * * The month label is produced through the shared `getDateString` + translation-key * pipeline used by message timestamps (see `useUserActivityStatus`), so the format * follows the configured locale and can be customized via the * `timestamp/FileAttachmentListSection` translation key. */ export const useFileAttachmentListSections = ( messages?: MessageResponse[], ): FileAttachmentSection[] => { const { t, tDateTimeParser } = useTranslationContext(); return useMemo<FileAttachmentSection[]>(() => { if (!messages || messages.length === 0) { return []; } const result: FileAttachmentSection[] = []; for (const message of messages) { const fileAttachments = getFileAttachments(message); if (fileAttachments.length === 0) { continue; } const formatted = getDateString({ date: message.created_at as string | Date | undefined, t, tDateTimeParser, timestampTranslationKey: 'timestamp/FileAttachmentListSection', }); const title = typeof formatted === 'string' ? formatted : String(formatted ?? ''); const tiles = fileAttachments.map((attachment) => ({ attachment, message })); const lastSection = result[result.length - 1]; if (lastSection && lastSection.title === title) { lastSection.data.push(...tiles); } else { result.push({ data: tiles, title }); } } return result; }, [messages, t, tDateTimeParser]); };