mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(settings): show crypto address validation inline instead of alert
Replace window.alert on empty check with a transient status message next to the check button, matching existing resolution feedback.
This commit is contained in:
+29
-1
@@ -28,7 +28,7 @@ vi.mock('react-i18next', () => ({
|
|||||||
crypto_address_not_yours: 'Crypto address is not yours.',
|
crypto_address_not_yours: 'Crypto address is not yours.',
|
||||||
crypto_address_verification: 'if the crypto address is resolved p2p',
|
crypto_address_verification: 'if the crypto address is resolved p2p',
|
||||||
crypto_address_yours: 'Crypto address belongs to this account.',
|
crypto_address_yours: 'Crypto address belongs to this account.',
|
||||||
enter_crypto_address: 'Enter crypto address.',
|
enter_crypto_address: 'Please enter a valid crypto address.',
|
||||||
loading: 'loading',
|
loading: 'loading',
|
||||||
save: 'save',
|
save: 'save',
|
||||||
saved: 'saved',
|
saved: 'saved',
|
||||||
@@ -152,6 +152,34 @@ describe('CryptoAddressSetting', () => {
|
|||||||
expect(getInput().value).toBe('resolved-alias.eth');
|
expect(getInput().value).toBe('resolved-alias.eth');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows a transient validation message when check is clicked with an empty field', async () => {
|
||||||
|
hookMocks.useAccount.mockReturnValue({
|
||||||
|
author: {
|
||||||
|
address: '12D3KooWSignerPublicKey',
|
||||||
|
shortAddress: '12D3KooWSignerPublicKey',
|
||||||
|
},
|
||||||
|
signer: {
|
||||||
|
address: SIGNER_ADDRESS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await render();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
getButtonByText('check').click();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(container.textContent).toContain('Please enter a valid crypto address.');
|
||||||
|
expect(alertSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
vi.advanceTimersByTime(2000);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(container.textContent).toContain('if the crypto address is resolved p2p');
|
||||||
|
expect(container.textContent).not.toContain('Please enter a valid crypto address.');
|
||||||
|
});
|
||||||
|
|
||||||
it('updates the displayed status after async resolution completes', async () => {
|
it('updates the displayed status after async resolution completes', async () => {
|
||||||
await render();
|
await render();
|
||||||
|
|
||||||
|
|||||||
@@ -85,12 +85,22 @@ const showSavedIndicator = (setSavedCryptoAddress: (value: boolean) => void) =>
|
|||||||
}, 2000);
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ResolutionStatus = ReturnType<typeof getResolutionStatus>;
|
||||||
|
|
||||||
|
const showTransientResolutionStatus = (setTransientResolutionStatus: (value: ResolutionStatus | undefined) => void, status: ResolutionStatus) => {
|
||||||
|
setTransientResolutionStatus(status);
|
||||||
|
setTimeout(() => {
|
||||||
|
setTransientResolutionStatus(undefined);
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
|
|
||||||
const CryptoAddressSettingContent = ({ account }: { account: ReturnType<typeof useAccount> }) => {
|
const CryptoAddressSettingContent = ({ account }: { account: ReturnType<typeof useAccount> }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [cryptoAddress, setCryptoAddress] = useState(() => getInitialCryptoAddress(account?.author?.address));
|
const [cryptoAddress, setCryptoAddress] = useState(() => getInitialCryptoAddress(account?.author?.address));
|
||||||
const [checkedAddress, setCheckedAddress] = useState<string>();
|
const [checkedAddress, setCheckedAddress] = useState<string>();
|
||||||
const [savedCryptoAddress, setSavedCryptoAddress] = useState(false);
|
const [savedCryptoAddress, setSavedCryptoAddress] = useState(false);
|
||||||
const [showCryptoAddressInfo, setShowCryptoAddressInfo] = useState(false);
|
const [showCryptoAddressInfo, setShowCryptoAddressInfo] = useState(false);
|
||||||
|
const [transientResolutionStatus, setTransientResolutionStatus] = useState<ResolutionStatus>();
|
||||||
|
|
||||||
const signerAddress = account?.signer?.address;
|
const signerAddress = account?.signer?.address;
|
||||||
const authorToResolve = checkedAddress ? { ...account?.author, address: checkedAddress } : undefined;
|
const authorToResolve = checkedAddress ? { ...account?.author, address: checkedAddress } : undefined;
|
||||||
@@ -108,7 +118,10 @@ const CryptoAddressSettingContent = ({ account }: { account: ReturnType<typeof u
|
|||||||
const checkCryptoAddress = () => {
|
const checkCryptoAddress = () => {
|
||||||
const addressToCheck = cryptoAddress.trim();
|
const addressToCheck = cryptoAddress.trim();
|
||||||
if (!addressToCheck || !addressToCheck.includes('.')) {
|
if (!addressToCheck || !addressToCheck.includes('.')) {
|
||||||
alert(t('enter_crypto_address'));
|
showTransientResolutionStatus(setTransientResolutionStatus, {
|
||||||
|
resolveClass: styles.red,
|
||||||
|
resolveString: t('enter_crypto_address'),
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +182,7 @@ const CryptoAddressSettingContent = ({ account }: { account: ReturnType<typeof u
|
|||||||
value={cryptoAddress}
|
value={cryptoAddress}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setCheckedAddress(undefined);
|
setCheckedAddress(undefined);
|
||||||
|
setTransientResolutionStatus(undefined);
|
||||||
setCryptoAddress(e.target.value);
|
setCryptoAddress(e.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -201,7 +215,7 @@ const CryptoAddressSettingContent = ({ account }: { account: ReturnType<typeof u
|
|||||||
<button className={styles.button} onClick={checkCryptoAddress}>
|
<button className={styles.button} onClick={checkCryptoAddress}>
|
||||||
{t('check')}
|
{t('check')}
|
||||||
</button>{' '}
|
</button>{' '}
|
||||||
<span className={resolutionStatus.resolveClass}>{resolutionStatus.resolveString}</span>
|
<span className={(transientResolutionStatus ?? resolutionStatus).resolveClass}>{(transientResolutionStatus ?? resolutionStatus).resolveString}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user