import { useState } from 'react'; import useKey from 'react-use/lib/useKey'; import styled from 'styled-components'; import { shell } from 'electron'; import { motion } from 'framer-motion'; import { isEmpty } from 'lodash'; import { useDispatch } from 'react-redux'; import { ConversationTypeEnum } from '../../../models/conversationAttributes'; import { getConversationController } from '../../../session/conversations'; import { PubKey } from '../../../session/types'; import { openConversationWithMessages } from '../../../state/ducks/conversations'; import { resetLeftOverlayMode } from '../../../state/ducks/section'; import { SessionButton } from '../../basic/SessionButton'; import { SessionSpinner } from '../../loading'; import { ONSResolve } from '../../../session/apis/snode_api/onsResolve'; import { NotFoundError, SnodeResponseError } from '../../../session/utils/errors'; import { THEME_GLOBALS } from '../../../themes/globals'; import { Flex } from '../../basic/Flex'; import { SpacerLG, SpacerMD } from '../../basic/Text'; import { SessionIconButton } from '../../icon'; import { SessionInput } from '../../inputs'; const StyledDescriptionContainer = styled(motion.div)` margin: 0 auto; text-align: center; padding: 0 var(--margins-md); .session-icon-button { border: 1px solid var(--text-secondary-color); border-radius: 9999px; margin-inline-start: var(--margins-xs); transition-duration: var(--default-duration); &:hover { border-color: var(--text-primary-color); } } `; const SessionIDDescription = styled.span` color: var(--text-secondary-color); font-family: var(--font-default); font-style: normal; font-weight: 400; font-size: 12px; text-align: center; `; export const StyledLeftPaneOverlay = styled(Flex)` background: var(--background-primary-color); overflow-y: auto; overflow-x: hidden; .session-button { width: 100%; } `; export const OverlayMessage = () => { const dispatch = useDispatch(); function closeOverlay() { dispatch(resetLeftOverlayMode()); } useKey('Escape', closeOverlay); const [pubkeyOrOns, setPubkeyOrOns] = useState(''); const [pubkeyOrOnsError, setPubkeyOrOnsError] = useState(undefined); const [loading, setLoading] = useState(false); const disableNextButton = !pubkeyOrOns || loading; async function openConvoOnceResolved(resolvedSessionID: string) { const convo = await getConversationController().getOrCreateAndWait( resolvedSessionID, ConversationTypeEnum.PRIVATE ); // we now want to show a conversation we just started on the leftpane, even if we did not send a message to it yet if (!convo.isActive() || convo.isHidden()) { // bump the timestamp only if we were not active before if (!convo.isActive()) { convo.set({ active_at: Date.now() }); } await convo.unhideIfNeeded(false); await convo.commit(); } await openConversationWithMessages({ conversationKey: resolvedSessionID, messageId: null }); closeOverlay(); } async function handleMessageButtonClick() { setPubkeyOrOnsError(undefined); if ((!pubkeyOrOns && !pubkeyOrOns.length) || !pubkeyOrOns.trim().length) { setPubkeyOrOnsError(window.i18n('accountIdErrorInvalid')); return; } const pubkeyorOnsTrimmed = pubkeyOrOns.trim(); const validationError = PubKey.validateWithErrorNoBlinding(pubkeyorOnsTrimmed); if (!validationError) { await openConvoOnceResolved(pubkeyorOnsTrimmed); return; } const isPubkey = PubKey.validate(pubkeyorOnsTrimmed); const isGroupPubkey = PubKey.isClosedGroupV3(pubkeyorOnsTrimmed); if ((isPubkey && validationError) || isGroupPubkey) { setPubkeyOrOnsError(validationError); return; } // this might be an ONS, validate the regex first const mightBeOnsName = new RegExp(ONSResolve.onsNameRegex, 'g').test(pubkeyorOnsTrimmed); if (!mightBeOnsName) { setPubkeyOrOnsError(window.i18n('onsErrorNotRecognized')); return; } setLoading(true); try { const resolvedSessionID = await ONSResolve.getSessionIDForOnsName(pubkeyorOnsTrimmed); const idValidationError = PubKey.validateWithErrorNoBlinding(resolvedSessionID); if (idValidationError) { setPubkeyOrOnsError(window.i18n('onsErrorNotRecognized')); return; } await openConvoOnceResolved(resolvedSessionID); } catch (e) { setPubkeyOrOnsError( e instanceof SnodeResponseError ? window.i18n('onsErrorUnableToSearch') : e instanceof NotFoundError ? window.i18n('onsErrorNotRecognized') : window.i18n('failedResolveOns') ); } finally { setLoading(false); } } return ( {!pubkeyOrOnsError && !loading ? ( <> {window.i18n('messageNewDescription')} { void shell.openExternal( 'https://sessionapp.zendesk.com/hc/en-us/articles/4439132747033-How-do-Session-ID-usernames-work' ); }} /> ) : null} {!isEmpty(pubkeyOrOns) ? ( ) : null} ); };