diff --git a/packages/page-council/src/Motions/ProposeExternal.tsx b/packages/page-council/src/Motions/ProposeExternal.tsx index e99ccc167c..8d1ef7c9c1 100644 --- a/packages/page-council/src/Motions/ProposeExternal.tsx +++ b/packages/page-council/src/Motions/ProposeExternal.tsx @@ -2,14 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 import type { SubmittableExtrinsic } from '@polkadot/api/types'; +import type { BN } from '@polkadot/util'; import type { HexString } from '@polkadot/util/types'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { getProposalThreshold } from '@polkadot/apps-config'; -import { Button, Input, InputAddress, Modal, TxButton } from '@polkadot/react-components'; +import { Button, Input, InputAddress, InputNumber, Modal, TxButton } from '@polkadot/react-components'; import { useApi, useCollectiveInstance, usePreimage, useToggle } from '@polkadot/react-hooks'; -import { isFunction, isHex } from '@polkadot/util'; +import { BN_ZERO, isFunction, isHex } from '@polkadot/util'; import { useTranslation } from '../translate'; @@ -24,6 +25,12 @@ interface HashState { isHashValid: boolean; } +interface ImageState { + imageLen: BN; + imageLenDefault?: BN; + isImageLenValid: boolean; +} + interface ProposalState { proposal?: SubmittableExtrinsic<'promise'> | null; proposalLength: number; @@ -36,24 +43,49 @@ function ProposeExternal ({ className = '', isMember, members }: Props): React.R const [accountId, setAcountId] = useState(null); const [{ proposal, proposalLength }, setProposal] = useState({ proposalLength: 0 }); const [{ hash, isHashValid }, setHash] = useState({ isHashValid: false }); + const [{ imageLen, imageLenDefault, isImageLenValid }, setImageLen] = useState({ imageLen: BN_ZERO, isImageLenValid: false }); const modLocation = useCollectiveInstance('council'); const preimage = usePreimage(hash); const threshold = Math.min(members.length, Math.ceil((members.length || 0) * getProposalThreshold(api))); + const isCurrentPreimage = useMemo( + () => isFunction(api.tx.preimage?.notePreimage) && !isFunction(api.tx.democracy?.notePreimage), + [api] + ); + const _onChangeHash = useCallback( (hash?: string): void => setHash({ hash: hash as HexString, isHashValid: isHex(hash, 256) }), [] ); + const _onChangeImageLen = useCallback( + (value?: BN): void => { + value && setImageLen((prev) => ({ + imageLen: value, + imageLenDefault: prev.imageLenDefault, + isImageLenValid: !value.isZero() + })); + }, + [] + ); + + useEffect((): void => { + preimage?.proposalLength && setImageLen((prev) => ({ + imageLen: prev.imageLen, + imageLenDefault: preimage.proposalLength, + isImageLenValid: prev.isImageLenValid + })); + }, [preimage]); + useEffect((): void => { if (isHashValid && hash) { - const proposal = isFunction(api.tx.preimage?.notePreimage) && !isFunction(api.tx.democracy?.notePreimage) + const proposal = isCurrentPreimage ? preimage && api.tx.democracy.externalProposeMajority({ Lookup: { hash: preimage.proposalHash, - len: preimage.proposalLength + len: preimage.proposalLength || imageLen } }) : api.tx.democracy.externalProposeMajority(hash); @@ -70,7 +102,7 @@ function ProposeExternal ({ className = '', isMember, members }: Props): React.R proposal: null, proposalLength: 0 }); - }, [api, hash, isHashValid, preimage]); + }, [api, hash, isCurrentPreimage, isHashValid, imageLen, preimage]); if (!modLocation) { return null; @@ -109,13 +141,24 @@ function ProposeExternal ({ className = '', isMember, members }: Props): React.R onChange={_onChangeHash} value={hash} /> + {isCurrentPreimage && ( + ('preimage length')} + onChange={_onChangeImageLen} + value={imageLen} + /> + )} ('Propose')} onStart={toggleVisible} params={