import { ChatBaseSelectorProps , getChatMessages , getIsLargeGroup , getLatestReadTime , getUserId } from './baseSelectors' ; import { toFlatCommunicationIdentifier } from '@internal/acs-ui-common' ; import { ChatClientState , ChatMessageWithStatus } from '@internal/chat-stateful-client' ; import { memoizeFnAll } from '@internal/acs-ui-common' ; import { ChatMessage , Message , CommunicationParticipant , SystemMessage , MessageContentType } from '@internal/react-components' ; import { createSelector } from 'reselect' ; import { ACSKnownMessageType } from './utils/constants' ; import { updateMessagesWithAttached } from './utils/updateMessagesWithAttached' ; const memoizedAllConvertChatMessage = memoizeFnAll ( ( _key , chatMessage , userId , isSeen , isLargeGroup ) : Message => { const messageType = chatMessage . type . toLowerCase ( ) ; if ( messageType === ACSKnownMessageType . text || messageType === ACSKnownMessageType . richtextHtml || messageType === ACSKnownMessageType . html ) { return convertToUiChatMessage ( chatMessage , userId , isSeen , isLargeGroup ) ; } else { return convertToUiSystemMessage ( chatMessage ) ; } } ) ; const convertToUiChatMessage = ( message , userId , isSeen , isLargeGroup ) : ChatMessage => { const messageSenderId = message . sender !== undefined ? toFlatCommunicationIdentifier ( message . sender ) : userId ; return { messageType : 'chat' , createdOn : message . createdOn , content : message . content ?. message , contentType : sanitizedMessageContentType ( message . type ) , status : ! isLargeGroup && message . status === 'delivered' && isSeen ? 'seen' : message . status , senderDisplayName : message . senderDisplayName , senderId : messageSenderId , messageId : message . id , clientMessageId : message . clientMessageId , editedOn : message . editedOn , deletedOn : message . deletedOn , mine : messageSenderId === userId } ; } ; const convertToUiSystemMessage = ( message ) : SystemMessage => { const systemMessageType = message . type ; if ( systemMessageType === 'participantAdded' || systemMessageType === 'participantRemoved' ) { return { messageType : 'system' , systemMessageType , createdOn : message . createdOn , participants : message . content ?. participants ?. filter ( ( participant ) => participant . displayName && participant . displayName !== '' ) . map ( ( participant ) : CommunicationParticipant => ( { userId : toFlatCommunicationIdentifier ( participant . id ) , displayName : participant . displayName } ) ) ?? [ ] , messageId : message . id , iconName : systemMessageType === 'participantAdded' ? 'PeopleAdd' : 'PeopleBlock' } ; } else { return { messageType : 'system' , systemMessageType : 'topicUpdated' , createdOn : message . createdOn , topic : message . content ?. topic ?? '' , messageId : message . id , iconName : 'Edit' } ; } } ; /**
 * Selector type for  MessageThread component.
 *
 *  public export type MessageThreadSelector = ( state : ChatClientState , props : ChatBaseSelectorProps ) => { userId : string ; showMessageStatus : boolean ; messages : Message [ ] ; } ; /** Returns `true` if the message has participants and at least one participant has a display name. */ const hasValidParticipant = ( chatMessage ) : boolean => ! ! chatMessage . content ?. participants && chatMessage . content . participants . some ( ( p ) => ! ! p . displayName ) ; /**
 * Selector for  MessageThread component.
 *
 *  public export const messageThreadSelector = createSelector ( [ getUserId , getChatMessages , getLatestReadTime , getIsLargeGroup ] , ( userId , chatMessages , latestReadTime , isLargeGroup ) => { const convertedMessages = memoizedAllConvertChatMessage ( ( memoizedFn ) => Object . values ( chatMessages ) . filter ( ( message ) => message . type . toLowerCase ( ) === ACSKnownMessageType . text || message . type . toLowerCase ( ) === ACSKnownMessageType . richtextHtml || message . type . toLowerCase ( ) === ACSKnownMessageType . html || ( message . type === ACSKnownMessageType . participantAdded && hasValidParticipant ( message ) ) || ( message . type === ACSKnownMessageType . participantRemoved && hasValidParticipant ( message ) ) || message . clientMessageId !== undefined ) . filter ( ( message ) => message . content && message . content . message !== '' ) . map ( ( message ) => memoizedFn ( message . id ?? message . clientMessageId , message , userId , message . createdOn <= latestReadTime , isLargeGroup ) ) ) ; updateMessagesWithAttached ( convertedMessages , userId ) ; return { userId , showMessageStatus : ! isLargeGroup , messages : convertedMessages } ; } ) ; const sanitizedMessageContentType = ( type ) : MessageContentType => { const lowerCaseType = type . toLowerCase ( ) ; return lowerCaseType === 'text' || lowerCaseType === 'html' || lowerCaseType === 'richtext/html' ? lowerCaseType : 'unknown' ; } ;