Cleanup InputNumber, simplify (#2648)

This commit is contained in:
Jaco Greeff 2020-04-28 13:46:49 +02:00 committed by GitHub
parent 71ffd6ec10
commit 57d8bfc80e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 65 deletions

View File

@ -11,11 +11,16 @@ import { useEffect, useState } from 'react';
import { registry } from '@polkadot/react-api';
import { useAccounts, useApi, useCall, useDebounce, useFavorites } from '@polkadot/react-hooks';
import { Option } from '@polkadot/types';
import { formatBalance } from '@polkadot/util';
import { STORE_FAVS_BASE } from './constants';
const PERBILL = new BN(1_000_000_000);
function baseBalance (): BN {
return new BN('1'.padEnd(formatBalance.getDefaults().decimals + 4, '0'));
}
function mapIndex (mapBy: TargetSortBy): (info: ValidatorInfo, index: number) => ValidatorInfo {
return (info, index): ValidatorInfo => {
info[mapBy] = index + 1;
@ -58,7 +63,7 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] {
);
}
function extractInfo (allAccounts: string[], amount: BN = new BN(0), electedInfo: DeriveStakingElected, favorites: string[], lastReward = new BN(1)): Partial<SortedTargets> {
function extractInfo (allAccounts: string[], amount: BN = baseBalance(), electedInfo: DeriveStakingElected, favorites: string[], lastReward = new BN(1)): Partial<SortedTargets> {
const nominators: string[] = [];
let totalStaked = new BN(0);
const perValidatorReward = lastReward.divn(electedInfo.info.length);
@ -134,7 +139,7 @@ export default function useSortedTargets (): SortedTargets {
const lastReward = useCall<BN>(lastEra && api.query.staking.erasValidatorReward, [lastEra], {
transform: (optBalance: Option<Balance>) => optBalance.unwrapOrDefault()
});
const [calcWith, setCalcWith] = useState<BN | undefined>(new BN(1_000));
const [calcWith, setCalcWith] = useState<BN | undefined>(baseBalance());
const calcWithDebounce = useDebounce(calcWith);
const [state, setState] = useState<SortedTargets>({ setCalcWith, toggleFavorite });

View File

@ -26,7 +26,7 @@ interface Props extends BareProps {
onEnter?: () => void;
onEscape?: () => void;
placeholder?: string;
value?: BN | string;
value?: BN;
withEllipsis?: boolean;
withLabel?: boolean;
withMax?: boolean;

View File

@ -7,17 +7,14 @@ import { BareProps, BitLength } from './types';
import BN from 'bn.js';
import React, { useCallback, useEffect, useState } from 'react';
import { formatBalance } from '@polkadot/util';
import { formatBalance, isBn } from '@polkadot/util';
import { classes } from './util';
import { BitLengthOption } from './constants';
// import Button from './Button';
import Dropdown from './Dropdown';
import Input, { KEYS, KEYS_PRE } from './Input';
import { useTranslation } from './translate';
// const ALLOW_MAX = false;
interface Props extends BareProps {
autoFocus?: boolean;
bitLength?: BitLength;
@ -37,7 +34,7 @@ interface Props extends BareProps {
onEnter?: () => void;
onEscape?: () => void;
placeholder?: string;
value?: BN | string;
value?: BN;
withEllipsis?: boolean;
withLabel?: boolean;
withMax?: boolean;
@ -68,13 +65,12 @@ function getRegex (isDecimal: boolean): RegExp {
}
function getSiOptions (): { text: string; value: string }[] {
return formatBalance.getOptions()
.map(({ power, text, value }): { text: string; value: string } => ({
text: power === 0
? TokenUnit.abbr
: text,
value
}));
return formatBalance.getOptions().map(({ power, text, value }): { text: string; value: string } => ({
text: power === 0
? TokenUnit.abbr
: text,
value
}));
}
function getSiPowers (si: SiDef | null): [BN, number, number] {
@ -87,7 +83,7 @@ function getSiPowers (si: SiDef | null): [BN, number, number] {
return [new BN(basePower + si.power), basePower, si.power];
}
function isValidNumber (bn: BN, { bitLength = DEFAULT_BITLENGTH, isZeroable, maxValue }: Props): boolean {
function isValidNumber (bn: BN, bitLength: BitLength, isZeroable: boolean, maxValue?: BN): boolean {
if (
// cannot be negative
bn.lt(ZERO) ||
@ -106,7 +102,7 @@ function isValidNumber (bn: BN, { bitLength = DEFAULT_BITLENGTH, isZeroable, max
return true;
}
function inputToBn (input: string, si: SiDef | null, props: Props): [BN, boolean] {
function inputToBn (input: string, si: SiDef | null, bitLength: BitLength, isZeroable: boolean, maxValue?: BN): [BN, boolean] {
const [siPower, basePower, siUnitPower] = getSiPowers(si);
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
@ -133,12 +129,12 @@ function inputToBn (input: string, si: SiDef | null, props: Props): [BN, boolean
return [
result,
isValidNumber(result, props)
isValidNumber(result, bitLength, isZeroable, maxValue)
];
}
function getValuesFromString (value: string, si: SiDef | null, props: Props): [string, BN, boolean] {
const [valueBn, isValid] = inputToBn(value, si, props);
function getValuesFromString (value: string, si: SiDef | null, bitLength: BitLength, isZeroable: boolean, maxValue?: BN): [string, BN, boolean] {
const [valueBn, isValid] = inputToBn(value, si, bitLength, isZeroable, maxValue);
return [
value,
@ -149,7 +145,7 @@ function getValuesFromString (value: string, si: SiDef | null, props: Props): [s
function getValuesFromBn (valueBn: BN, si: SiDef | null): [string, BN, boolean] {
const value = si
? valueBn.div(TEN.pow(new BN(si.power))).toString()
? valueBn.div(TEN.pow(new BN(formatBalance.getDefaults().decimals + si.power))).toString()
: valueBn.toString();
return [
@ -159,46 +155,29 @@ function getValuesFromBn (valueBn: BN, si: SiDef | null): [string, BN, boolean]
];
}
function getValues (value: BN | string, si: SiDef | null, props: Props): [string, BN, boolean] {
return BN.isBN(value)
function getValues (value: BN | string, si: SiDef | null, bitLength: BitLength, isZeroable: boolean, maxValue?: BN): [string, BN, boolean] {
return isBn(value)
? getValuesFromBn(value, si)
: getValuesFromString(value, si, props);
: getValuesFromString(value, si, bitLength, isZeroable, maxValue);
}
function isNewPropsValue (propsValue: BN | string, value: string, valueBn: BN): boolean {
return BN.isBN(propsValue) ? !propsValue.eq(valueBn) : propsValue !== value;
}
function InputNumber (props: Props): React.ReactElement<Props> {
function InputNumber ({ 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> {
const { t } = useTranslation();
const { bitLength = DEFAULT_BITLENGTH, className, defaultValue = ZERO, help, isDecimal, isFull, isSi, isDisabled, isError = false, maxLength, maxValue, onChange, onEnter, onEscape, placeholder, style, value: propsValue } = props;
const [si, setSi] = useState<SiDef | null>(isSi ? formatBalance.findSi('-') : null);
const [isPreKeyDown, setIsPreKeyDown] = useState(false);
const [[value, valueBn, isValid], setValues] = useState<[string, BN, boolean]>(
getValues(propsValue || defaultValue, si, props)
getValues(propsValue || defaultValue, si, bitLength, isZeroable, maxValue)
);
useEffect((): void => {
propsValue && isNewPropsValue(propsValue, value, valueBn) && setValues(getValues(propsValue, si, props));
// ummmm...
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [propsValue]);
useEffect((): void => {
setValues(getValues(value, si, props));
// ummmm...
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [value, si, bitLength, maxValue]);
useEffect((): void => {
onChange && onChange(valueBn);
}, [onChange, valueBn]);
const _onChange = useCallback(
(input: string) => setValues(getValuesFromString(input, si, props)),
[props, si]
(input: string) => setValues(
getValuesFromString(input, si, bitLength, isZeroable, maxValue)
),
[bitLength, isZeroable, maxValue, si]
);
const _onKeyDown = useCallback(
@ -250,13 +229,14 @@ function InputNumber (props: Props): React.ReactElement<Props> {
return (
<Input
{...props}
className={classes('ui--InputNumber', className)}
help={help}
isAction={isSi}
isDisabled={isDisabled}
isError={!isValid || isError}
isFull={isFull}
label={label}
labelExtra={labelExtra}
maxLength={maxLength || maxValueLength}
onChange={_onChange}
onEnter={onEnter}
@ -269,15 +249,6 @@ function InputNumber (props: Props): React.ReactElement<Props> {
type='text'
value={value}
>
{/* (ALLOW_MAX && withMax && !!maxValue && valueBn.lt(maxValue)) && (
<Button
className='ui--MaxButton'
icon=''
onClick={_onClickMaxButton}
>
{t('Max')}
</Button>
) */}
{!!si && (
<Dropdown
defaultValue={si.value}

View File

@ -40,8 +40,8 @@ interface Props extends I18nProps, ApiProps, BaseProps {
}
interface State {
accountNonce?: string;
blocks: string;
accountNonce?: BN;
blocks: BN;
currentItem?: QueueTx;
isQrScanning: boolean;
isQrVisible: boolean;
@ -49,7 +49,7 @@ interface State {
isSendable: boolean;
isSubmit: boolean;
multiApproval: boolean;
nonce?: string;
nonce?: BN;
password: string;
qrAddress: string;
qrPayload: Uint8Array;
@ -117,7 +117,7 @@ async function makeExtrinsicSignature (
const initialState: State = {
accountNonce: undefined,
blocks: '50',
blocks: new BN(50),
isQrScanning: false,
isQrVisible: false,
isRenderError: false,
@ -429,11 +429,11 @@ class Signer extends React.PureComponent<Props, State> {
}
private onChangeNonce = (value?: BN): void => {
this.setState({ nonce: value ? value.toString() : '0' });
this.setState({ nonce: value || new BN(0) });
}
private onChangeBlocks = (value?: BN): void => {
this.setState({ blocks: value ? value.toString() : '0' });
this.setState({ blocks: value || new BN(0) });
}
private onChangeSignatory = (signatory?: string | null): void => {
@ -563,10 +563,10 @@ class Signer extends React.PureComponent<Props, State> {
private updateNonce = async (): Promise<void> => {
const { currentItem } = this.state;
let accountNonce: string | undefined;
let accountNonce: BN | undefined;
if (currentItem?.accountId) {
accountNonce = (await this.props.api.rpc.account.nextIndex(currentItem.accountId)).toString();
accountNonce = await this.props.api.rpc.account.nextIndex(currentItem.accountId);
} else {
accountNonce = undefined;
}