import React, { useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { ChannelPreviewProps } from './ChannelPreview'; import { LastMessageType } from './hooks/useChannelPreviewData'; import { useChannelPreviewDraftMessage } from './hooks/useChannelPreviewDraftMessage'; import { useChannelPreviewPollLabel } from './hooks/useChannelPreviewPollLabel'; import { useChannelTypingState } from './hooks/useChannelTypingState'; import { useChatContext } from '../../contexts/chatContext/ChatContext'; import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useTranslationContext } from '../../contexts/translationContext/TranslationContext'; import { PollIcon } from '../../icons/poll'; import { primitives } from '../../theme'; import { MessageStatusTypes } from '../../utils/utils'; import { ErrorBadge } from '../ui'; export type ChannelPreviewMessageProps = Pick & { lastMessage?: LastMessageType; }; export const ChannelPreviewMessage = (props: ChannelPreviewMessageProps) => { const { channel, lastMessage } = props; const { ChannelPreviewTypingIndicator, ChannelPreviewMessageDeliveryStatus, ChannelPreviewLastMessage, } = useComponentsContext(); const { theme: { semantics }, } = useTheme(); const isMessageDeleted = lastMessage?.type === 'deleted'; const styles = useStyles({ isMessageDeleted }); const { client } = useChatContext(); const { t } = useTranslationContext(); const { usersTyping } = useChannelTypingState({ channel }); const draftMessage = useChannelPreviewDraftMessage({ channel }); const pollLabel = useChannelPreviewPollLabel({ pollId: lastMessage?.poll_id ?? '' }); const membersWithoutSelf = useMemo(() => { return Object.values(channel.state.members).filter( (member) => member.user?.id !== client.user?.id, ); }, [channel.state.members, client.user?.id]); const isFailedMessage = lastMessage?.status === MessageStatusTypes.FAILED || lastMessage?.type === 'error'; const showMessageDeliveryStatus = !isMessageDeleted; if (usersTyping.length > 0) { return ; } if (draftMessage) { return ( {t('Draft')}: ); } // If there are no messages yet, show a message saying "No messages yet" if (!lastMessage) { return ( {t('No messages yet')} ); } if (pollLabel) { return ( {pollLabel} ); } if (isFailedMessage) { return ( {t('Message failed to send')} ); } if (channel.data?.name || membersWithoutSelf.length > 1) { return ( {showMessageDeliveryStatus ? ( ) : null} ); } else { return ( {showMessageDeliveryStatus ? ( ) : null} ); } }; const useStyles = ({ isMessageDeleted = false }: { isMessageDeleted?: boolean }) => { const { theme: { semantics, channelPreview: { message }, }, } = useTheme(); return useMemo(() => { return StyleSheet.create({ container: { flexDirection: 'row', alignItems: 'center', gap: primitives.spacingXxs, flexShrink: 1, ...message.container, }, subtitle: { color: isMessageDeleted ? semantics.textTertiary : semantics.textSecondary, fontSize: primitives.typographyFontSizeSm, fontWeight: primitives.typographyFontWeightRegular, includeFontPadding: false, lineHeight: primitives.typographyLineHeightNormal, flexShrink: 1, ...message.subtitle, }, draftText: { color: semantics.accentPrimary, fontSize: primitives.typographyFontSizeSm, fontWeight: primitives.typographyFontWeightSemiBold, lineHeight: primitives.typographyLineHeightNormal, includeFontPadding: false, ...message.draftText, }, errorText: { color: semantics.accentError, fontSize: primitives.typographyFontSizeSm, fontWeight: primitives.typographyFontWeightRegular, includeFontPadding: false, lineHeight: primitives.typographyLineHeightNormal, ...message.errorText, }, }); }, [semantics, isMessageDeleted, message]); };