mirror of
https://github.com/lux-tel/session-desktop.git
synced 2026-10-30 20:33:24 +00:00
200 lines
7.2 KiB
TypeScript
200 lines
7.2 KiB
TypeScript
import { useState } from 'react';
|
|
import useKey from 'react-use/lib/useKey';
|
|
import styled from 'styled-components';
|
|
import { getAppDispatch } from '../../state/dispatch';
|
|
|
|
import { ConvoHub } from '../../session/conversations';
|
|
import { openConversationWithMessages } from '../../state/ducks/conversations';
|
|
import { updateUserProfileModal, UserProfileModalState } from '../../state/ducks/modalDialog';
|
|
import { SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
|
|
import { CopyToClipboardButton } from '../buttons/CopyToClipboardButton';
|
|
import { ConversationTypeEnum } from '../../models/types';
|
|
import { Flex } from '../basic/Flex';
|
|
import { AccountIdPill } from '../basic/AccountIdPill';
|
|
import {
|
|
ModalBasicHeader,
|
|
ModalActionsContainer,
|
|
SessionWrapperModal,
|
|
ModalBottomButtonWithBorder,
|
|
} from '../SessionWrapperModal';
|
|
import { tr } from '../../localization/localeTools';
|
|
import { PubKey } from '../../session/types';
|
|
import type { ProfileDialogModes } from './user-settings/ProfileDialogModes';
|
|
import { ProfileHeader } from './user-settings/components';
|
|
import { useAvatarPath, useConversationUsernameWithFallback } from '../../hooks/useParamSelector';
|
|
import { SessionLucideIconButton } from '../icon/SessionIconButton';
|
|
import { LUCIDE_ICONS_UNICODE } from '../icon/lucide';
|
|
import { useHasDisabledBlindedMsgRequests } from '../../state/selectors/conversations';
|
|
import { Localizer } from '../basic/Localizer';
|
|
import { SessionTooltip } from '../SessionTooltip';
|
|
import { shortenDisplayName } from '../../session/profile_manager/ShortenDisplayName';
|
|
import { UsernameFallback } from './conversationSettings/UsernameFallback';
|
|
import { ConversationTitleDialog } from './conversationSettings/ConversationTitleDialog';
|
|
import { SessionIDNotEditable } from '../basic/SessionIdNotEditable';
|
|
import { QRView } from '../qrview/QrView';
|
|
|
|
const StyledHasDisabledMsgRequests = styled.div`
|
|
max-width: 42ch;
|
|
color: var(--text-secondary-color);
|
|
font-size: var(--font-size-sm);
|
|
text-align: center;
|
|
`;
|
|
|
|
function HasDisabledMsgRequests({ conversationId }: { conversationId: string }) {
|
|
const username = useConversationUsernameWithFallback(true, conversationId);
|
|
const name = shortenDisplayName(username);
|
|
|
|
return (
|
|
<StyledHasDisabledMsgRequests>
|
|
<Localizer token="messageRequestsTurnedOff" name={name} />
|
|
</StyledHasDisabledMsgRequests>
|
|
);
|
|
}
|
|
|
|
export const UserProfileModal = ({
|
|
conversationId,
|
|
realSessionId,
|
|
}: NonNullable<UserProfileModalState>) => {
|
|
const dispatch = getAppDispatch();
|
|
const [enlargedImage, setEnlargedImage] = useState(false);
|
|
|
|
const isBlinded = PubKey.isBlinded(conversationId);
|
|
const isBlindedAndNotResolved = isBlinded && !realSessionId;
|
|
const isBlindedAndResolved = isBlinded && !!realSessionId;
|
|
const conversationIdToDisplay = isBlindedAndResolved ? realSessionId : conversationId;
|
|
|
|
const avatarPath = useAvatarPath(conversationIdToDisplay) || '';
|
|
const profileName = useConversationUsernameWithFallback(false, conversationIdToDisplay) || '';
|
|
|
|
function closeDialog() {
|
|
dispatch(updateUserProfileModal(null));
|
|
}
|
|
|
|
const [mode, setMode] = useState<ProfileDialogModes>('default');
|
|
|
|
const hasDisabledMsgRequests = useHasDisabledBlindedMsgRequests(conversationId);
|
|
const blindedAndDisabledMsgRequests = isBlindedAndNotResolved && hasDisabledMsgRequests;
|
|
|
|
async function onClickStartConversation() {
|
|
if (isBlindedAndNotResolved && hasDisabledMsgRequests) {
|
|
return;
|
|
}
|
|
const convo = ConvoHub.use().get(conversationIdToDisplay);
|
|
|
|
const conversation = await ConvoHub.use().getOrCreateAndWait(
|
|
convo.id,
|
|
ConversationTypeEnum.PRIVATE
|
|
);
|
|
|
|
await openConversationWithMessages({ conversationKey: conversation.id, messageId: null });
|
|
|
|
closeDialog();
|
|
}
|
|
|
|
useKey(
|
|
'Enter',
|
|
() => {
|
|
void onClickStartConversation();
|
|
},
|
|
undefined
|
|
);
|
|
|
|
return (
|
|
<SessionWrapperModal
|
|
modalId="userProfileModal"
|
|
headerChildren={<ModalBasicHeader title={''} showExitIcon={true} />}
|
|
onClose={closeDialog}
|
|
buttonChildren={
|
|
<ModalActionsContainer buttonType={SessionButtonType.Outline}>
|
|
<ModalBottomButtonWithBorder
|
|
text={tr('message')}
|
|
onClick={onClickStartConversation}
|
|
dataTestId="new-session-conversation"
|
|
disabled={isBlindedAndNotResolved && hasDisabledMsgRequests}
|
|
buttonColor={SessionButtonColor.PrimaryDark}
|
|
/>
|
|
|
|
{!isBlindedAndNotResolved && (
|
|
<CopyToClipboardButton
|
|
copyContent={conversationIdToDisplay}
|
|
buttonColor={SessionButtonColor.PrimaryDark}
|
|
dataTestId="copy-button-account-id"
|
|
buttonType={SessionButtonType.Outline}
|
|
hotkey={true}
|
|
/>
|
|
)}
|
|
</ModalActionsContainer>
|
|
}
|
|
>
|
|
<Flex
|
|
$container={true}
|
|
width={'100%'}
|
|
$justifyContent="center"
|
|
$alignItems="center"
|
|
$flexDirection="column"
|
|
$flexGap="var(--margins-md)"
|
|
$paddingBlock="0 var(--margins-lg)"
|
|
style={{ position: 'relative' }}
|
|
>
|
|
{mode === 'qr' ? (
|
|
<QRView sessionID={conversationIdToDisplay} onExit={() => setMode('default')} />
|
|
) : (
|
|
<ProfileHeader
|
|
avatarPath={avatarPath}
|
|
conversationId={conversationIdToDisplay}
|
|
onPlusAvatarClick={null} // no + icon in this modal
|
|
dataTestId="avatar-user-profile-dialog"
|
|
onQRClick={
|
|
blindedAndDisabledMsgRequests
|
|
? null
|
|
: () => {
|
|
setMode('qr');
|
|
}
|
|
}
|
|
enlargedImage={enlargedImage}
|
|
toggleEnlargedImage={() => setEnlargedImage(!enlargedImage)}
|
|
/>
|
|
)}
|
|
|
|
<ConversationTitleDialog conversationId={conversationIdToDisplay} editable={false} />
|
|
<UsernameFallback conversationId={conversationIdToDisplay} />
|
|
<AccountIdPill accountType={isBlindedAndNotResolved ? 'blinded' : 'theirs'} />
|
|
<SessionIDNotEditable
|
|
dataTestId="account-id"
|
|
sessionId={conversationIdToDisplay}
|
|
displayType={
|
|
isBlindedAndNotResolved ? 'blinded' : isBlindedAndResolved ? '3lines' : '2lines'
|
|
}
|
|
style={{ color: 'var(--text-primary-color)' }}
|
|
tooltipNode={
|
|
<SessionTooltip
|
|
content={
|
|
!isBlinded ? null : isBlindedAndResolved ? (
|
|
<Localizer
|
|
token="tooltipAccountIdVisible"
|
|
name={shortenDisplayName(profileName)}
|
|
className="session-id-tooltip"
|
|
/>
|
|
) : (
|
|
<Localizer token="tooltipBlindedIdCommunities" className="session-id-tooltip" />
|
|
)
|
|
}
|
|
dataTestId="tooltip-info"
|
|
>
|
|
<SessionLucideIconButton
|
|
unicode={LUCIDE_ICONS_UNICODE.CIRCLE_HELP}
|
|
iconColor="var(--text-primary-color)"
|
|
iconSize="small"
|
|
dataTestId="tooltip"
|
|
/>
|
|
</SessionTooltip>
|
|
}
|
|
/>
|
|
{blindedAndDisabledMsgRequests ? (
|
|
<HasDisabledMsgRequests conversationId={conversationId} />
|
|
) : null}
|
|
</Flex>
|
|
</SessionWrapperModal>
|
|
);
|
|
};
|