// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { ReactNode, FunctionComponent } from 'react'; import classNames from 'classnames'; import { isBoolean, isNumber } from 'lodash'; import { Avatar, AvatarSize } from '../Avatar'; import { Timestamp } from '../conversation/Timestamp'; import { isConversationUnread } from '../../util/isConversationUnread'; import { cleanId } from '../_util'; import { LocalizerType } from '../../types/Util'; import { ConversationType } from '../../state/ducks/conversations'; const BASE_CLASS_NAME = 'module-conversation-list__item--contact-or-conversation'; const CONTENT_CLASS_NAME = `${BASE_CLASS_NAME}__content`; const HEADER_CLASS_NAME = `${CONTENT_CLASS_NAME}__header`; export const DATE_CLASS_NAME = `${HEADER_CLASS_NAME}__date`; const TIMESTAMP_CLASS_NAME = `${DATE_CLASS_NAME}__timestamp`; const MESSAGE_CLASS_NAME = `${CONTENT_CLASS_NAME}__message`; export const MESSAGE_TEXT_CLASS_NAME = `${MESSAGE_CLASS_NAME}__text`; const CHECKBOX_CLASS_NAME = `${BASE_CLASS_NAME}__checkbox`; type PropsType = { checked?: boolean; conversationType: 'group' | 'direct'; disabled?: boolean; headerDate?: number; headerName: ReactNode; id?: string; i18n: LocalizerType; isNoteToSelf?: boolean; isSelected: boolean; markedUnread?: boolean; messageId?: string; messageStatusIcon?: ReactNode; messageText?: ReactNode; onClick?: () => void; unreadCount?: number; } & Pick< ConversationType, | 'acceptedMessageRequest' | 'avatarPath' | 'color' | 'isMe' | 'markedUnread' | 'name' | 'phoneNumber' | 'profileName' | 'sharedGroupNames' | 'title' | 'unblurredAvatarPath' >; export const BaseConversationListItem: FunctionComponent = React.memo( function BaseConversationListItem({ acceptedMessageRequest, avatarPath, checked, color, conversationType, disabled, headerDate, headerName, i18n, id, isMe, isNoteToSelf, isSelected, markedUnread, messageStatusIcon, messageText, name, onClick, phoneNumber, profileName, sharedGroupNames, title, unblurredAvatarPath, unreadCount, }) { const isUnread = isConversationUnread({ markedUnread, unreadCount }); const isAvatarNoteToSelf = isBoolean(isNoteToSelf) ? isNoteToSelf : Boolean(isMe); const isCheckbox = isBoolean(checked); let checkboxNode: ReactNode; if (isCheckbox) { let ariaLabel: string; if (disabled) { ariaLabel = i18n('cannotSelectContact'); } else if (checked) { ariaLabel = i18n('deselectContact'); } else { ariaLabel = i18n('selectContact'); } checkboxNode = ( { if (onClick && !disabled && event.key === 'Enter') { onClick(); } }} type="checkbox" /> ); } const contents = ( <>
{isUnread && (
{unreadCount || ''}
)}
{headerName}
{isNumber(headerDate) && (
)}
{messageText ? (
{messageText}
{messageStatusIcon}
) : null}
{checkboxNode} ); const commonClassNames = classNames(BASE_CLASS_NAME, { [`${BASE_CLASS_NAME}--has-unread`]: isUnread, [`${BASE_CLASS_NAME}--is-selected`]: isSelected, }); if (isCheckbox) { return ( ); } if (onClick) { return ( ); } return (
{contents}
); } );