import React from 'react'; import { Avatar, AvatarSize } from '../avatar/Avatar'; import { contextMenu } from 'react-contexify'; import styled from 'styled-components'; import { ConversationNotificationSettingType } from '../../models/conversationAttributes'; import { getIsSelectedActive, getIsSelectedBlocked, getIsSelectedNoteToSelf, getIsSelectedPrivate, getSelectedConversationIsPublic, getSelectedConversationKey, getSelectedMessageIds, isMessageDetailView, isMessageSelectionMode, } from '../../state/selectors/conversations'; import { useDispatch, useSelector } from 'react-redux'; import { deleteMessagesById, deleteMessagesByIdForEveryone, } from '../../interactions/conversations/unsendingInteractions'; import { closeMessageDetailsView, openRightPanel, resetSelectedMessageIds, } from '../../state/ducks/conversations'; import { callRecipient } from '../../interactions/conversationInteractions'; import { getHasIncomingCall, getHasOngoingCall } from '../../state/selectors/call'; import { useIsRequest } from '../../hooks/useParamSelector'; import { SessionButton, SessionButtonColor, SessionButtonShape, SessionButtonType, } from '../basic/SessionButton'; import { SessionIconButton } from '../icon'; import { ConversationHeaderMenu } from '../menu/ConversationHeaderMenu'; import { Flex } from '../basic/Flex'; import { ConversationHeaderTitle } from './ConversationHeaderTitle'; export interface TimerOption { name: string; value: number; } export type ConversationHeaderProps = { conversationKey: string; name?: string; profileName?: string; avatarPath: string | null; 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; currentNotificationSetting: ConversationNotificationSettingType; hasNickname: boolean; isBlocked: boolean; isKickedFromGroup: boolean; left: boolean; }; const SelectionOverlay = () => { const selectedMessageIds = useSelector(getSelectedMessageIds); const selectedConversationKey = useSelector(getSelectedConversationKey); const isPublic = useSelector(getSelectedConversationIsPublic); const dispatch = useDispatch(); const { i18n } = window; function onCloseOverlay() { dispatch(resetSelectedMessageIds()); } function onDeleteSelectedMessages() { if (selectedConversationKey) { void deleteMessagesById(selectedMessageIds, selectedConversationKey); } } function onDeleteSelectedMessagesForEveryone() { if (selectedConversationKey) { void deleteMessagesByIdForEveryone(selectedMessageIds, selectedConversationKey); } } const isOnlyServerDeletable = isPublic; const deleteMessageButtonText = i18n('delete'); const deleteForEveryoneMessageButtonText = i18n('deleteForEveryone'); return (
{!isOnlyServerDeletable && ( )}
); }; const TripleDotContainer = styled.div` user-select: none; flex-grow: 0; flex-shrink: 0; `; const TripleDotsMenu = (props: { triggerId: string; showBackButton: boolean }) => { const { showBackButton } = props; if (showBackButton) { return null; } return ( { contextMenu.show({ id: props.triggerId, event: e, }); }} data-testid="three-dots-conversation-options" > ); }; const AvatarHeader = (props: { pubkey: string; showBackButton: boolean; onAvatarClick?: (pubkey: string) => void; }) => { const { pubkey, onAvatarClick, showBackButton } = props; return ( { // do not allow right panel to appear if another button is shown on the SessionConversation if (onAvatarClick && !showBackButton) { onAvatarClick(pubkey); } }} pubkey={pubkey} dataTestId="conversation-options-avatar" /> ); }; const BackButton = (props: { onGoBack: () => void; showBackButton: boolean }) => { const { onGoBack, showBackButton } = props; if (!showBackButton) { return null; } return ( ); }; const CallButton = () => { const isPrivate = useSelector(getIsSelectedPrivate); const isBlocked = useSelector(getIsSelectedBlocked); const activeAt = useSelector(getIsSelectedActive); const isMe = useSelector(getIsSelectedNoteToSelf); const selectedConvoKey = useSelector(getSelectedConversationKey); const hasIncomingCall = useSelector(getHasIncomingCall); const hasOngoingCall = useSelector(getHasOngoingCall); const canCall = !(hasIncomingCall || hasOngoingCall); const isRequest = useIsRequest(selectedConvoKey); if (!isPrivate || isMe || !selectedConvoKey || isBlocked || !activeAt || isRequest) { return null; } return ( { void callRecipient(selectedConvoKey, canCall); }} /> ); }; export const ConversationHeaderWithDetails = () => { const isSelectionMode = useSelector(isMessageSelectionMode); const isMessageDetailOpened = useSelector(isMessageDetailView); const selectedConvoKey = useSelector(getSelectedConversationKey); const dispatch = useDispatch(); if (!selectedConvoKey) { return null; } const triggerId = 'conversation-header'; return (
{ dispatch(closeMessageDetailsView()); }} showBackButton={isMessageDetailOpened} /> {!isSelectionMode && ( { dispatch(openRightPanel()); }} pubkey={selectedConvoKey} showBackButton={isMessageDetailOpened} /> )}
{isSelectionMode && }
); };