// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import type { FunctionComponent } from 'react'; import React, { useMemo, useState } from 'react'; import { HEADER_CONTACT_NAME_CLASS_NAME } from './BaseConversationListItem'; import type { ConversationType } from '../../state/ducks/conversations'; import type { BadgeType } from '../../badges/types'; import type { LocalizerType, ThemeType } from '../../types/Util'; import { ContactName } from '../conversation/ContactName'; import { About } from '../conversation/About'; import { ListTile } from '../ListTile'; import { Avatar, AvatarSize } from '../Avatar'; import { ContextMenu } from '../ContextMenu'; import { I18n } from '../I18n'; import { ConfirmationDialog } from '../ConfirmationDialog'; import { isSignalConversation } from '../../util/isSignalConversation'; import { isInSystemContacts } from '../../util/isInSystemContacts'; import { InContactsIcon } from '../InContactsIcon'; export type ContactListItemConversationType = Pick< ConversationType, | 'about' | 'acceptedMessageRequest' | 'avatarUrl' | 'badges' | 'color' | 'groupId' | 'id' | 'name' | 'isMe' | 'phoneNumber' | 'profileName' | 'sharedGroupNames' | 'systemGivenName' | 'systemFamilyName' | 'title' | 'type' | 'unblurredAvatarUrl' | 'username' | 'e164' | 'serviceId' >; type PropsDataType = ContactListItemConversationType & { badge: undefined | BadgeType; }; type PropsHousekeepingType = { i18n: LocalizerType; onClick?: (id: string) => void; onAudioCall?: (id: string) => void; onVideoCall?: (id: string) => void; onRemove?: (id: string) => void; onBlock?: (id: string) => void; hasContextMenu: boolean; theme: ThemeType; }; type PropsType = PropsDataType & PropsHousekeepingType; export const ContactListItem: FunctionComponent = React.memo( function ContactListItem({ about, acceptedMessageRequest, avatarUrl, badge, color, hasContextMenu, i18n, id, isMe, name, onClick, onAudioCall, onVideoCall, onRemove, onBlock, phoneNumber, profileName, sharedGroupNames, systemGivenName, systemFamilyName, theme, title, type, unblurredAvatarUrl, serviceId, }) { const [isConfirmingBlocking, setConfirmingBlocking] = useState(false); const [isConfirmingRemoving, setConfirmingRemoving] = useState(false); const menuOptions = useMemo( () => [ ...(onClick ? [ { icon: 'ContactListItem__context-menu__chat-icon', label: i18n('icu:ContactListItem__menu__message'), onClick: () => onClick(id), }, ] : []), ...(!isMe && onAudioCall ? [ { icon: 'ContactListItem__context-menu__phone-icon', label: i18n('icu:ContactListItem__menu__audio-call'), onClick: () => onAudioCall(id), }, ] : []), ...(!isMe && onVideoCall ? [ { icon: 'ContactListItem__context-menu__video-icon', label: i18n('icu:ContactListItem__menu__video-call'), onClick: () => onVideoCall(id), }, ] : []), ...(!isMe && onRemove ? [ { icon: 'ContactListItem__context-menu__delete-icon', label: i18n('icu:ContactListItem__menu__remove'), onClick: () => setConfirmingRemoving(true), }, ] : []), ...(!isMe && onBlock ? [ { icon: 'ContactListItem__context-menu__block-icon', label: i18n('icu:ContactListItem__menu__block'), onClick: () => setConfirmingBlocking(true), }, ] : []), ], [id, i18n, isMe, onClick, onAudioCall, onVideoCall, onRemove, onBlock] ); const headerName = isMe ? ( ) : ( ); const messageText = about && !isMe ? : undefined; let trailing: JSX.Element | undefined; if (hasContextMenu) { trailing = ( ); } let blockConfirmation: JSX.Element | undefined; let removeConfirmation: JSX.Element | undefined; if (isConfirmingBlocking) { blockConfirmation = ( setConfirmingBlocking(false)} title={ , }} /> } actions={[ { text: i18n('icu:MessageRequests--block'), action: () => onBlock?.(id), style: 'negative', }, ]} > {i18n('icu:MessageRequests--block-direct-confirm-body')} ); } if (isConfirmingRemoving) { if ( isInSystemContacts({ type, name, systemGivenName, systemFamilyName }) ) { removeConfirmation = ( setConfirmingRemoving(false)} title={ , }} /> } cancelText={i18n('icu:Confirmation--confirm')} > {i18n('icu:ContactListItem__remove-system--body')} ); } else { removeConfirmation = ( setConfirmingRemoving(false)} title={ , }} /> } actions={[ { text: i18n('icu:ContactListItem__remove--confirm'), action: () => onRemove?.(id), style: 'negative', }, ]} > {i18n('icu:ContactListItem__remove--body')} ); } } return ( <> } trailing={trailing} title={ <> {headerName} {isInSystemContacts({ type, name, systemGivenName, systemFamilyName, }) && ( {' '} )} } subtitle={messageText} subtitleMaxLines={1} onClick={onClick ? () => onClick(id) : undefined} /> {blockConfirmation} {removeConfirmation} ); } );