@ -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,6 +13,43 @@ import Select from 'components/base/LegacySelect'
import type { Unit } from '@ledgerhq/live-common/lib/types'
// 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 = decimals ; i < unit . magnitude ; ++ i ) {
value += '0'
}
if ( ! value ) value = '0'
return { display , value }
}
function format ( unit : Unit , value : number , { isFocused , showAllDigits , subMagnitude } ) {
// FIXME do we need locale for the input too ?
return formatCurrencyUnit ( unit , value , {
@ -81,9 +117,10 @@ class InputCurrency extends PureComponent<Props, State> {
componentWillReceiveProps ( nextProps : Props ) {
const { value , showAllDigits , unit } = this . props
const needsToBeReformatted =
value !== nextProps . value ||
showAllDigits !== nextProps . showAllDigits ||
unit !== nextProps . unit
! this . state . isFocused &&
( value !== nextProps . value ||
showAllDigits !== nextProps . showAllDigits ||
unit !== nextProps . unit )
if ( needsToBeReformatted ) {
const { isFocused } = this . state
this . setState ( {
@ -100,31 +137,13 @@ class InputCurrency extends PureComponent<Props, State> {
}
handleChange = ( v : string ) => {
// FIXME this is to refactor. this is hacky and don't cover everything..
v = v . toString ( ) . replace ( /,/g , '.' )
// 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
const asNumber = parseFloat ( v )
if ( isNaN ( asNumber ) || ! isFinite ( asNumber ) || asNumber < 0 ) {
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 = ( ) => {
@ -148,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 } < / C u r r e n c y >