Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions packages/app-council/src/Overview/VoteValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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, 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]);

function VoteValue ({ accountId, onChange, t }: Props): React.ReactElement<Props> {
const _setVoteValue = (value?: BN): void => {
onChange(value || ZERO);
};
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)
);
8 changes: 6 additions & 2 deletions packages/react-components/src/InputBalance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
8 changes: 6 additions & 2 deletions packages/react-components/src/InputNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]);
Expand Down Expand Up @@ -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();
}
}
Expand Down