diff --git a/packages/react-components/src/Spinner.tsx b/packages/react-components/src/Spinner.tsx index ad174cefb6..830ab576bf 100644 --- a/packages/react-components/src/Spinner.tsx +++ b/packages/react-components/src/Spinner.tsx @@ -27,7 +27,7 @@ function Spinner ({ className = '', label, variant = 'app' }: Props): React.Reac size='medium' > {variant === 'app' && ( - label || t('Retrieving data') +
{label || t('Retrieving data')}
)} @@ -36,8 +36,7 @@ function Spinner ({ className = '', label, variant = 'app' }: Props): React.Reac export default React.memo(styled(Spinner)` .text { - margin: 0 auto 1.5rem auto; + color: inherit !important; opacity: 0.6; - text-align: center; } `); diff --git a/packages/react-signer/src/PaymentInfo.tsx b/packages/react-signer/src/PaymentInfo.tsx index 111026fc8d..442c4c5d12 100644 --- a/packages/react-signer/src/PaymentInfo.tsx +++ b/packages/react-signer/src/PaymentInfo.tsx @@ -29,13 +29,16 @@ function PaymentInfo ({ accountId, className = '', extrinsic }: Props): React.Re useEffect((): void => { // eslint-disable-next-line @typescript-eslint/unbound-method accountId && extrinsic && isFunction(extrinsic.paymentInfo) && isFunction(api.rpc.payment?.queryInfo) && - Promise.resolve( - extrinsic - .paymentInfo(accountId) - .then((info): void => { - mountedRef.current && setDispatchInfo(info); - }) - ).catch((error: Error) => console.error(error.message)); + setImmediate((): void => { + try { + extrinsic + .paymentInfo(accountId) + .then((info) => mountedRef.current && setDispatchInfo(info)) + .catch(console.error); + } catch (error) { + console.error((error as Error).message); + } + }); }, [api, accountId, extrinsic, mountedRef]); if (!dispatchInfo) { diff --git a/packages/react-signer/src/Qr.tsx b/packages/react-signer/src/Qr.tsx index 3064db19ea..d28f5b1d52 100644 --- a/packages/react-signer/src/Qr.tsx +++ b/packages/react-signer/src/Qr.tsx @@ -6,9 +6,11 @@ import { BareProps } from '@polkadot/react-components/types'; import React from 'react'; import styled from 'styled-components'; -import { Columar } from '@polkadot/react-components'; +import { Columar, Spinner } from '@polkadot/react-components'; import { QrDisplayPayload, QrScanSignature } from '@polkadot/react-qr'; +import { useTranslation } from './translate'; + interface Props extends BareProps { address: string; className?: string; @@ -23,6 +25,14 @@ const CMD_HASH = 1; const CMD_MORTAL = 2; function Qr ({ address, className, genesisHash, isHashed, onSignature, payload }: Props): React.ReactElement { + const { t } = useTranslation(); + + if (!address) { + return ( + {t('Preparing QR for signing')}} /> + ); + } + return ( diff --git a/packages/react-signer/src/TxSigned.tsx b/packages/react-signer/src/TxSigned.tsx index d7bdc22a50..6ed3f3a95c 100644 --- a/packages/react-signer/src/TxSigned.tsx +++ b/packages/react-signer/src/TxSigned.tsx @@ -157,7 +157,8 @@ function TxSigned ({ className, currentItem, requestAddress }: Props): React.Rea const { t } = useTranslation(); const { queueSetTxStatus } = useContext(StatusContext); const [flags, setFlags] = useState(extractExternal(requestAddress)); - const [{ isQrHashed, isQrVisible, qrAddress, qrPayload, qrResolve }, setQrState] = useState({ isQrHashed: false, isQrVisible: false, qrAddress: '', qrPayload: new Uint8Array() }); + const [{ isQrHashed, qrAddress, qrPayload, qrResolve }, setQrState] = useState({ isQrHashed: false, qrAddress: '', qrPayload: new Uint8Array() }); + const [isBusy, setBusy] = useState(false); const [isRenderError, toggleRenderError] = useToggle(); const [isSubmit, setIsSubmit] = useState(true); const [passwordError, setPasswordError] = useState(null); @@ -216,8 +217,8 @@ function TxSigned ({ className, currentItem, requestAddress }: Props): React.Rea ); const _onSendPayload = useCallback( - (): void => { - if (_unlock() && senderInfo.signAddress && currentItem.payload) { + (queueSetTxStatus: QueueTxMessageSetStatus, currentItem: QueueTx, senderInfo: AddressProxy): void => { + if (senderInfo.signAddress && currentItem.payload) { const { id, payload, signerCb = NOOP } = currentItem; const pair = keyring.getPair(senderInfo.signAddress); const result = registry.createType('ExtrinsicPayload', payload, { version: payload.version }).sign(pair); @@ -226,12 +227,12 @@ function TxSigned ({ className, currentItem, requestAddress }: Props): React.Rea queueSetTxStatus(id, 'completed'); } }, - [_unlock, currentItem, queueSetTxStatus, senderInfo] + [] ); const _onSend = useCallback( - async (): Promise => { - if (_unlock() && senderInfo.signAddress) { + async (queueSetTxStatus: QueueTxMessageSetStatus, currentItem: QueueTx, senderInfo: AddressProxy): Promise => { + if (senderInfo.signAddress) { const [tx, [status, pairOrAddress, options]] = await Promise.all([ wrapTx(api, currentItem, senderInfo), extractParams(senderInfo.signAddress, { tip }, setQrState) @@ -242,12 +243,12 @@ function TxSigned ({ className, currentItem, requestAddress }: Props): React.Rea await signAndSend(queueSetTxStatus, currentItem, tx, pairOrAddress, options); } }, - [_unlock, api, currentItem, queueSetTxStatus, senderInfo, tip] + [api, tip] ); const _onSign = useCallback( - async (): Promise => { - if (_unlock() && senderInfo.signAddress) { + async (queueSetTxStatus: QueueTxMessageSetStatus, currentItem: QueueTx, senderInfo: AddressProxy): Promise => { + if (senderInfo.signAddress) { const [tx, [, pairOrAddress, options]] = await Promise.all([ wrapTx(api, currentItem, senderInfo), extractParams(senderInfo.signAddress, { ...signedOptions, tip }, setQrState) @@ -256,14 +257,33 @@ function TxSigned ({ className, currentItem, requestAddress }: Props): React.Rea setSignedTx(await signAsync(queueSetTxStatus, currentItem, tx, pairOrAddress, options)); } }, - [_unlock, api, currentItem, queueSetTxStatus, senderInfo, signedOptions, tip] + [api, signedOptions, tip] + ); + + const _doStart = useCallback( + (): void => { + setBusy(true); + + setImmediate((): void => { + if (_unlock()) { + isSubmit + ? currentItem.payload + ? _onSendPayload(queueSetTxStatus, currentItem, senderInfo) + : _onSend(queueSetTxStatus, currentItem, senderInfo).catch(console.error) + : _onSign(queueSetTxStatus, currentItem, senderInfo).catch(console.error); + } else { + setBusy(false); + } + }); + }, + [_onSend, _onSendPayload, _onSign, _unlock, currentItem, isSubmit, queueSetTxStatus, senderInfo] ); return ( <> - {isQrVisible + {(isBusy && flags.isQr) ? ( - {!isQrVisible && ( + {!isBusy && ( <>