From 2537267f1098ad81f691d0f2d98196e38d71fcad Mon Sep 17 00:00:00 2001 From: meriadec Date: Tue, 3 Apr 2018 13:19:27 +0200 Subject: [PATCH] Handle max when changing fees --- src/components/base/InputCurrency/index.js | 27 ++++++++----- src/components/modals/Send/01-step-amount.js | 22 +++-------- src/components/modals/Send/Footer.js | 13 +++++-- src/components/modals/Send/index.js | 40 ++++++++++++++------ 4 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/components/base/InputCurrency/index.js b/src/components/base/InputCurrency/index.js index c0c8437a..dde49cd6 100644 --- a/src/components/base/InputCurrency/index.js +++ b/src/components/base/InputCurrency/index.js @@ -57,6 +57,7 @@ type Props = { } type State = { + unit: Unit, isFocus: boolean, displayValue: string, } @@ -72,20 +73,23 @@ class InputCurrency extends PureComponent { state = { isFocus: false, displayValue: '0', + unit: this.props.unit, } componentWillMount() { - const { value, unit } = this.props + const { value } = this.props + const { unit } = this.state const displayValue = format(unit, value) this.setState({ displayValue }) } componentWillReceiveProps(nextProps: Props) { + const { unit } = this.state if (this.props.value !== nextProps.value) { const { isFocus } = this.state const displayValue = isFocus - ? (nextProps.value / 10 ** nextProps.unit.magnitude).toString() - : format(nextProps.unit, nextProps.value) + ? (nextProps.value / 10 ** unit.magnitude).toString() + : format(unit, nextProps.value) this.setState({ displayValue }) } } @@ -108,13 +112,14 @@ class InputCurrency extends PureComponent { } handleBlur = () => { - const { unit, value } = this.props + const { value } = this.props + const { unit } = this.state const v = format(unit, value) this.setState({ isFocus: false, displayValue: v }) } handleFocus = () => { - const { unit } = this.props + const { unit } = this.state this.setState(prev => ({ isFocus: true, @@ -123,8 +128,8 @@ class InputCurrency extends PureComponent { } emitOnChange = (v: string) => { - const { onChange, unit } = this.props - const { displayValue } = this.state + const { onChange } = this.props + const { displayValue, unit } = this.state if (displayValue.toString() !== v.toString()) { const satoshiValue = Number(v) * 10 ** unit.magnitude @@ -133,7 +138,8 @@ class InputCurrency extends PureComponent { } renderListUnits = () => { - const { unit, units, onChange, value } = this.props + const { units, value } = this.props + const { unit } = this.state if (units.length <= 1) { return null @@ -145,7 +151,10 @@ class InputCurrency extends PureComponent { bg="lightGraphite" keyProp="code" flatLeft - onChange={item => onChange(unformat(item, value), item)} + onChange={item => { + this.setState({ unit: item, displayValue: format(item, value) }) + // onChange(unformat(item, value), item) + }} items={units} value={unit} renderItem={item => item.code} diff --git a/src/components/modals/Send/01-step-amount.js b/src/components/modals/Send/01-step-amount.js index 498ed276..032f96a5 100644 --- a/src/components/modals/Send/01-step-amount.js +++ b/src/components/modals/Send/01-step-amount.js @@ -3,7 +3,6 @@ import React, { Fragment } from 'react' import type { Account } from '@ledgerhq/wallet-common/lib/types' -import type { Unit } from '@ledgerhq/currencies' import type { T } from 'types/common' import Box from 'components/base/Box' @@ -23,10 +22,7 @@ type PropsStepAmount = { onChange: Function, recipientAddress: string, amount: number, - fees: { - value: number, - unit: Unit | null, - }, + fees: number, isRBF: boolean, t: T, } @@ -61,7 +57,7 @@ function StepAmount(props: PropsStepAmount) { - onChange('fees')({ value, unit })} - /> + onChange('fees')(value)} /> @@ -121,11 +112,10 @@ type PropsFees = { account: Account, amount: number, onChange: Function, - unit: Unit | null, } function Fees(props: PropsFees) { - const { onChange, account, unit, amount } = props + const { onChange, account, amount } = props const { units } = account.currency return ( @@ -135,11 +125,11 @@ function Fees(props: PropsFees) { items={[{ key: 'custom', name: 'Custom' }]} value={{ key: 'custom', name: 'Custom' }} renderSelected={item => item.name} - onChange={() => onChange(amount, unit)} + onChange={() => onChange(amount)} /> - + {'('} { state = INITIAL_STATE _steps = GET_STEPS(this.props.t) + _account: Account | null = null canNext = account => { const { stepIndex } = this.state @@ -90,7 +84,25 @@ class SendModal extends PureComponent { this.setState({ stepIndex: stepIndex + 1 }) } - createChangeHandler = key => value => this.setState({ [key]: value }) + createChangeHandler = key => value => { + const patch = { [key]: value } + // ensure max is always restecped when changing fees + if (key === 'fees') { + const { amount } = this.state + // if changing fees goes further than max, change amount + if (this._account && amount + value > this._account.balance) { + const diff = amount + value - this._account.balance + patch.amount = amount - diff + // if the user is a little joker, and try to put fees superior + // to the max, let's reset amount to 0 and put fees to max. + if (patch.amount < 0) { + patch.amount = 0 + patch.fees = this._account.balance + } + } + } + this.setState(patch) + } renderStep = acc => { const { stepIndex, account, amount, ...othersState } = this.state @@ -110,7 +122,7 @@ class SendModal extends PureComponent { render() { const { t } = this.props - const { stepIndex, amount, account } = this.state + const { stepIndex, amount, account, fees } = this.state return ( { render={({ data, onClose }) => { const acc = account || get(data, 'account', null) const canNext = this.canNext(acc) + + // hack: access the selected account, living in modal data, outside + // of the modal render function + this._account = acc + return ( {t('send:title')} @@ -132,6 +149,7 @@ class SendModal extends PureComponent { onNext={this.handleNextStep} account={acc} amount={amount} + fees={fees} t={t} /> )}