import React from 'react'; import { Avatar, AvatarSize } from '../Avatar'; import { SessionIconButton, SessionIconSize, SessionIconType } from '../session/icon'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../session/SessionButton'; import { ConversationAvatar } from '../session/usingClosedConversationDetails'; import { MemoConversationHeaderMenu } from '../session/menu/ConversationHeaderMenu'; import { contextMenu } from 'react-contexify'; import { useTheme } from 'styled-components'; import { ConversationNotificationSettingType } from '../../models/conversation'; import { getConversationHeaderProps, getConversationHeaderTitleProps, getSelectedConversation, getSelectedMessageIds, isMessageDetailView, isMessageSelectionMode, } from '../../state/selectors/conversations'; import { useDispatch, useSelector } from 'react-redux'; import { useMembersAvatars } from '../../hooks/useMembersAvatar'; import { deleteMessagesById } from '../../interactions/conversationInteractions'; import { closeMessageDetailsView, openRightPanel, resetSelectedMessageIds, } from '../../state/ducks/conversations'; import { NotificationForConvoOption } from '../../state/ducks/conversations'; export interface TimerOption { name: string; value: number; } export type ConversationHeaderProps = { id: string; name?: string; phoneNumber: string; profileName?: string; avatarPath?: string; isMe: boolean; isGroup: boolean; isPrivate: boolean; isPublic: boolean; weAreAdmin: 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; notificationForConvo: Array; currentNotificationSetting: ConversationNotificationSettingType; hasNickname: boolean; isBlocked: boolean; isKickedFromGroup: boolean; left: boolean; }; const SelectionOverlay = (props: { onDeleteSelectedMessages: () => void; onCloseOverlay: () => void; isPublic: boolean; }) => { const { onDeleteSelectedMessages, onCloseOverlay, isPublic } = props; const { i18n } = window; const theme = useTheme(); const isServerDeletable = isPublic; const deleteMessageButtonText = i18n(isServerDeletable ? 'deleteForEveryone' : 'delete'); return (
); }; const TripleDotsMenu = (props: { triggerId: string; showBackButton: boolean }) => { const { showBackButton } = props; const theme = useTheme(); if (showBackButton) { return <>; } return (
{ contextMenu.show({ id: props.triggerId, event: e, }); }} >
); }; const ExpirationLength = (props: { expirationSettingName?: string }) => { const { expirationSettingName } = props; if (!expirationSettingName) { return null; } return (
{expirationSettingName}
); }; const AvatarHeader = (props: { avatarPath?: string; memberAvatars?: Array; name?: string; phoneNumber: string; profileName?: string; showBackButton: boolean; onAvatarClick?: (pubkey: string) => void; }) => { const { avatarPath, memberAvatars, name, phoneNumber, profileName } = props; const userName = name || profileName || phoneNumber; return ( { // do not allow right panel to appear if another button is shown on the SessionConversation if (props.onAvatarClick && !props.showBackButton) { props.onAvatarClick(phoneNumber); } }} memberAvatars={memberAvatars} pubkey={phoneNumber} /> ); }; const BackButton = (props: { onGoBack: () => void; showBackButton: boolean }) => { const { onGoBack, showBackButton } = props; const theme = useTheme(); if (!showBackButton) { return null; } return ( ); }; export type ConversationHeaderTitleProps = { phoneNumber: string; profileName?: string; isMe: boolean; isGroup: boolean; isPublic: boolean; members: Array; subscriberCount?: number; isKickedFromGroup: boolean; name?: string; }; const ConversationHeaderTitle = () => { const headerTitleProps = useSelector(getConversationHeaderTitleProps); if (!headerTitleProps) { return null; } const { phoneNumber, profileName, isGroup, isPublic, members, subscriberCount, isMe, isKickedFromGroup, name, } = headerTitleProps; const { i18n } = window; if (isMe) { return
{i18n('noteToSelf')}
; } const memberCount: number = (() => { if (!isGroup) { 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}
); }; export const ConversationHeaderWithDetails = () => { const headerProps = useSelector(getConversationHeaderProps); const isSelectionMode = useSelector(isMessageSelectionMode); const selectedMessageIds = useSelector(getSelectedMessageIds); const selectedConversation = useSelector(getSelectedConversation); const memberDetails = useMembersAvatars(selectedConversation); const isMessageDetailOpened = useSelector(isMessageDetailView); const dispatch = useDispatch(); if (!headerProps) { return null; } const { isKickedFromGroup, expirationSettingName, phoneNumber, avatarPath, name, profileName, id, isMe, isPublic, notificationForConvo, currentNotificationSetting, hasNickname, weAreAdmin, isBlocked, left, isPrivate, isGroup, } = headerProps; const triggerId = 'conversation-header'; return (
{ dispatch(closeMessageDetailsView()); }} showBackButton={isMessageDetailOpened} />
{!isKickedFromGroup && } {!isSelectionMode && ( { dispatch(openRightPanel()); }} phoneNumber={phoneNumber} showBackButton={isMessageDetailOpened} avatarPath={avatarPath} memberAvatars={memberDetails} name={name} profileName={profileName} /> )}
{isSelectionMode && ( dispatch(resetSelectedMessageIds())} onDeleteSelectedMessages={() => { void deleteMessagesById(selectedMessageIds, id, true); }} /> )}
); };