Auto-populate Vote balance (#1879)
* Auto-populate Vote balance * Commenting
This commit is contained in:
parent
c85062d839
commit
918822f48a
@ -6,9 +6,11 @@ import { DerivedBalances } from '@polkadot/api-derive/types';
|
||||
import { I18nProps } from '@polkadot/react-components/types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { withCalls } from '@polkadot/react-api';
|
||||
import { InputBalance } from '@polkadot/react-components';
|
||||
import { BalanceVoting } from '@polkadot/react-query';
|
||||
import { formatBalance, isBn } from '@polkadot/util';
|
||||
|
||||
import translate from '../translate';
|
||||
|
||||
@ -18,21 +20,60 @@ interface Props extends I18nProps {
|
||||
onChange: (value: BN) => void;
|
||||
}
|
||||
|
||||
const ZERO = new BN(0);
|
||||
interface ValueState {
|
||||
selectedId?: string | null;
|
||||
value?: BN | string;
|
||||
}
|
||||
|
||||
function VoteValue ({ accountId, onChange, t }: Props): React.ReactElement<Props> {
|
||||
const _setVoteValue = (value?: BN): void => {
|
||||
onChange(value || ZERO);
|
||||
};
|
||||
function VoteValue ({ accountId, allBalances, onChange, t }: Props): React.ReactElement<Props> | null {
|
||||
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]
|
||||
// if =
|
||||
: 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]);
|
||||
|
||||
// only do onChange to parent when the BN value comes in, not our formatted version
|
||||
useEffect((): void => {
|
||||
isBn(value) && onChange(value);
|
||||
}, [value]);
|
||||
|
||||
const _setValue = (value?: BN): void => setValue({ selectedId, value });
|
||||
|
||||
return (
|
||||
<InputBalance
|
||||
help={t('The amount that is associated with this vote. This value is is locked for the duration of the vote.')}
|
||||
label={t('vote value')}
|
||||
labelExtra={<BalanceVoting label={<label>{t('voting balance')}</label>} params={accountId} />}
|
||||
onChange={_setVoteValue}
|
||||
maxValue={allBalances?.votingBalance}
|
||||
onChange={_setValue}
|
||||
value={value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(VoteValue);
|
||||
export default translate(
|
||||
withCalls<Props>(
|
||||
['derive.balances.all', {
|
||||
paramName: 'accountId',
|
||||
propName: 'allBalances'
|
||||
}]
|
||||
)(VoteValue)
|
||||
);
|
||||
|
||||
@ -32,13 +32,17 @@ interface Props extends BareProps {
|
||||
|
||||
const DEFAULT_BITLENGTH = BitLengthOption.CHAIN_SPEC as BitLength;
|
||||
|
||||
function InputBalance ({ autoFocus, className, defaultValue, help, isDisabled, isError, isZeroable, label, labelExtra, maxValue, onChange, onEnter, placeholder, style, value, withEllipsis, withLabel, withMax }: Props): React.ReactElement<Props> {
|
||||
function InputBalance ({ autoFocus, className, defaultValue: inDefault, help, isDisabled, isError, isZeroable, label, labelExtra, maxValue, onChange, onEnter, placeholder, style, value, withEllipsis, withLabel, withMax }: Props): React.ReactElement<Props> {
|
||||
const defaultValue = inDefault
|
||||
? formatBalance(value, { forceUnit: '-', withSi: false })
|
||||
: inDefault;
|
||||
|
||||
return (
|
||||
<InputNumber
|
||||
autoFocus={autoFocus}
|
||||
className={`ui--InputBalance ${className}`}
|
||||
bitLength={DEFAULT_BITLENGTH}
|
||||
defaultValue={defaultValue ? formatBalance(defaultValue, { forceUnit: '-', withSi: false }) : undefined}
|
||||
defaultValue={defaultValue}
|
||||
help={help}
|
||||
isDisabled={isDisabled}
|
||||
isError={isError}
|
||||
|
||||
@ -87,10 +87,15 @@ function getSiPowers (si: SiDef | null): [BN, number, number] {
|
||||
|
||||
function isValidNumber (bn: BN, { bitLength = DEFAULT_BITLENGTH, isZeroable, maxValue }: Props): boolean {
|
||||
if (
|
||||
// cannot be negative
|
||||
bn.lt(ZERO) ||
|
||||
// cannot be > than allowed max
|
||||
!bn.lt(getGlobalMaxValue(bitLength)) ||
|
||||
// check if 0 and it should be a value
|
||||
(!isZeroable && bn.eq(ZERO)) ||
|
||||
// check that the bitlengths fit
|
||||
bn.bitLength() > (bitLength || DEFAULT_BITLENGTH) ||
|
||||
// cannot be > max (if specified)
|
||||
(maxValue && maxValue.gtn(0) && bn.gt(maxValue))
|
||||
) {
|
||||
return false;
|
||||
@ -197,7 +202,7 @@ function InputNumber (props: Props): React.ReactElement<Props> {
|
||||
);
|
||||
|
||||
useEffect((): void => {
|
||||
if (!!propsValue && isNewPropsValue(propsValue, value, valueBn)) {
|
||||
if (propsValue && isNewPropsValue(propsValue, value, valueBn)) {
|
||||
setValues(getValues(propsValue, si, props));
|
||||
}
|
||||
}, [propsValue]);
|
||||
@ -225,7 +230,6 @@ function InputNumber (props: Props): React.ReactElement<Props> {
|
||||
const newValue = `${value.substring(0, i || 0)}${event.key}${value.substring(j || 0)}`;
|
||||
|
||||
if (!getRegex(isDecimal || !!si).test(newValue)) {
|
||||
console.log(newValue, getRegex(isDecimal || !!si));
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user