Allow voting to use locked balance (#2668)
* Allow voting to use locked balance * Update linting * i18n strings
This commit is contained in:
parent
5b7825b99c
commit
5b8894d167
@ -4,6 +4,7 @@
|
||||
"Close proposal": "Close proposal",
|
||||
"Council overview": "Council overview",
|
||||
"Current prime member, default voting": "Current prime member, default voting",
|
||||
"In calculating the election outcome, this prioitized vote ordering will be used to determine the final score for the candidates.": "In calculating the election outcome, this prioitized vote ordering will be used to determine the final score for the candidates.",
|
||||
"Motions ({{count}})": "Motions ({{count}})",
|
||||
"No candidates found": "No candidates found",
|
||||
"No council motions": "No council motions",
|
||||
@ -28,6 +29,10 @@
|
||||
"The preimage hash of the proposal": "The preimage hash of the proposal",
|
||||
"The proposal that will be affected. Once closed for the current voting round, it would need to be re-submitted to council for a subsequent voting round.": "The proposal that will be affected. Once closed for the current voting round, it would need to be re-submitted to council for a subsequent voting round.",
|
||||
"The unapplied slashed era to cancel.": "The unapplied slashed era to cancel.",
|
||||
"The value associated with this vote. The amount will be locked (not available for transfer) and used in all subsequent elections.": "The value associated with this vote. The amount will be locked (not available for transfer) and used in all subsequent elections.",
|
||||
"The vote will be recorded for the selected account.": "The vote will be recorded for the selected account.",
|
||||
"The votes for the members, runner-ups and candidates. These should be ordered based on your priority.": "The votes for the members, runner-ups and candidates. These should be ordered based on your priority.",
|
||||
"This account will appear in the list of candidates. With enough votes in an election, it will become either a runner-up or a council member.": "This account will appear in the list of candidates. With enough votes in an election, it will become either a runner-up or a council member.",
|
||||
"This account will be use to approve each candidate.": "This account will be use to approve each candidate.",
|
||||
"Vote": "Vote",
|
||||
"Vote for current candidates": "Vote for current candidates",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"Democracy overview": "Democracy overview",
|
||||
"Fast track": "Fast track",
|
||||
"Fast track proposal": "Fast track proposal",
|
||||
"If this proposal is passed, the changes will be applied via dispatch and the deposit returned.": "If this proposal is passed, the changes will be applied via dispatch and the deposit returned.",
|
||||
"No active proposals": "No active proposals",
|
||||
"No active referendums": "No active referendums",
|
||||
"No external proposal": "No external proposal",
|
||||
@ -13,6 +14,7 @@
|
||||
"Register the vote for or against the proposal.": "Register the vote for or against the proposal.",
|
||||
"Second": "Second",
|
||||
"Second proposal": "Second proposal",
|
||||
"Seconding a proposal that indicates your backing for the proposal. Proposals with greater interest moves up the queue for potential next referendums.": "Seconding a proposal that indicates your backing for the proposal. Proposals with greater interest moves up the queue for potential next referendums.",
|
||||
"Seconding in a pre-approval that indicates your backing for the proposal. Proposal with greater interest moves up the queue for potential next referendums.": "Seconding in a pre-approval that indicates your backing for the proposal. Proposal with greater interest moves up the queue for potential next referendums.",
|
||||
"Seconds ({{count}})": "Seconds ({{count}})",
|
||||
"Select the account you wish to make the proposal with.": "Select the account you wish to make the proposal with.",
|
||||
@ -34,6 +36,7 @@
|
||||
"The locked value for this proposal": "The locked value for this proposal",
|
||||
"The minimum deposit required": "The minimum deposit required",
|
||||
"The preimage hash of the proposal": "The preimage hash of the proposal",
|
||||
"The proposal is in the queue for future referendums. One proposal from this list will move forward to voting.": "The proposal is in the queue for future referendums. One proposal from this list will move forward to voting.",
|
||||
"The proposal will be registered from this account and the balance lock will be applied here.": "The proposal will be registered from this account and the balance lock will be applied here.",
|
||||
"The referendum info that is voted upon. If passed, the changed will be applied via dispatch and the deposit returned.": "The referendum info that is voted upon. If passed, the changed will be applied via dispatch and the deposit returned.",
|
||||
"The vote will be recorded for this account. If another account delegated to this one, the delegated votes will also be counted.": "The vote will be recorded for this account. If another account delegated to this one, the delegated votes will also be counted.",
|
||||
|
||||
@ -15,11 +15,14 @@
|
||||
"The input data to hash. This can be either specified as a hex value (0x-prefix) or as a string.": "The input data to hash. This can be either specified as a hex value (0x-prefix) or as a string.",
|
||||
"The input data to sign. This can be either specified as a hex value (0x-prefix) or as a string.": "The input data to sign. This can be either specified as a hex value (0x-prefix) or as a string.",
|
||||
"The resulting signature of the input data, as done with the crypto algorithm from the account. (This could be non-deterministic for some types such as sr25519).": "The resulting signature of the input data, as done with the crypto algorithm from the account. (This could be non-deterministic for some types such as sr25519).",
|
||||
"The selected account to be unlocked.": "The selected account to be unlocked.",
|
||||
"The signature as by the account being checked, supplied as a hex-formatted string.": "The signature as by the account being checked, supplied as a hex-formatted string.",
|
||||
"This account that will perform the message signing.": "This account that will perform the message signing.",
|
||||
"This external account cannot be used to sign data. Only Limited support is currently available for signing from any non-internal accounts.": "This external account cannot be used to sign data. Only Limited support is currently available for signing from any non-internal accounts.",
|
||||
"This injected account cannot be used to sign data since the extension does not support raw signing.": "This injected account cannot be used to sign data since the extension does not support raw signing.",
|
||||
"Unlock": "Unlock",
|
||||
"Unlock account": "Unlock account",
|
||||
"Unlock the account for signing. Once active the signature will be generated based on the content provided.": "Unlock the account for signing. Once active the signature will be generated based on the content provided.",
|
||||
"Verify signature": "Verify signature",
|
||||
"Yes": "Yes",
|
||||
"You are about to unlock your account to allow for the signing of messages. Once active the signature will be generated based on the content provided.": "You are about to unlock your account to allow for the signing of messages. Once active the signature will be generated based on the content provided.",
|
||||
|
||||
@ -159,7 +159,9 @@
|
||||
"Hash data": "",
|
||||
"I'm Online": "",
|
||||
"If the recipient account is new, the balance needs to be more than the existential deposit. Likewise if the sending account balance drops below the same value, the account will be removed from the state.": "",
|
||||
"If this proposal is passed, the changes will be applied via dispatch and the deposit returned.": "",
|
||||
"Important notice": "",
|
||||
"In calculating the election outcome, this prioitized vote ordering will be used to determine the final score for the candidates.": "",
|
||||
"Inactive nominations ({{count}})": "",
|
||||
"Include an optional tip for faster processing": "",
|
||||
"Initializing connection": "",
|
||||
@ -326,6 +328,7 @@
|
||||
"Search for": "",
|
||||
"Second": "",
|
||||
"Second proposal": "",
|
||||
"Seconding a proposal that indicates your backing for the proposal. Proposals with greater interest moves up the queue for potential next referendums.": "",
|
||||
"Seconding in a pre-approval that indicates your backing for the proposal. Proposal with greater interest moves up the queue for potential next referendums.": "",
|
||||
"Seconds ({{count}})": "",
|
||||
"Select Network": "",
|
||||
@ -496,6 +499,7 @@
|
||||
"The percentage reward (0-100) that should be applied for the validator": "",
|
||||
"The preimage hash of the proposal": "",
|
||||
"The private key for your account is derived from this seed. This seed must be kept secret as anyone in its possession has access to the funds of this account. If you validate, use the seed of the session account as the \"--key\" parameter of your node.": "",
|
||||
"The proposal is in the queue for future referendums. One proposal from this list will move forward to voting.": "",
|
||||
"The proposal that will be affected. Once closed for the current voting round, it would need to be re-submitted to council for a subsequent voting round.": "",
|
||||
"The proposal will be registered from this account and the balance lock will be applied here.": "",
|
||||
"The reason why this tip should be paid.": "",
|
||||
@ -503,6 +507,7 @@
|
||||
"The resulting signature of the input data, as done with the crypto algorithm from the account. (This could be non-deterministic for some types such as sr25519).": "",
|
||||
"The scheduling preference for this parachain.": "",
|
||||
"The scheduling setting for this parachain.": "",
|
||||
"The selected account to be unlocked.": "",
|
||||
"The selected account to perform the derivation on.": "",
|
||||
"The selected validators to nominate, either via the \"currently best algorithm\" or via a manual selection.": "",
|
||||
"The sending account that will be used to send this transaction. Any applicable fees will be paid by this account.": "",
|
||||
@ -523,14 +528,19 @@
|
||||
"The twitter name for this identity.": "",
|
||||
"The type of council proposal to submit.": "",
|
||||
"The unapplied slashed era to cancel.": "",
|
||||
"The value associated with this vote. The amount will be locked (not available for transfer) and used in all subsequent elections.": "",
|
||||
"The value is not in a valid address format": "",
|
||||
"The value is the amount that is being asked for and that will be allocated to the beneficiary if the proposal is approved.": "",
|
||||
"The vote will be recorded for the selected account.": "",
|
||||
"The vote will be recorded for this account. If another account delegated to this one, the delegated votes will also be counted.": "",
|
||||
"The votes for the members, runner-ups and candidates. These should be ordered based on your priority.": "",
|
||||
"The voting period to apply in blocks": "",
|
||||
"There are no registered parachains": "",
|
||||
"There is currently an ongoing election for new validator candidates. As such staking operations are not permitted.": "",
|
||||
"Think of the stash as your cold wallet and the controller as your hot wallet. Funding operations are controlled by the stash, any other non-funding actions by the controller itself.": "",
|
||||
"This account is recoverable, with the following friends:": "",
|
||||
"This account that will perform the message signing.": "",
|
||||
"This account will appear in the list of candidates. With enough votes in an election, it will become either a runner-up or a council member.": "",
|
||||
"This account will be use to approve each candidate.": "",
|
||||
"This account will make the proposal and be responsible for the bond.": "",
|
||||
"This account will pay the fees for the preimage, based on the size thereof.": "",
|
||||
@ -569,6 +579,7 @@
|
||||
"Unknown Owner": "",
|
||||
"Unlock": "",
|
||||
"Unlock account": "",
|
||||
"Unlock the account for signing. Once active the signature will be generated based on the content provided.": "",
|
||||
"Unlock the sending account to allow signing of this transaction.": "",
|
||||
"Update metadata": "",
|
||||
"Upload": "",
|
||||
|
||||
@ -15,7 +15,7 @@ import { compactAddLength } from '@polkadot/util';
|
||||
import ContractModal, { ContractModalProps, ContractModalState } from '../Modal';
|
||||
import store from '../store';
|
||||
import translate from '../translate';
|
||||
import { GAS_LIMIT } from '../constants';
|
||||
import { DEFAULT_GAS_LIMIT } from '../constants';
|
||||
|
||||
interface Props extends ContractModalProps, ApiProps {}
|
||||
|
||||
@ -36,7 +36,7 @@ class Upload extends ContractModal<Props, State> {
|
||||
|
||||
this.defaultState = {
|
||||
...this.defaultState,
|
||||
gasLimit: new BN(GAS_LIMIT),
|
||||
gasLimit: new BN(DEFAULT_GAS_LIMIT),
|
||||
isGasLimit: api.tx.contracts.putCode.meta.args.length === 2,
|
||||
isWasmValid: false,
|
||||
wasm: null
|
||||
|
||||
@ -17,7 +17,7 @@ import Params from '../Params';
|
||||
import Outcome from './Outcome';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import { GAS_LIMIT } from '../constants';
|
||||
import { DEFAULT_GAS_LIMIT } from '../constants';
|
||||
import { getCallMessageOptions } from './util';
|
||||
|
||||
interface Props extends BareProps {
|
||||
@ -37,7 +37,7 @@ function Call (props: Props): React.ReactElement<Props> | null {
|
||||
|
||||
const [accountId, setAccountId] = useState<StringOrNull>(null);
|
||||
const [endowment, setEndowment] = useState<BN>(new BN(0));
|
||||
const [gasLimit, setGasLimit] = useState<BN>(new BN(GAS_LIMIT));
|
||||
const [gasLimit, setGasLimit] = useState<BN>(new BN(DEFAULT_GAS_LIMIT));
|
||||
const [isBusy, setIsBusy] = useState(false);
|
||||
const [outcomes, setOutcomes] = useState<ContractCallOutcome[]>([]);
|
||||
const [params, setParams] = useState<any[]>(callMessage ? callMessage.def.args.map(({ type }): any => createValue({ type })) : []);
|
||||
@ -172,7 +172,7 @@ function Call (props: Props): React.ReactElement<Props> | null {
|
||||
value={endowment}
|
||||
/>
|
||||
<InputNumber
|
||||
defaultValue={gasLimit}
|
||||
defaultValue={DEFAULT_GAS_LIMIT}
|
||||
help={t('The maximum amount of gas that can be used by this call. If the code requires more, the call will fail.')}
|
||||
isDisabled={isBusy}
|
||||
isError={!isGasValid}
|
||||
|
||||
@ -22,7 +22,7 @@ import ContractModal, { ContractModalProps, ContractModalState } from './Modal';
|
||||
import Params from './Params';
|
||||
import store from './store';
|
||||
import translate from './translate';
|
||||
import { ENDOWMENT, GAS_LIMIT } from './constants';
|
||||
import { ENDOWMENT, DEFAULT_GAS_LIMIT } from './constants';
|
||||
|
||||
type ConstructOptions = { key: string; text: React.ReactNode; value: string }[];
|
||||
|
||||
@ -53,7 +53,7 @@ class Deploy extends ContractModal<Props, State> {
|
||||
constructOptions: [],
|
||||
constructorIndex: -1,
|
||||
endowment: new BN(ENDOWMENT),
|
||||
gasLimit: new BN(GAS_LIMIT),
|
||||
gasLimit: new BN(DEFAULT_GAS_LIMIT),
|
||||
isHashValid: false,
|
||||
params: [],
|
||||
...Deploy.getCodeState(props.codeHash)
|
||||
|
||||
@ -3,7 +3,9 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export const ENDOWMENT = 1000;
|
||||
export const GAS_LIMIT = 500000;
|
||||
|
||||
export const DEFAULT_GAS_LIMIT = '500000';
|
||||
|
||||
export const CONTRACT_NULL = {
|
||||
abi: null,
|
||||
address: null
|
||||
|
||||
@ -20,14 +20,22 @@ function SubmitCandidacy (): React.ReactElement {
|
||||
<Modal
|
||||
header={t('Submit your council candidacy')}
|
||||
onClose={onClose}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<InputAddress
|
||||
help={t('Select the account you wish to submit for candidacy.')}
|
||||
label={t('candidate account')}
|
||||
onChange={setAcountId}
|
||||
type='account'
|
||||
/>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
help={t('Select the account you wish to submit for candidacy.')}
|
||||
label={t('candidate account')}
|
||||
onChange={setAcountId}
|
||||
type='account'
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('This account will appear in the list of candidates. With enough votes in an election, it will become either a runner-up or a council member.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={onClose}>
|
||||
<TxButton
|
||||
|
||||
@ -35,8 +35,8 @@ function Vote ({ electionsInfo }: Props): React.ReactElement<Props> {
|
||||
setAvailable(
|
||||
members
|
||||
.map(([accountId]): string => accountId.toString())
|
||||
.concat(runnersUp.map(([accountId]): string => accountId.toString()))
|
||||
.concat(candidates.map((accountId): string => accountId.toString()))
|
||||
.concat(runnersUp.map(([accountId]) => accountId.toString()))
|
||||
.concat(candidates.map((accountId) => accountId.toString()))
|
||||
);
|
||||
}
|
||||
}, [electionsInfo]);
|
||||
@ -60,27 +60,52 @@ function Vote ({ electionsInfo }: Props): React.ReactElement<Props> {
|
||||
onClick={toggleVisible}
|
||||
/>
|
||||
{isVisible && (
|
||||
<Modal header={t('Vote for current candidates')}>
|
||||
<Modal
|
||||
header={t('Vote for current candidates')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<InputAddress
|
||||
help={t('This account will be use to approve each candidate.')}
|
||||
label={t('voting account')}
|
||||
onChange={setAccountId}
|
||||
type='account'
|
||||
/>
|
||||
<VoteValue
|
||||
accountId={accountId}
|
||||
onChange={setVoteValue}
|
||||
/>
|
||||
<InputAddressMulti
|
||||
available={available}
|
||||
availableLabel={t('council candidates')}
|
||||
defaultValue={defaultVotes}
|
||||
help={t('Select and order council candidates you wish to vote for.')}
|
||||
maxCount={MAX_VOTES}
|
||||
onChange={setVotes}
|
||||
valueLabel={t('my ordered votes')}
|
||||
/>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
help={t('This account will be use to approve each candidate.')}
|
||||
label={t('voting account')}
|
||||
onChange={setAccountId}
|
||||
type='account'
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('The vote will be recorded for the selected account.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<VoteValue
|
||||
accountId={accountId}
|
||||
onChange={setVoteValue}
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('The value associated with this vote. The amount will be locked (not available for transfer) and used in all subsequent elections.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddressMulti
|
||||
available={available}
|
||||
availableLabel={t('council candidates')}
|
||||
defaultValue={defaultVotes}
|
||||
help={t('Select and order council candidates you wish to vote for.')}
|
||||
maxCount={MAX_VOTES}
|
||||
onChange={setVotes}
|
||||
valueLabel={t('my ordered votes')}
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('The votes for the members, runner-ups and candidates. These should be ordered based on your priority.')}</p>
|
||||
<p>{t('In calculating the election outcome, this prioitized vote ordering will be used to determine the final score for the candidates.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={toggleVisible}>
|
||||
<TxButton
|
||||
|
||||
@ -39,10 +39,17 @@ function Seconding ({ depositors, image, proposalId }: Props): React.ReactElemen
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<ProposedAction
|
||||
idNumber={proposalId}
|
||||
proposal={image?.proposal}
|
||||
/>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<ProposedAction
|
||||
idNumber={proposalId}
|
||||
proposal={image?.proposal}
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('The proposal is in the queue for future referendums. One proposal from this list will move forward to voting.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
@ -54,7 +61,7 @@ function Seconding ({ depositors, image, proposalId }: Props): React.ReactElemen
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('Seconding in a pre-approval that indicates your backing for the proposal. Proposal with greater interest moves up the queue for potential next referendums.')}</p>
|
||||
<p>{t('Seconding a proposal that indicates your backing for the proposal. Proposals with greater interest moves up the queue for potential next referendums.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
|
||||
@ -81,7 +81,7 @@ function Voting ({ proposal, referendumId }: Props): React.ReactElement<Props> |
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('The referendum info that is voted upon. If passed, the changed will be applied via dispatch and the deposit returned.')}</p>
|
||||
<p>{t('If this proposal is passed, the changes will be applied via dispatch and the deposit returned.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns>
|
||||
|
||||
@ -93,7 +93,7 @@ function Register ({ nextFreeId = ONE_THOUSAND, sudoKey }: Props): React.ReactEl
|
||||
>
|
||||
<Modal.Content>
|
||||
<InputNumber
|
||||
defaultValue={nextFreeId}
|
||||
defaultValue={nextFreeId.toString()}
|
||||
help={t('The id number to assign to this parachain.')}
|
||||
isError={!isIdValid}
|
||||
label={t('parachain id')}
|
||||
|
||||
@ -52,6 +52,7 @@ function SetSessionKey ({ controllerId, onClose, stashId }: Props): React.ReactE
|
||||
isError={!keys}
|
||||
label={t('Keys from rotateKeys')}
|
||||
onChange={setKeys}
|
||||
placeholder='0x...'
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { KeyringPair } from '@polkadot/keyring/types';
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { AddressRow, Button, Modal, Password } from '@polkadot/react-components';
|
||||
import { Button, InputAddress, Modal, Password } from '@polkadot/react-components';
|
||||
|
||||
import { useTranslation } from './translate';
|
||||
|
||||
@ -54,14 +54,24 @@ function Unlock ({ onClose, onUnlock, pair }: Props): React.ReactElement<Props>
|
||||
<Modal
|
||||
className='toolbox--Unlock'
|
||||
header={t('Unlock account')}
|
||||
size='large'
|
||||
>
|
||||
<Modal.Content>
|
||||
<AddressRow
|
||||
isInline
|
||||
value={address}
|
||||
>
|
||||
<p>{t('You are about to unlock your account to allow for the signing of messages. Once active the signature will be generated based on the content provided.')}</p>
|
||||
<div>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<InputAddress
|
||||
help={t('The selected account to be unlocked.')}
|
||||
isDisabled
|
||||
label={t('account')}
|
||||
value={address}
|
||||
/>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('This account that will perform the message signing.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
<Modal.Columns>
|
||||
<Modal.Column>
|
||||
<Password
|
||||
autoFocus
|
||||
help={t('The account\'s password specified at the creation of this account.')}
|
||||
@ -71,8 +81,11 @@ function Unlock ({ onClose, onUnlock, pair }: Props): React.ReactElement<Props>
|
||||
onEnter={_onUnlock}
|
||||
value={password}
|
||||
/>
|
||||
</div>
|
||||
</AddressRow>
|
||||
</Modal.Column>
|
||||
<Modal.Column>
|
||||
<p>{t('Unlock the account for signing. Once active the signature will be generated based on the content provided.')}</p>
|
||||
</Modal.Column>
|
||||
</Modal.Columns>
|
||||
</Modal.Content>
|
||||
<Modal.Actions onCancel={onClose}>
|
||||
<Button
|
||||
|
||||
@ -8,7 +8,7 @@ import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { BitLengthOption } from '@polkadot/react-components/constants';
|
||||
import { formatBalance } from '@polkadot/util';
|
||||
import { formatBalance, isBn } from '@polkadot/util';
|
||||
import InputNumber from './InputNumber';
|
||||
|
||||
interface Props extends BareProps {
|
||||
@ -33,10 +33,13 @@ interface Props extends BareProps {
|
||||
}
|
||||
|
||||
const DEFAULT_BITLENGTH = BitLengthOption.CHAIN_SPEC as BitLength;
|
||||
const TEN = new BN(10);
|
||||
|
||||
function InputBalance ({ autoFocus, className, defaultValue: inDefault, help, isDisabled, isError, isFull, isZeroable, label, labelExtra, maxValue, onChange, onEnter, onEscape, placeholder, style, value, withEllipsis, withLabel, withMax }: Props): React.ReactElement<Props> {
|
||||
const defaultValue = inDefault
|
||||
? formatBalance(inDefault, { forceUnit: '-', withSi: false }).replace(',', isDisabled ? ',' : '')
|
||||
? isBn(inDefault)
|
||||
? inDefault.div(TEN.pow(new BN(formatBalance.getDefaults().decimals))).toString()
|
||||
: formatBalance(inDefault, { forceUnit: '-', withSi: false }).replace(',', isDisabled ? ',' : '')
|
||||
: inDefault;
|
||||
|
||||
return (
|
||||
|
||||
@ -18,7 +18,7 @@ import { useTranslation } from './translate';
|
||||
interface Props extends BareProps {
|
||||
autoFocus?: boolean;
|
||||
bitLength?: BitLength;
|
||||
defaultValue?: BN | string;
|
||||
defaultValue?: string;
|
||||
help?: React.ReactNode;
|
||||
isDisabled?: boolean;
|
||||
isError?: boolean;
|
||||
@ -155,13 +155,13 @@ function getValuesFromBn (valueBn: BN, si: SiDef | null): [string, BN, boolean]
|
||||
];
|
||||
}
|
||||
|
||||
function getValues (value: BN | string, si: SiDef | null, bitLength: BitLength, isZeroable: boolean, maxValue?: BN): [string, BN, boolean] {
|
||||
function getValues (value: BN | string = ZERO, si: SiDef | null, bitLength: BitLength, isZeroable: boolean, maxValue?: BN): [string, BN, boolean] {
|
||||
return isBn(value)
|
||||
? getValuesFromBn(value, si)
|
||||
: getValuesFromString(value, si, bitLength, isZeroable, maxValue);
|
||||
}
|
||||
|
||||
function InputNumber ({ autoFocus, bitLength = DEFAULT_BITLENGTH, className, defaultValue = ZERO, help, isDecimal, isFull, isSi, isDisabled, isError = false, isZeroable = true, label, labelExtra, maxLength, maxValue, onChange, onEnter, onEscape, placeholder, style, value: propsValue }: Props): React.ReactElement<Props> {
|
||||
function InputNumber ({ autoFocus, bitLength = DEFAULT_BITLENGTH, className, defaultValue, help, isDecimal, isFull, isSi, isDisabled, isError = false, isZeroable = true, label, labelExtra, maxLength, maxValue, onChange, onEnter, onEscape, placeholder, style, value: propsValue }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const [si, setSi] = useState<SiDef | null>(isSi ? formatBalance.findSi('-') : null);
|
||||
const [isPreKeyDown, setIsPreKeyDown] = useState(false);
|
||||
@ -185,6 +185,10 @@ function InputNumber ({ autoFocus, bitLength = DEFAULT_BITLENGTH, className, def
|
||||
[_onChangeWithSi, si]
|
||||
);
|
||||
|
||||
useEffect((): void => {
|
||||
defaultValue && _onChange(defaultValue);
|
||||
}, [_onChange, defaultValue]);
|
||||
|
||||
const _onKeyDown = useCallback(
|
||||
(event: React.KeyboardEvent<Element>): void => {
|
||||
if (KEYS_PRE.includes(event.key)) {
|
||||
|
||||
@ -8,7 +8,7 @@ import BN from 'bn.js';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { BalanceVoting } from '@polkadot/react-query';
|
||||
import { formatBalance, isBn } from '@polkadot/util';
|
||||
import { isBn } from '@polkadot/util';
|
||||
|
||||
import InputBalance from './InputBalance';
|
||||
import { useTranslation } from './translate';
|
||||
@ -21,7 +21,7 @@ interface Props {
|
||||
|
||||
interface ValueState {
|
||||
selectedId?: string | null;
|
||||
value?: BN | string;
|
||||
value?: BN;
|
||||
}
|
||||
|
||||
function VoteValue ({ accountId, autoFocus, onChange }: Props): React.ReactElement<Props> | null {
|
||||
@ -30,25 +30,12 @@ function VoteValue ({ accountId, autoFocus, onChange }: Props): React.ReactEleme
|
||||
const allBalances = useCall<DeriveBalancesAll>(api.derive.balances.all, [accountId]);
|
||||
const [{ selectedId, value }, setValue] = useState<ValueState>({});
|
||||
|
||||
// TODO This may be useful elsewhere, so figure out a way to make this a utility
|
||||
useEffect((): void => {
|
||||
// if the set accountId changes and the new balances is for that id, set it
|
||||
if (accountId !== selectedId && allBalances?.accountId.eq(accountId)) {
|
||||
// format, removing ',' separators
|
||||
const formatted = formatBalance(allBalances.lockedBalance, { forceUnit: '-', withSi: false }).replace(',', '');
|
||||
// format the balance
|
||||
// - if > 0 just take the significant portion
|
||||
// - if == 0, just display 0
|
||||
// - if < 0, display the 3 decimal formatted value
|
||||
const value = allBalances.lockedBalance.gtn(0)
|
||||
? formatted.split('.')[0]
|
||||
: allBalances.lockedBalance.eqn(0)
|
||||
? '0'
|
||||
: formatted;
|
||||
|
||||
// set both the selected id (for future checks) and the formatted value
|
||||
setValue({ selectedId: accountId, value });
|
||||
}
|
||||
(accountId !== selectedId) && allBalances?.accountId.eq(accountId) && setValue({
|
||||
selectedId: accountId,
|
||||
value: allBalances.lockedBalance
|
||||
});
|
||||
}, [accountId, selectedId, allBalances]);
|
||||
|
||||
// only do onChange to parent when the BN value comes in, not our formatted version
|
||||
@ -57,14 +44,18 @@ function VoteValue ({ accountId, autoFocus, onChange }: Props): React.ReactEleme
|
||||
}, [onChange, value]);
|
||||
|
||||
const _setValue = useCallback(
|
||||
(value?: BN): void => setValue({ selectedId, value }),
|
||||
[selectedId]
|
||||
(value?: BN) => setValue(({ selectedId }) => ({ selectedId, value })),
|
||||
[]
|
||||
);
|
||||
|
||||
const isDisabled = accountId !== selectedId;
|
||||
|
||||
return (
|
||||
<InputBalance
|
||||
autoFocus={autoFocus}
|
||||
defaultValue={accountId !== selectedId ? undefined : allBalances?.lockedBalance}
|
||||
help={t('The amount that is associated with this vote. This value is is locked for the duration of the vote.')}
|
||||
isDisabled={isDisabled}
|
||||
isZeroable
|
||||
label={t('vote value')}
|
||||
labelExtra={
|
||||
@ -75,7 +66,6 @@ function VoteValue ({ accountId, autoFocus, onChange }: Props): React.ReactEleme
|
||||
}
|
||||
maxValue={allBalances?.votingBalance}
|
||||
onChange={_setValue}
|
||||
value={value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user