Browse Source

Handle max when changing fees

master
meriadec 7 years ago
parent
commit
2537267f10
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 27
      src/components/base/InputCurrency/index.js
  2. 22
      src/components/modals/Send/01-step-amount.js
  3. 13
      src/components/modals/Send/Footer.js
  4. 40
      src/components/modals/Send/index.js

27
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<Props, State> {
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<Props, State> {
}
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<Props, State> {
}
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<Props, State> {
}
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<Props, State> {
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}

22
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) {
<Box flow={1}>
<Label>{t('send:steps.amount.amount')}</Label>
<RequestAmount
max={account.balance - 0}
max={account.balance - fees}
account={account}
onChange={onChange('amount')}
value={amount}
@ -75,12 +71,7 @@ function StepAmount(props: PropsStepAmount) {
<LabelInfoTooltip ml={1} text={t('send:steps.amount.fees')} />
</Label>
<Box horizontal flow={5}>
<Fees
amount={fees.value}
unit={fees.unit}
account={account}
onChange={(value, unit) => onChange('fees')({ value, unit })}
/>
<Fees amount={fees} account={account} onChange={value => onChange('fees')(value)} />
</Box>
</Box>
@ -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)}
/>
<InputCurrency
unit={units[0]}
units={units}
unit={unit || units[0]}
containerProps={{ grow: true }}
value={amount}
onChange={onChange}

13
src/components/modals/Send/Footer.js

@ -17,24 +17,31 @@ type Props = {
t: T,
account: Account,
amount: number,
fees: number,
onNext: Function,
canNext: boolean,
}
function Footer({ account, amount, t, onNext, canNext }: Props) {
function Footer({ account, amount, fees, t, onNext, canNext }: Props) {
return (
<ModalFooter horizontal alignItems="center">
<Box grow>
<Label>{t('send:totalSpent')}</Label>
<Box horizontal flow={2} align="center">
<FormattedVal disableRounding color="dark" val={amount} unit={account.unit} showCode />
<FormattedVal
disableRounding
color="dark"
val={amount + fees}
unit={account.unit}
showCode
/>
<Box horizontal align="center">
<Text ff="Rubik" fontSize={3}>
{'('}
</Text>
<CounterValue
ticker={account.currency.units[0].code}
value={amount}
value={amount + fees}
disableRounding
color="grey"
fontSize={3}

40
src/components/modals/Send/index.js

@ -5,7 +5,6 @@ import { translate } from 'react-i18next'
import get from 'lodash/get'
import type { Account } from '@ledgerhq/wallet-common/lib/types'
import type { Unit } from '@ledgerhq/currencies'
import type { T } from 'types/common'
import { MODAL_SEND } from 'config/constants'
@ -28,12 +27,9 @@ type State = {
stepIndex: number,
isDeviceReady: boolean,
amount: number,
fees: number,
account: Account | null,
recipientAddress: string,
fees: {
value: number,
unit: Unit | null,
},
isRBF: boolean,
}
@ -50,10 +46,7 @@ const INITIAL_STATE = {
account: null,
recipientAddress: '',
amount: 0,
fees: {
value: 0,
unit: null,
},
fees: 0,
isRBF: false,
}
@ -61,6 +54,7 @@ class SendModal extends PureComponent<Props, State> {
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<Props, State> {
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<Props, State> {
render() {
const { t } = this.props
const { stepIndex, amount, account } = this.state
const { stepIndex, amount, account, fees } = this.state
return (
<Modal
@ -119,6 +131,11 @@ class SendModal extends PureComponent<Props, State> {
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 (
<ModalBody onClose={onClose} deferHeight={acc ? 630 : 355}>
<ModalTitle>{t('send:title')}</ModalTitle>
@ -132,6 +149,7 @@ class SendModal extends PureComponent<Props, State> {
onNext={this.handleNextStep}
account={acc}
amount={amount}
fees={fees}
t={t}
/>
)}

Loading…
Cancel
Save