Token sorting, zero-ETH transfer & token decimals (#2805)
* Error trapping for decimals (Fixes #2799) * Sort tokens by tag (Closes #2789) * PR comments * Always display ETH * Recalculate in all cases (traps >available)
This commit is contained in:
parent
a6fd922ffb
commit
b6f2628018
@ -119,17 +119,19 @@ export default class Details extends Component {
|
|||||||
const { balance, images, tag } = this.props;
|
const { balance, images, tag } = this.props;
|
||||||
|
|
||||||
const items = balance.tokens
|
const items = balance.tokens
|
||||||
.filter((token) => token.value.gt(0))
|
.filter((token, index) => !index || token.value.gt(0))
|
||||||
.map((balance, idx) => {
|
.map((balance, index) => {
|
||||||
const token = balance.token;
|
const token = balance.token;
|
||||||
const isEth = idx === 0;
|
const isEth = index === 0;
|
||||||
const imagesrc = token.image || images[token.address] || imageUnknown;
|
const imagesrc = token.image || images[token.address] || imageUnknown;
|
||||||
let value = 0;
|
let value = 0;
|
||||||
|
|
||||||
if (isEth) {
|
if (isEth) {
|
||||||
value = api.util.fromWei(balance.value).toFormat(3);
|
value = api.util.fromWei(balance.value).toFormat(3);
|
||||||
} else {
|
} else {
|
||||||
value = new BigNumber(balance.value).div(balance.token.format || 1).toFormat(3);
|
const format = balance.token.format || 1;
|
||||||
|
const decimals = format === 1 ? 0 : Math.min(3, Math.floor(format / 10));
|
||||||
|
value = new BigNumber(balance.value).div(format).toFormat(decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
const label = (
|
const label = (
|
||||||
@ -165,7 +167,7 @@ export default class Details extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeToken = (event, idx, tag) => {
|
onChangeToken = (event, index, tag) => {
|
||||||
this.props.onChange('tag', tag);
|
this.props.onChange('tag', tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ const ERRORS = {
|
|||||||
requireRecipient: 'a recipient network address is required for the transaction',
|
requireRecipient: 'a recipient network address is required for the transaction',
|
||||||
invalidAddress: 'the supplied address is an invalid network address',
|
invalidAddress: 'the supplied address is an invalid network address',
|
||||||
invalidAmount: 'the supplied amount should be a valid positive number',
|
invalidAmount: 'the supplied amount should be a valid positive number',
|
||||||
|
invalidDecimals: 'the supplied amount exceeds the allowed decimals',
|
||||||
largeAmount: 'the transaction total is higher than the available balance'
|
largeAmount: 'the transaction total is higher than the available balance'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -297,6 +297,24 @@ export default class Transfer extends Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateDecimals (num) {
|
||||||
|
const { balance } = this.props;
|
||||||
|
const { tag } = this.state;
|
||||||
|
|
||||||
|
if (tag === 'ETH') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = balance.tokens.find((balance) => balance.token.tag === tag).token;
|
||||||
|
const s = new BigNumber(num).mul(token.format || 1).toString();
|
||||||
|
|
||||||
|
if (s.indexOf('.') !== -1) {
|
||||||
|
return ERRORS.invalidDecimals;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
_onUpdateGas (gas) {
|
_onUpdateGas (gas) {
|
||||||
const gasError = this.validatePositiveNumber(gas);
|
const gasError = this.validatePositiveNumber(gas);
|
||||||
|
|
||||||
@ -341,7 +359,11 @@ export default class Transfer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_onUpdateValue (value) {
|
_onUpdateValue (value) {
|
||||||
const valueError = this.validatePositiveNumber(value);
|
let valueError = this.validatePositiveNumber(value);
|
||||||
|
|
||||||
|
if (!valueError) {
|
||||||
|
valueError = this.validateDecimals(value);
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
value,
|
value,
|
||||||
@ -407,7 +429,7 @@ export default class Transfer extends Component {
|
|||||||
to: token.address
|
to: token.address
|
||||||
}, [
|
}, [
|
||||||
recipient,
|
recipient,
|
||||||
new BigNumber(value).mul(token.format).toString()
|
new BigNumber(value).mul(token.format).toFixed(0)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,6 +522,7 @@ export default class Transfer extends Component {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('etimateGas', error);
|
console.error('etimateGas', error);
|
||||||
|
this.recalculate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +588,7 @@ export default class Transfer extends Component {
|
|||||||
}, this.recalculate);
|
}, this.recalculate);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('getDefaults', error);
|
console.warn('getDefaults', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,8 @@ export default class Balances {
|
|||||||
})
|
})
|
||||||
.then(([_tokens, images]) => {
|
.then(([_tokens, images]) => {
|
||||||
const tokens = {};
|
const tokens = {};
|
||||||
this._tokens = _tokens.map((_token, index) => {
|
this._tokens = _tokens
|
||||||
|
.map((_token, index) => {
|
||||||
const [address, tag, format, name] = _token;
|
const [address, tag, format, name] = _token;
|
||||||
|
|
||||||
const token = {
|
const token = {
|
||||||
@ -114,6 +115,15 @@ export default class Balances {
|
|||||||
this._store.dispatch(setAddressImage(address, images[index]));
|
this._store.dispatch(setAddressImage(address, images[index]));
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
|
})
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (a.tag < b.tag) {
|
||||||
|
return -1;
|
||||||
|
} else if (a.tag > b.tag) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
this._store.dispatch(getTokens(tokens));
|
this._store.dispatch(getTokens(tokens));
|
||||||
|
Loading…
Reference in New Issue
Block a user