Skip to content
This repository has been archived by the owner on May 24, 2022. It is now read-only.

Add Max button to send the whole balance #302

Merged
merged 19 commits into from
Dec 20, 2018
Merged
Show file tree
Hide file tree
Changes from 10 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
104 changes: 86 additions & 18 deletions packages/fether-react/src/Send/TxForm/TxForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Form as FetherForm, Header } from 'fether-ui';
import { inject, observer } from 'mobx-react';
import { isAddress } from '@parity/api/lib/util/address';
import { Link } from 'react-router-dom';
import { toWei } from '@parity/api/lib/util/wei';
import { toWei, fromWei } from '@parity/api/lib/util/wei';
Tbaut marked this conversation as resolved.
Show resolved Hide resolved
import { withProps } from 'recompose';

import { estimateGas } from '../../utils/estimateGas';
Expand All @@ -35,28 +35,58 @@ const MIN_GAS_PRICE = 3; // Safelow gas price from GasStation, in Gwei
@withEthBalance // ETH balance
@observer
class Send extends Component {
state = {
maxSelected: false
};
handleSubmit = values => {
const { accountAddress, history, sendStore, token } = this.props;

sendStore.setTx(values);
history.push(`/send/${token.address}/from/${accountAddress}/signer`);
};

decorator = createDecorator({
field: /to|amount/, // when the value of these fields change...
updates: {
// ...set field "gas"
gas: (value, allValues) => {
const { parityStore, token } = this.props;

if (this.preValidate(allValues) === true) {
return estimateGas(allValues, token, parityStore.api);
} else {
return null;
decorator = createDecorator(
{
field: /to|amount/, // when the value of these fields change...
updates: {
// ...set field "gas"
gas: (value, allValues) => {
const { parityStore, token } = this.props;
if (this.preValidate(allValues) === true) {
return estimateGas(allValues, token, parityStore.api);
} else {
return null;
}
}
}
},
{
field: /gas|gasPrice/, // when the value of these fields change...
updates: {
// ...set field "gas"
amount: (value, allValues) => {
Tbaut marked this conversation as resolved.
Show resolved Hide resolved
if (this.state.maxSelected) {
return this.calculateMax(allValues.gas, allValues.gasPrice);
} else {
// This return is needed for the amount not to be set to 0 when Max is deactivated and gasPrice changes
// TODO understand why returning "value" here makes the amount field change when gasPrice changes..
return allValues.amount;
}
}
}
}
});
);

calculateMax = (gas, gasPrice) => {
const { token, balance } = this.props;

const gasBn = gas ? new BigNumber(gas) : new BigNumber(21000);
const gasPriceBn = new BigNumber(gasPrice);

return token.address === 'ETH'
? fromWei(toWei(balance).minus(gasBn.mul(toWei(gasPriceBn, 'shannon'))))
: balance;
};

render () {
const {
Expand All @@ -65,6 +95,18 @@ class Send extends Component {
token
} = this.props;

const recalculateMax = (args, state, { changeValue }) => {
Tbaut marked this conversation as resolved.
Show resolved Hide resolved
changeValue(state, 'amount', value => {
return this.calculateMax(
state.formState.values.gas,
state.formState.values.gasPrice
);
});
if (args[0].toggleMax) {
this.setState({ maxSelected: !this.state.maxSelected });
}
};

return (
<div>
<Header
Expand All @@ -88,19 +130,42 @@ class Send extends Component {
onSubmit={this.handleSubmit}
validate={this.validateForm}
decorators={[this.decorator]}
render={({ handleSubmit, valid, validating, values }) => (
mutators={{ recalculateMax }}
Tbaut marked this conversation as resolved.
Show resolved Hide resolved
render={({
handleSubmit,
valid,
validating,
values,
form: { mutators }
}) => (
<form className='send-form' onSubmit={handleSubmit}>
<fieldset className='form_fields'>
<Field
className='form_field_amount'
formNoValidate
label='Amount'
name='amount'
disabled={this.state.maxSelected}
placeholder='0.00'
render={FetherForm.Field}
required
type='number' // In ETH or coin
/>
>
<button
type='button'
className={
this.state.maxSelected
? 'button -tiny active max'
: 'button -tiny max'
}
onClick={() => {
Tbaut marked this conversation as resolved.
Show resolved Hide resolved
const args = { toggleMax: true };
mutators.recalculateMax(args);
}}
>
Max
</button>
</Field>

<Field
as='textarea'
Expand All @@ -115,14 +180,14 @@ class Send extends Component {
<Field
centerText={`${values.gasPrice} GWEI`}
className='-range'
label='Transaction Fee'
leftText='Slow'
label='Transaction Speed'
leftText='Low'
max={MAX_GAS_PRICE}
min={MIN_GAS_PRICE}
name='gasPrice'
render={FetherForm.Slider}
required
rightText='Fast'
rightText='High'
step={0.5}
type='range' // In Gwei
/>
Expand Down Expand Up @@ -172,6 +237,9 @@ class Send extends Component {
} else if (amountBn.isZero()) {
return { amount: 'Please enter a non-zero amount' };
} else if (amountBn.isNegative()) {
if (this.state.maxSelected) {
Tbaut marked this conversation as resolved.
Show resolved Hide resolved
return { amount: 'ETH balance too low to pay for gas.' };
}
return { amount: 'Please enter a positive amount' };
} else if (token.symbol === 'ETH' && toWei(values.amount).lt(1)) {
return { amount: 'Please enter at least 1 Wei' };
Expand Down
14 changes: 13 additions & 1 deletion packages/fether-react/src/assets/sass/shared/_button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
cursor: pointer;
}

&:active {
&:active, &.active{
background-color: darken($blue, 2.5%);
color: $white;
}
Expand All @@ -41,6 +41,18 @@
padding: 0 0 0 0.925rem;
opacity: 0.425;

&.max {
padding: 0.325rem 0.675rem;;
border-radius: 1rem;
border: 1px solid $black;

&.active{
background-color: darken($black, 2.5%);
color: $white;
}
}


&:hover {
opacity: 0.625;
background-color: transparent;
Expand Down
2 changes: 1 addition & 1 deletion packages/fether-react/src/assets/sass/shared/_form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ input.form_field_amount[type='number'] {
font-size: ms(6);
line-height: ms(6) * 1.1;
font-weight: 200;
text-align: center;
width: 80%;
-webkit-appearance: none;

&::-webkit-inner-spin-button,
Expand Down
2 changes: 1 addition & 1 deletion packages/fether-ui/src/Form/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// SPDX-License-Identifier: BSD-3-Clause

import { Field } from './Field';
import { Slider } from './Slider';
import { InputFile } from './InputFile';
import { Slider } from './Slider';

export const Form = {
Field,
Expand Down