diff --git a/packages/page-accounts/src/Accounts/modals/Identity.tsx b/packages/page-accounts/src/Accounts/modals/Identity.tsx index 6ad0c72fb4..4b90811996 100644 --- a/packages/page-accounts/src/Accounts/modals/Identity.tsx +++ b/packages/page-accounts/src/Accounts/modals/Identity.tsx @@ -26,6 +26,17 @@ interface WrapProps { value: boolean; } +interface ValueState { + info: Record; + okAll: boolean; + okDisplay?: boolean; + okEmail?: boolean; + okLegal?: boolean; + okRiot?: boolean; + okTwitter?: boolean; + okWeb?: boolean; +} + function setData (data: Data, setActive: null | ((isActive: boolean) => void), setVal: (val: string) => void): void { if (data.isRaw) { setActive && setActive(true); @@ -41,11 +52,7 @@ function WrapToggle ({ children, onChange, value }: WrapProps): React.ReactEleme {children} ('include value') - : t('exclude value') - } + label={t('include field')} onChange={onChange} value={value} /> @@ -53,11 +60,20 @@ function WrapToggle ({ children, onChange, value }: WrapProps): React.ReactEleme ); } +function checkValue (hasValue: boolean, value: string | null | undefined, minLength: number, includes: string[], starting: string[]): boolean { + return !hasValue || ( + !!value && + (value.length >= minLength) && + includes.reduce((hasIncludes: boolean, check) => hasIncludes && value.includes(check), true) && + starting.reduce((hasStarting: boolean, check) => hasStarting || value.startsWith(check), starting.length === 0) + ); +} + function Identity ({ address, className = '', onClose }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); const identityOpt = useCall>(api.query.identity.identityOf, [address]); - const [info, setInfo] = useState>({}); + const [{ info, okAll, okDisplay, okEmail, okLegal, okRiot, okTwitter, okWeb }, setInfo] = useState({ info: {}, okAll: false }); const [hasEmail, setHasEmail] = useState(false); // const [hasImg, setHasImg] = useState(false); const [hasLegal, setHasLegal] = useState(false); @@ -88,15 +104,31 @@ function Identity ({ address, className = '', onClose }: Props): React.ReactElem }, [identityOpt]); useEffect((): void => { + const okDisplay = checkValue(true, valDisplay, 1, [], []); + const okEmail = checkValue(hasEmail, valEmail, 3, ['@'], []); + const okLegal = checkValue(hasLegal, valLegal, 1, [], []); + const okRiot = checkValue(hasRiot, valRiot, 6, [':'], ['@', '~']); + const okTwitter = checkValue(hasTwitter, valTwitter, 3, [], ['@']); + const okWeb = checkValue(hasWeb, valWeb, 8, ['.'], ['https://', 'http://']); + setInfo({ - display: { [valDisplay ? 'raw' : 'none']: valDisplay || null }, - email: { [hasEmail ? 'raw' : 'none']: hasEmail ? valEmail : null }, - legal: { [hasLegal ? 'raw' : 'none']: hasLegal ? valLegal : null }, - riot: { [hasRiot ? 'raw' : 'none']: hasRiot ? valRiot : null }, - twitter: { [hasTwitter ? 'raw' : 'none']: hasTwitter ? valTwitter : null }, - web: { [hasWeb ? 'raw' : 'none']: hasWeb ? valWeb : null } - // image: { [hasImg ? 'sha256' : 'none']: hasImg ? valImg : null }, - // pgpFingerprint: hasPgp ? valPgp : null + info: { + display: { [okDisplay ? 'raw' : 'none']: valDisplay || null }, + email: { [okEmail ? 'raw' : 'none']: hasEmail ? valEmail : null }, + legal: { [okLegal ? 'raw' : 'none']: hasLegal ? valLegal : null }, + riot: { [okRiot ? 'raw' : 'none']: hasRiot ? valRiot : null }, + twitter: { [okTwitter ? 'raw' : 'none']: hasTwitter ? valTwitter : null }, + web: { [okWeb ? 'raw' : 'none']: hasWeb ? valWeb : null } + // image: { [hasImg ? 'sha256' : 'none']: hasImg ? valImg : null }, + // pgpFingerprint: hasPgp ? valPgp : null + }, + okAll: okDisplay && okEmail && okLegal && okRiot && okTwitter && okWeb, + okDisplay, + okEmail, + okLegal, + okRiot, + okTwitter, + okWeb }); // errImg, errPgp, hasImg, hasPgp, valImg, valPgp, }, [hasEmail, hasLegal, hasRiot, hasTwitter, hasWeb, valDisplay, valEmail, valLegal, valRiot, valTwitter, valWeb]); @@ -110,9 +142,11 @@ function Identity ({ address, className = '', onClose }: Props): React.ReactElem ('The name that will be displayed in your accounts list.')} + isError={!okDisplay} label={t('display name')} maxLength={32} onChange={setValDisplay} + placeholder={t('My On-Chain Name')} value={valDisplay} /> ('The legal name for this identity.')} isDisabled={!hasLegal} + isError={!okLegal} label={t('legal name')} maxLength={32} onChange={setValLegal} + placeholder={t('Full Legal Name')} value={hasLegal ? valLegal : ''} /> @@ -135,9 +171,11 @@ function Identity ({ address, className = '', onClose }: Props): React.ReactElem ('The email address associated with this identity.')} isDisabled={!hasEmail} + isError={!okEmail} label={t('email')} maxLength={32} onChange={setValEmail} + placeholder={t('somebody@example.com')} value={hasEmail ? valEmail : ''} /> @@ -148,9 +186,11 @@ function Identity ({ address, className = '', onClose }: Props): React.ReactElem ('An URL that is linked to this identity.')} isDisabled={!hasWeb} + isError={!okWeb} label={t('web')} maxLength={32} onChange={setValWeb} + placeholder={t('https://example.com')} value={hasWeb ? valWeb : ''} /> @@ -161,8 +201,10 @@ function Identity ({ address, className = '', onClose }: Props): React.ReactElem ('The twitter name for this identity.')} isDisabled={!hasTwitter} + isError={!okTwitter} label={t('twitter')} onChange={setValTwitter} + placeholder={t('@YourTwitterName')} value={hasTwitter ? valTwitter : ''} /> @@ -173,9 +215,11 @@ function Identity ({ address, className = '', onClose }: Props): React.ReactElem ('a riot name linked to this identity')} isDisabled={!hasRiot} + isError={!okRiot} label={t('riot name')} maxLength={32} onChange={setValRiot} + placeholder={t('@yourname:matrix.org')} value={hasRiot ? valRiot : ''} /> @@ -211,7 +255,7 @@ function Identity ({ address, className = '', onClose }: Props): React.ReactElem ('Set Identity')} onStart={onClose} @@ -230,7 +274,7 @@ export default styled(Identity)` .toggle-Toggle { position: absolute; right: 3.5rem; - top: 0.5rem; + bottom: 1.375rem; } } `;