Auto-populate Vote balance (#1879)

* Auto-populate Vote balance

* Commenting
This commit is contained in:
Jaco Greeff 2019-11-14 10:44:15 +01:00 committed by GitHub
parent c85062d839
commit 918822f48a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 12 deletions

View File

@ -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)
);

View File

@ -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}

View File

@ -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();
}
}