// A single topic or user. import React from 'react'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import { Tinode } from 'tinode-sdk'; import ContactBadges from './contact-badges.jsx'; import LetterTile from './letter-tile.jsx'; import UnreadBadge from './unread-badge.jsx'; import { Drafty } from 'tinode-sdk'; import { previewFormatter } from '../lib/formatters.js'; import { deliveryMarker } from '../lib/utils.js'; import { truncateString } from '../lib/strformat.js'; const messages = defineMessages({ self_topic_name: { id: 'self_topic_name', defaultMessage: 'Saved messages', description: 'Name of self topic for UI' }, self_topic_comment: { id: 'self_topic_comment', defaultMessage: 'Notes, messages, links, files saved for posterity', description: 'Comment for self topic for UI' } }); class Contact extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); this.handleContextClick = this.handleContextClick.bind(this); } handleClick(e) { e.preventDefault(); e.stopPropagation(); if (this.props.onSelected) { // Index this.props.index is used by GroupManager. this.props.onSelected(this.props.item, this.props.index); } } handleContextClick(e) { e.preventDefault(); e.stopPropagation(); this.props.showContextMenu({ topicName: this.props.item, topicTitle: this.props.title, y: e.pageY, x: e.pageX }); } render() { let title = this.props.title; const self = Tinode.isSelfTopicName(this.props.item); if (!title) { if (self) { title = this.props.intl.formatMessage(messages.self_topic_name); } else { title = ; } } else if (title.length > 30) { // Have to support RTL languages too. title = truncateString(title, 30); } const online = this.props.now ? 'online' : 'offline'; const avatar = this.props.avatar ? this.props.avatar : true; const badges = this.props.badges ? this.props.badges.slice() : []; const icon_badges = []; if (this.props.isVerified) { icon_badges.push({icon: 'verified', color: 'verified-color'}); } if (this.props.isStaff) { icon_badges.push({icon: 'staff', color: 'staff-color'}); } if (this.props.isDangerous) { icon_badges.push({icon: 'dangerous', color: 'danger-color'}); } if (this.props.acs) { if (this.props.showMode) { badges.push({name: this.props.acs.getMode(), key: 'mode'}); } if (this.props.acs.isMuted()) { icon_badges.push({icon: 'muted'}); } if (!this.props.acs.isJoiner()) { icon_badges.push({icon: 'banned'}); } } // The this.props.preview contains alreay shortened Drafty or string. let preview; if (typeof this.props.preview == 'string') { preview = this.props.preview; } else if (Drafty.isValid(this.props.preview)) { preview = React.createElement(React.Fragment, null, Drafty.format(this.props.preview, previewFormatter, {formatMessage: this.props.intl.formatMessage, previewIsResponse: this.props.previewIsResponse})); } else if (this.props.preview) { preview = <>warning_amber ; } const icon = deliveryMarker(this.props.received); const marker = icon ? {icon.name} : null; const titleClass = 'contact-title' + (this.props.deleted ? ' deleted' : ''); const comment = preview || this.props.comment || (self ? this.props.intl.formatMessage(messages.self_topic_comment) : '\u00A0'); const bgColor = this.props.showCheckmark ? null : (this.props.selected ? 'selected' : (this.props.pinned ? 'tpinned' : null)); return (
  • {this.props.deleted ? cancel : (!self && this.props.showOnline) ? : (this.props.showCheckmark && this.props.selected) ? check_circle : null}
    {title} {this.props.isGroup ? group : null} {this.props.isChannel ? podcasts : null} {!self ? : null} {!this.props.deleted ? : null}
    {this.props.showMode ? : this.props.small ? null :
    {marker}{comment}
    }
    {this.props.showContextMenu ? expand_more : null}
  • ); } }; export default injectIntl(Contact);