// Copyright 2018-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { useCallback, CSSProperties, FunctionComponent, ReactNode, } from 'react'; import classNames from 'classnames'; import { BaseConversationListItem, MESSAGE_TEXT_CLASS_NAME, } from './BaseConversationListItem'; import { MessageBody } from '../conversation/MessageBody'; import { ContactName } from '../conversation/ContactName'; import { TypingAnimation } from '../conversation/TypingAnimation'; import { LocalizerType } from '../../types/Util'; import { ColorType } from '../../types/Colors'; const MESSAGE_STATUS_ICON_CLASS_NAME = `${MESSAGE_TEXT_CLASS_NAME}__status-icon`; export const MessageStatuses = [ 'sending', 'sent', 'delivered', 'read', 'error', 'partial-sent', ] as const; export type MessageStatusType = typeof MessageStatuses[number]; export type PropsData = { id: string; phoneNumber?: string; color?: ColorType; profileName?: string; title: string; name?: string; type: 'group' | 'direct'; avatarPath?: string; isMe?: boolean; muteExpiresAt?: number; lastUpdated?: number; unreadCount?: number; markedUnread?: boolean; isSelected?: boolean; acceptedMessageRequest?: boolean; draftPreview?: string; shouldShowDraft?: boolean; typingContact?: unknown; lastMessage?: { status: MessageStatusType; text: string; deletedForEveryone?: boolean; }; isPinned?: boolean; }; type PropsHousekeeping = { i18n: LocalizerType; style: CSSProperties; onClick: (id: string) => void; }; export type Props = PropsData & PropsHousekeeping; export const ConversationListItem: FunctionComponent = React.memo( ({ acceptedMessageRequest, avatarPath, color, draftPreview, i18n, id, isMe, isSelected, lastMessage, lastUpdated, markedUnread, muteExpiresAt, name, onClick, phoneNumber, profileName, shouldShowDraft, style, title, type, typingContact, unreadCount, }) => { const headerName = isMe ? ( i18n('noteToSelf') ) : ( ); let messageText: ReactNode = null; let messageStatusIcon: ReactNode = null; if (lastMessage || typingContact) { const messageBody = lastMessage ? lastMessage.text : ''; const showingDraft = shouldShowDraft && draftPreview; const deletedForEveryone = Boolean( lastMessage && lastMessage.deletedForEveryone ); /* eslint-disable no-nested-ternary */ messageText = ( <> {muteExpiresAt && Date.now() < muteExpiresAt && ( )} {!acceptedMessageRequest ? ( {i18n('ConversationListItem--message-request')} ) : typingContact ? ( ) : ( <> {showingDraft ? ( <> {i18n('ConversationListItem--draft-prefix')} ) : deletedForEveryone ? ( {i18n('message--deletedForEveryone')} ) : ( )} )} ); /* eslint-enable no-nested-ternary */ if (!showingDraft && lastMessage && lastMessage.status) { messageStatusIcon = (
); } } const onClickItem = useCallback(() => onClick(id), [onClick, id]); return ( ); } );