import React from 'react'; import { Avatar } from '../Avatar'; import { LocalizerType } from '../../types/Util'; import { SessionIcon, SessionIconButton, SessionIconSize, SessionIconType, } from '../session/icon'; import { SessionButton, SessionButtonColor, SessionButtonType, } from '../session/SessionButton'; import { ConversationAvatar, usingClosedConversationDetails, } from '../session/usingClosedConversationDetails'; import { MenuProvider } from 'react-contexify'; import { ConversationHeaderMenu, PropsConversationHeaderMenu, } from '../session/menu/ConversationHeaderMenu'; export interface TimerOption { name: string; value: number; } interface Props { id: string; name?: string; phoneNumber: string; profileName?: string; avatarPath?: string; isVerified: boolean; isMe: boolean; isClosable?: boolean; isGroup: boolean; isPrivate: boolean; isPublic: boolean; isRss: boolean; amMod: boolean; // We might not always have the full list of members, // e.g. for open groups where we could have thousands // of members. We'll keep this for now (for closed chats) members: Array; // not equal members.length (see above) subscriberCount?: number; expirationSettingName?: string; showBackButton: boolean; timerOptions: Array; hasNickname?: boolean; isBlocked: boolean; isOnline?: boolean; isKickedFromGroup: boolean; selectionMode: boolean; // is the UI on the message selection mode or not onInviteContacts: () => void; onSetDisappearingMessages: (seconds: number) => void; onDeleteMessages: () => void; onDeleteContact: () => void; onResetSession: () => void; onCloseOverlay: () => void; onDeleteSelectedMessages: () => void; onShowSafetyNumber: () => void; onGoBack: () => void; onBlockUser: () => void; onUnblockUser: () => void; onCopyPublicKey: () => void; onLeaveGroup: () => void; onAddModerators: () => void; onRemoveModerators: () => void; onAvatarClick?: (userPubKey: string) => void; onUpdateGroupName: () => void; i18n: LocalizerType; memberAvatars?: Array; // this is added by usingClosedConversationDetails } class ConversationHeader extends React.Component { public onAvatarClickBound: (userPubKey: string) => void; public constructor(props: Props) { super(props); this.onAvatarClickBound = this.onAvatarClick.bind(this); } public renderBackButton() { const { onGoBack, showBackButton } = this.props; if (!showBackButton) { return null; } return (
); } public renderTitle() { const { phoneNumber, i18n, profileName, isGroup, isPublic, isRss, members, subscriberCount, isMe, isKickedFromGroup, name, } = this.props; if (isMe) { return (
{i18n('noteToSelf')}
); } const memberCount: number = (() => { if (!isGroup || isRss) { return 0; } if (isPublic) { return subscriberCount || 0; } else { return members.length; } })(); let text = ''; if (isGroup && memberCount > 0) { const count = String(memberCount); text = i18n('members', [count]); } const textEl = text === '' || isKickedFromGroup ? null : ( {text} ); const title = profileName || name || phoneNumber; return (
{title} {textEl}
); } public renderAvatar() { const { avatarPath, memberAvatars, name, phoneNumber, profileName, } = this.props; const userName = name || profileName || phoneNumber; return ( { this.onAvatarClickBound(phoneNumber); }} memberAvatars={memberAvatars} pubkey={phoneNumber} /> ); } public renderExpirationLength() { const { expirationSettingName } = this.props; if (!expirationSettingName) { return null; } return (
{expirationSettingName}
); } public renderSearch() { return (
); } public renderOptions(triggerId: string) { const { showBackButton } = this.props; if (showBackButton) { return null; } return ( ); } public renderSelectionOverlay() { const { onDeleteSelectedMessages, onCloseOverlay, isPublic, i18n, } = this.props; const isServerDeletable = isPublic; const deleteMessageButtonText = i18n( isServerDeletable ? 'deleteForEveryone' : 'delete' ); return (
); } public render() { const { id, isKickedFromGroup, selectionMode } = this.props; const triggerId = `conversation-header-${id}`; return (
{this.renderBackButton()}
{!selectionMode && this.renderOptions(triggerId)} {this.renderTitle()}
{!isKickedFromGroup && this.renderExpirationLength()} {!this.props.isRss && !selectionMode && this.renderAvatar()}
{selectionMode && this.renderSelectionOverlay()}
); } public onAvatarClick(userPubKey: string) { if (this.props.onAvatarClick) { this.props.onAvatarClick(userPubKey); } } public highlightMessageSearch() { // This is a temporary fix. In future we want to search // messages in the current conversation ($('.session-search-input input') as any).focus(); } private getHeaderMenuProps(triggerId: string): PropsConversationHeaderMenu { return { triggerId, ...this.props, }; } } export const ConversationHeaderWithDetails = usingClosedConversationDetails( ConversationHeader );