import React, { useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import type { Attachment, LocalMessage } from 'stream-chat'; import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext'; import { useComponentsContext } from '../../../contexts/componentsContext/ComponentsContext'; import { Alignment, MessageContextValue, useMessageContext, } from '../../../contexts/messageContext/MessageContext'; import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext'; import { primitives } from '../../../theme'; import { isEditedMessage, MessageStatusTypes } from '../../../utils/utils'; import { useShouldUseOverlayStyles } from '../hooks/useShouldUseOverlayStyles'; type MessageFooterComponentProps = { date?: string | Date; formattedDate?: string | Date; }; type MessageFooterPropsWithContext = Pick< MessageContextValue, | 'alignment' | 'members' | 'message' | 'showMessageStatus' | 'lastGroupMessage' | 'isMessageAIGenerated' > & MessageFooterComponentProps; const MessageFooterWithContext = (props: MessageFooterPropsWithContext) => { const { alignment, date, formattedDate, isMessageAIGenerated, lastGroupMessage, members, message, showMessageStatus, } = props; const { MessageStatus, MessageTimestamp } = useComponentsContext(); const styles = useStyles(); const { theme: { messageItemView: { footer: { container, name, editedText }, }, }, } = useTheme(); const { t } = useTranslationContext(); const isAIGenerated = useMemo( () => isMessageAIGenerated(message), [message, isMessageAIGenerated], ); if (lastGroupMessage === false && message.status === MessageStatusTypes.RECEIVED) { return null; } const isEdited = isEditedMessage(message) && !isAIGenerated; return ( {Object.keys(members).length > 2 && alignment === 'left' && message.user?.name ? ( {message.user.name} ) : null} {showMessageStatus ? : null} {isEdited ? {t('Edited')} : null} ); }; const areEqual = ( prevProps: MessageFooterPropsWithContext, nextProps: MessageFooterPropsWithContext, ) => { const { alignment: prevAlignment, date: prevDate, formattedDate: prevFormattedDate, lastGroupMessage: prevLastGroupMessage, members: prevMembers, message: prevMessage, showMessageStatus: prevShowMessageStatus, } = prevProps; const { alignment: nextAlignment, date: nextDate, formattedDate: nextFormattedDate, lastGroupMessage: nextLastGroupMessage, members: nextMembers, message: nextMessage, showMessageStatus: nextShowMessageStatus, } = nextProps; const alignmentEqual = prevAlignment === nextAlignment; if (!alignmentEqual) { return false; } const membersEqual = Object.keys(prevMembers).length === Object.keys(nextMembers).length; if (!membersEqual) { return false; } const lastGroupMessageEqual = prevLastGroupMessage === nextLastGroupMessage; if (!lastGroupMessageEqual) { return false; } const isPrevMessageTypeDeleted = prevMessage.type === 'deleted'; const isNextMessageTypeDeleted = nextMessage.type === 'deleted'; const messageEqual = isPrevMessageTypeDeleted === isNextMessageTypeDeleted && prevMessage.reply_count === nextMessage.reply_count && prevMessage.status === nextMessage.status && prevMessage.type === nextMessage.type && prevMessage.text === nextMessage.text && prevMessage.pinned === nextMessage.pinned; if (!messageEqual) { return false; } const showMessageStatusEqual = prevShowMessageStatus === nextShowMessageStatus; if (!showMessageStatusEqual) { return false; } const dateEqual = prevDate === nextDate; if (!dateEqual) { return false; } const formattedDateEqual = prevFormattedDate === nextFormattedDate; if (!formattedDateEqual) { return false; } return true; }; const MemoizedMessageFooter = React.memo( MessageFooterWithContext, areEqual, ) as typeof MessageFooterWithContext; export type MessageFooterProps = Partial> & MessageFooterComponentProps & { alignment?: Alignment; lastGroupMessage?: boolean; message?: LocalMessage; otherAttachments?: Attachment[]; showMessageStatus?: boolean; }; export const MessageFooter = (props: MessageFooterProps) => { const { alignment, isMessageAIGenerated, lastGroupMessage, members, message, showMessageStatus } = useMessageContext(); return ( ); }; const useStyles = () => { const { theme: { semantics }, } = useTheme(); const shouldUseOverlayStyles = useShouldUseOverlayStyles(); return useMemo(() => { return StyleSheet.create({ container: { maxWidth: '100%', alignItems: 'center', flexDirection: 'row', justifyContent: 'center', paddingVertical: primitives.spacingXxs, gap: primitives.spacingXs, }, name: { flexShrink: 1, color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextUsername, fontSize: primitives.typographyFontSizeXs, fontWeight: primitives.typographyFontWeightSemiBold, lineHeight: primitives.typographyLineHeightTight, }, editedText: { color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp, fontSize: primitives.typographyFontSizeXs, fontWeight: primitives.typographyFontWeightRegular, lineHeight: primitives.typographyLineHeightTight, }, }); }, [ shouldUseOverlayStyles, semantics.chatTextTimestamp, semantics.chatTextUsername, semantics.textOnAccent, ]); };