import React from 'react'; import classNames from 'classnames'; import { isEmpty } from 'lodash'; import { ContextMenu, ContextMenuTrigger, MenuItem } from 'react-contextmenu'; import { Portal } from 'react-portal'; import { Avatar } from './Avatar'; import { MessageBody } from './conversation/MessageBody'; import { Timestamp } from './conversation/Timestamp'; import { ContactName } from './conversation/ContactName'; import { TypingAnimation } from './conversation/TypingAnimation'; import { Colors, LocalizerType } from '../types/Util'; import { getBlockMenuItem, getClearNicknameMenuItem, getCopyMenuItem, getDeleteContactMenuItem, getDeleteMessagesMenuItem, getInviteContactMenuItem, getLeaveGroupMenuItem, } from '../session/utils/Menu'; export type PropsData = { id: string; phoneNumber: string; color?: string; profileName?: string; name?: string; type: 'group' | 'direct'; avatarPath?: string; isMe: boolean; isPublic?: boolean; isRss?: boolean; isClosable?: boolean; primaryDevice?: string; lastUpdated: number; unreadCount: number; mentionedUs: boolean; isSelected: boolean; isTyping: boolean; lastMessage?: { status: 'sending' | 'sent' | 'delivered' | 'read' | 'error'; text: string; isRss: boolean; }; isBlocked?: boolean; isOnline?: boolean; hasNickname?: boolean; isSecondary?: boolean; isGroupInvitation?: boolean; isKickedFromGroup?: boolean; }; type PropsHousekeeping = { i18n: LocalizerType; style?: Object; onClick?: (id: string) => void; onDeleteMessages?: () => void; onDeleteContact?: () => void; onBlockContact?: () => void; onChangeNickname?: () => void; onClearNickname?: () => void; onCopyPublicKey?: () => void; onUnblockContact?: () => void; onInviteContacts?: () => void; }; type Props = PropsData & PropsHousekeeping; export class ConversationListItem extends React.PureComponent { public renderAvatar() { const { avatarPath, color, type, i18n, isMe, name, phoneNumber, profileName, isOnline, } = this.props; const borderColor = isOnline ? Colors.ONLINE : Colors.OFFLINE; const iconSize = 36; return (
); } public renderUnread() { const { unreadCount, mentionedUs } = this.props; if (unreadCount > 0) { const atSymbol = mentionedUs ?

@

: null; return (

{unreadCount}

{atSymbol}
); } return null; } public renderHeader() { const { unreadCount, i18n, isMe, lastUpdated } = this.props; return (
0 ? 'module-conversation-list-item__header__name--with-unread' : null )} > {this.renderUser()}
{this.renderUnread()} {
0 ? 'module-conversation-list-item__header__date--has-unread' : null )} > { }
}
); } public renderContextMenu(triggerId: string) { const { i18n, isBlocked, isMe, isClosable, isRss, isPublic, hasNickname, type, isKickedFromGroup, onDeleteContact, onDeleteMessages, onBlockContact, onClearNickname, onCopyPublicKey, onUnblockContact, onInviteContacts, } = this.props; const isPrivate = type === 'direct'; return ( {getBlockMenuItem( isMe, isPrivate, isBlocked, onBlockContact, onUnblockContact, i18n )} {/* {!isPublic && !isRss && !isMe ? ( {i18n('changeNickname')} ) : null} */} {getClearNicknameMenuItem( isPublic, isRss, isMe, hasNickname, onClearNickname, i18n )} {getCopyMenuItem( isPublic, isRss, type === 'group', onCopyPublicKey, i18n )} {getDeleteMessagesMenuItem(isPublic, onDeleteMessages, i18n)} {getInviteContactMenuItem( type === 'group', isPublic, onInviteContacts, i18n )} {getDeleteContactMenuItem( isMe, isClosable, type === 'group', isPublic, isRss, onDeleteContact, i18n )} {getLeaveGroupMenuItem( isKickedFromGroup, type === 'group', isPublic, isRss, onDeleteContact, i18n )} ); } public renderMessage() { const { lastMessage, isTyping, unreadCount, i18n } = this.props; if (!lastMessage && !isTyping) { return null; } let text = lastMessage && lastMessage.text ? lastMessage.text : ''; // if coming from Rss feed if (lastMessage && lastMessage.isRss) { // strip any HTML text = text.replace(/<[^>]*>?/gm, ''); } if (isEmpty(text)) { return null; } return (
0 ? 'module-conversation-list-item__message__text--has-unread' : null )} > {isTyping ? ( ) : ( )}
{lastMessage && lastMessage.status ? (
) : null}
); } public render() { const { phoneNumber, unreadCount, onClick, id, isSelected, isBlocked, style, mentionedUs, } = this.props; const triggerId = `conversation-item-${phoneNumber}-ctxmenu`; return (
{ if (onClick) { onClick(id); } }} style={style} className={classNames( 'module-conversation-list-item', unreadCount > 0 ? 'module-conversation-list-item--has-unread' : null, unreadCount > 0 && mentionedUs ? 'module-conversation-list-item--mentioned-us' : null, isSelected ? 'module-conversation-list-item--is-selected' : null, isBlocked ? 'module-conversation-list-item--is-blocked' : null )} > {this.renderAvatar()}
{this.renderHeader()} {this.renderMessage()}
{this.renderContextMenu(triggerId)}
); } private renderUser() { const { name, phoneNumber, profileName, isMe, i18n } = this.props; const shortenedPubkey = window.shortenPubkey(phoneNumber); const displayedPubkey = profileName ? shortenedPubkey : phoneNumber; const displayName = isMe ? i18n('noteToSelf') : profileName; return (
); } }