import React, { useCallback } from 'react'; import classNames from 'classnames'; import { isEmpty } from 'lodash'; import { contextMenu } from 'react-contexify'; import { Avatar, AvatarSize } from './Avatar'; import { MessageBody } from './conversation/MessageBody'; import { Timestamp } from './conversation/Timestamp'; import { ContactName } from './conversation/ContactName'; import { TypingAnimation } from './conversation/TypingAnimation'; import { ConversationAvatar } from './session/usingClosedConversationDetails'; import { MemoConversationListItemContextMenu } from './session/menu/ConversationListItemContextMenu'; import { createPortal } from 'react-dom'; import { OutgoingMessageStatus } from './conversation/message/OutgoingMessageStatus'; import { useTheme } from 'styled-components'; import { PubKey } from '../session/types'; import { LastMessageType, openConversationExternal, ReduxConversationType, } from '../state/ducks/conversations'; import _ from 'underscore'; import { useMembersAvatars } from '../hooks/useMembersAvatar'; import { SessionIcon, SessionIconSize, SessionIconType } from './session/icon'; import { useDispatch, useSelector } from 'react-redux'; import { SectionType } from '../state/ducks/section'; import { getFocusedSection } from '../state/selectors/section'; import { getFirstUnreadMessageIdInConversation } from '../data/data'; // tslint:disable-next-line: no-empty-interface export interface ConversationListItemProps extends ReduxConversationType {} type PropsHousekeeping = { style?: Object; }; type Props = ConversationListItemProps & PropsHousekeeping; const Portal = ({ children }: { children: any }) => { return createPortal(children, document.querySelector('.inbox.index') as Element); }; const HeaderItem = (props: { unreadCount: number; isMe: boolean; mentionedUs: boolean; activeAt?: number; name?: string; profileName?: string; conversationId: string; isPinned: boolean; }) => { const { unreadCount, mentionedUs, activeAt, isMe, isPinned, conversationId, profileName, name, } = props; const theme = useTheme(); let atSymbol = null; let unreadCountDiv = null; if (unreadCount > 0) { atSymbol = mentionedUs ?

@

: null; unreadCountDiv =

{unreadCount}

; } const isMessagesSection = useSelector(getFocusedSection) === SectionType.Message; const pinIcon = isMessagesSection && isPinned ? ( ) : null; return (
0 ? 'module-conversation-list-item__header__name--with-unread' : null )} >
{pinIcon} {unreadCountDiv} {atSymbol} {
0 ? 'module-conversation-list-item__header__date--has-unread' : null )} > {}
}
); }; const UserItem = (props: { name?: string; profileName?: string; isMe: boolean; conversationId: string; }) => { const { name, conversationId, profileName, isMe } = props; const shortenedPubkey = PubKey.shorten(conversationId); const displayedPubkey = profileName ? shortenedPubkey : conversationId; const displayName = isMe ? window.i18n('noteToSelf') : profileName; let shouldShowPubkey = false; if ((!name || name.length === 0) && (!displayName || displayName.length === 0)) { shouldShowPubkey = true; } return (
); }; const MessageItem = (props: { lastMessage?: LastMessageType; isTyping: boolean; unreadCount: number; }) => { const { lastMessage, isTyping, unreadCount } = props; const theme = useTheme(); if (!lastMessage && !isTyping) { return null; } const text = lastMessage && lastMessage.text ? lastMessage.text : ''; if (isEmpty(text)) { return null; } return (
0 ? 'module-conversation-list-item__message__text--has-unread' : null )} > {isTyping ? ( ) : ( )}
{lastMessage && lastMessage.status ? ( ) : null}
); }; const AvatarItem = (props: { avatarPath?: string; conversationId: string; memberAvatars?: Array; name?: string; profileName?: string; }) => { const { avatarPath, name, conversationId, profileName, memberAvatars } = props; const userName = name || profileName || conversationId; return (
); }; const ConversationListItem = (props: Props) => { const { activeAt, unreadCount, id: conversationId, isSelected, isBlocked, style, mentionedUs, isMe, name, isPinned, profileName, isTyping, lastMessage, hasNickname, isKickedFromGroup, left, type, isPublic, avatarPath, notificationForConvo, currentNotificationSetting, } = props; const triggerId = `conversation-item-${conversationId}-ctxmenu`; const key = `conversation-item-${conversationId}`; const membersAvatar = useMembersAvatars(props); const dispatch = useDispatch(); const openConvo = useCallback(async () => { const firstUnreadIdOnOpen = await getFirstUnreadMessageIdInConversation(conversationId); dispatch(openConversationExternal({ id: conversationId, firstUnreadIdOnOpen })); }, [conversationId]); return (
{ contextMenu.show({ id: triggerId, event: e, }); }} 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 )} >
); }; export const MemoConversationListItemWithDetails = React.memo(ConversationListItem, _.isEqual);