import React from 'react'; import { AttachmentActions as AttachmentActionsDefault } from '../../components/Attachment/AttachmentActions'; import { Card as CardDefault } from '../../components/Attachment/Card'; import { Gallery as GalleryDefault } from '../../components/Attachment/Gallery'; import { Giphy as GiphyDefault } from '../../components/Attachment/Giphy'; import { FileAttachment as FileAttachmentDefault } from '../../components/Attachment/FileAttachment'; import { MessagesContextValue, useMessagesContext, } from '../../contexts/messagesContext/MessagesContext'; import type { Attachment as AttachmentType } from 'stream-chat'; import type { DefaultAttachmentType, DefaultChannelType, DefaultCommandType, DefaultEventType, DefaultMessageType, DefaultReactionType, DefaultUserType, UnknownType, } from '../../types/types'; export type ActionHandler = (name: string, value: string) => void; export type AttachmentPropsWithContext< At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, > = Pick< MessagesContextValue, 'AttachmentActions' | 'Card' | 'FileAttachment' | 'Gallery' | 'Giphy' | 'UrlPreview' > & { /** * The attachment to render */ attachment: AttachmentType; }; const AttachmentWithContext = < At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, >( props: AttachmentPropsWithContext, ) => { const { attachment, AttachmentActions, Card, FileAttachment, Gallery, Giphy, UrlPreview } = props; const hasAttachmentActions = !!attachment.actions?.length; if (attachment.type === 'giphy' || attachment.type === 'imgur') { return ; } if ( (attachment.title_link || attachment.og_scrape_url) && (attachment.image_url || attachment.thumb_url) ) { return ; } if (attachment.type === 'image') { return ( <> {hasAttachmentActions && ( )} ); } if (attachment.type === 'file' || attachment.type === 'audio') { return ; } if (attachment.type === 'video' && attachment.asset_url) { return ( // TODO: Put in video component ); } if (hasAttachmentActions) { return ( <> ); } else { return ; } }; const areEqual = < At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, >( prevProps: AttachmentPropsWithContext, nextProps: AttachmentPropsWithContext, ) => { const { attachment: prevAttachment } = prevProps; const { attachment: nextAttachment } = nextProps; const attachmentEqual = prevAttachment.actions?.length === nextAttachment.actions?.length && prevAttachment.image_url === nextAttachment.image_url && prevAttachment.thumb_url === nextAttachment.thumb_url; return attachmentEqual; }; const MemoizedAttachment = React.memo( AttachmentWithContext, areEqual, ) as typeof AttachmentWithContext; export type AttachmentProps< At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, > = Partial< Pick< MessagesContextValue, 'AttachmentActions' | 'Card' | 'FileAttachment' | 'Gallery' | 'Giphy' | 'UrlPreview' > > & Pick, 'attachment'>; /** * Attachment - The message attachment */ export const Attachment = < At extends UnknownType = DefaultAttachmentType, Ch extends UnknownType = DefaultChannelType, Co extends string = DefaultCommandType, Ev extends UnknownType = DefaultEventType, Me extends UnknownType = DefaultMessageType, Re extends UnknownType = DefaultReactionType, Us extends UnknownType = DefaultUserType, >( props: AttachmentProps, ) => { const { attachment, AttachmentActions: PropAttachmentActions, Card: PropCard, FileAttachment: PropFileAttachment, Gallery: PropGallery, Giphy: PropGiphy, UrlPreview: PropUrlPreview, } = props; const { AttachmentActions: ContextAttachmentActions, Card: ContextCard, FileAttachment: ContextFileAttachment, Gallery: ContextGallery, Giphy: ContextGiphy, UrlPreview: ContextUrlPreview, } = useMessagesContext(); if (!attachment) { return null; } const AttachmentActions = PropAttachmentActions || ContextAttachmentActions || AttachmentActionsDefault; const Card = PropCard || ContextCard || CardDefault; const FileAttachment = PropFileAttachment || ContextFileAttachment || FileAttachmentDefault; const Gallery = PropGallery || ContextGallery || GalleryDefault; const Giphy = PropGiphy || ContextGiphy || GiphyDefault; const UrlPreview = PropUrlPreview || ContextUrlPreview || CardDefault; return ( ); };