|
|
@ -6,7 +6,6 @@ import styled from 'styled-components' |
|
|
|
import { formatCurrencyUnit } from '@ledgerhq/live-common/lib/helpers/currencies' |
|
|
|
|
|
|
|
import noop from 'lodash/noop' |
|
|
|
import isNaN from 'lodash/isNaN' |
|
|
|
|
|
|
|
import Box from 'components/base/Box' |
|
|
|
import Input from 'components/base/Input' |
|
|
@ -14,8 +13,41 @@ import Select from 'components/base/LegacySelect' |
|
|
|
|
|
|
|
import type { Unit } from '@ledgerhq/live-common/lib/types' |
|
|
|
|
|
|
|
function parseValue(value) { |
|
|
|
return value.toString().replace(/,/g, '.') |
|
|
|
// TODO move this back to live common
|
|
|
|
const numbers = '0123456789' |
|
|
|
const sanitizeValueString = ( |
|
|
|
unit: Unit, |
|
|
|
valueString: string, |
|
|
|
): { |
|
|
|
display: string, |
|
|
|
value: string, |
|
|
|
} => { |
|
|
|
let display = '' |
|
|
|
let value = '' |
|
|
|
let decimals = -1 |
|
|
|
for (let i = 0; i < valueString.length; i++) { |
|
|
|
const c = valueString[i] |
|
|
|
if (numbers.indexOf(c) !== -1) { |
|
|
|
if (decimals >= 0) { |
|
|
|
decimals++ |
|
|
|
if (decimals > unit.magnitude) break |
|
|
|
value += c |
|
|
|
display += c |
|
|
|
} else if (value !== '0') { |
|
|
|
value += c |
|
|
|
display += c |
|
|
|
} |
|
|
|
} else if (decimals === -1 && (c === ',' || c === '.')) { |
|
|
|
if (i === 0) display = '0' |
|
|
|
decimals = 0 |
|
|
|
display += '.' |
|
|
|
} |
|
|
|
} |
|
|
|
for (let i = Math.max(0, decimals); i < unit.magnitude; ++i) { |
|
|
|
value += '0' |
|
|
|
} |
|
|
|
if (!value) value = '0' |
|
|
|
return { display, value } |
|
|
|
} |
|
|
|
|
|
|
|
function format(unit: Unit, value: number, { isFocused, showAllDigits, subMagnitude }) { |
|
|
@ -85,9 +117,10 @@ class InputCurrency extends PureComponent<Props, State> { |
|
|
|
componentWillReceiveProps(nextProps: Props) { |
|
|
|
const { value, showAllDigits, unit } = this.props |
|
|
|
const needsToBeReformatted = |
|
|
|
value !== nextProps.value || |
|
|
|
!this.state.isFocused && |
|
|
|
(value !== nextProps.value || |
|
|
|
showAllDigits !== nextProps.showAllDigits || |
|
|
|
unit !== nextProps.unit |
|
|
|
unit !== nextProps.unit) |
|
|
|
if (needsToBeReformatted) { |
|
|
|
const { isFocused } = this.state |
|
|
|
this.setState({ |
|
|
@ -104,28 +137,13 @@ class InputCurrency extends PureComponent<Props, State> { |
|
|
|
} |
|
|
|
|
|
|
|
handleChange = (v: string) => { |
|
|
|
v = parseValue(v) |
|
|
|
|
|
|
|
// allow to type directly `.` in input to have `0.`
|
|
|
|
if (v.startsWith('.')) { |
|
|
|
v = `0${v}` |
|
|
|
} |
|
|
|
|
|
|
|
// forbid multiple 0 at start
|
|
|
|
if (v === '' || v.startsWith('00')) { |
|
|
|
const { onChange, unit } = this.props |
|
|
|
onChange(0, unit) |
|
|
|
this.setState({ displayValue: '' }) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// Check if value is valid Number
|
|
|
|
if (isNaN(Number(v))) { |
|
|
|
return |
|
|
|
const { onChange, unit, value } = this.props |
|
|
|
const r = sanitizeValueString(unit, v) |
|
|
|
const satoshiValue = parseInt(r.value, 10) |
|
|
|
if (value !== satoshiValue) { |
|
|
|
onChange(satoshiValue, unit) |
|
|
|
} |
|
|
|
|
|
|
|
this.emitOnChange(v) |
|
|
|
this.setState({ displayValue: v || '' }) |
|
|
|
this.setState({ displayValue: r.display }) |
|
|
|
} |
|
|
|
|
|
|
|
handleBlur = () => { |
|
|
@ -149,16 +167,6 @@ class InputCurrency extends PureComponent<Props, State> { |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
emitOnChange = (v: string) => { |
|
|
|
const { onChange, unit } = this.props |
|
|
|
const { displayValue } = this.state |
|
|
|
|
|
|
|
if (displayValue.toString() !== v.toString()) { |
|
|
|
const satoshiValue = Number(v) * 10 ** unit.magnitude |
|
|
|
onChange(satoshiValue, unit) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
renderItem = item => item.code |
|
|
|
|
|
|
|
renderSelected = item => <Currency>{item.code}</Currency> |
|
|
|