diff --git a/package.json b/package.json index d1afc901..f8f47f78 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@ledgerhq/hw-transport": "^4.12.0", "@ledgerhq/hw-transport-node-hid": "^4.12.0", "@ledgerhq/ledger-core": "1.4.5", - "@ledgerhq/live-common": "2.26.0", + "@ledgerhq/live-common": "2.27.0", "axios": "^0.18.0", "babel-runtime": "^6.26.0", "bcryptjs": "^2.4.3", diff --git a/src/components/CalculateBalance.js b/src/components/CalculateBalance.js index fb544402..d1824e9b 100644 --- a/src/components/CalculateBalance.js +++ b/src/components/CalculateBalance.js @@ -7,7 +7,12 @@ import { connect } from 'react-redux' import type { Account } from '@ledgerhq/live-common/lib/types' import { getBalanceHistorySum } from '@ledgerhq/live-common/lib/helpers/account' import CounterValues from 'helpers/countervalues' -import { exchangeSettingsForAccountSelector, counterValueCurrencySelector } from 'reducers/settings' +import { + exchangeSettingsForAccountSelector, + counterValueCurrencySelector, + counterValueExchangeSelector, + intermediaryCurrency, +} from 'reducers/settings' import type { State } from 'reducers' type OwnProps = { @@ -31,6 +36,7 @@ type Props = OwnProps & { const mapStateToProps = (state: State, props: OwnProps) => { const counterValueCurrency = counterValueCurrencySelector(state) + const counterValueExchange = counterValueExchangeSelector(state) let isAvailable = true // create array of original values, used to reconciliate @@ -43,14 +49,20 @@ const mapStateToProps = (state: State, props: OwnProps) => { (account, value, date) => { // keep track of original value originalValues.push(value) + const fromExchange = exchangeSettingsForAccountSelector(state, { account }) - const cv = CounterValues.calculateSelector(state, { - value, - date, - to: counterValueCurrency, - from: account.currency, - exchange: exchangeSettingsForAccountSelector(state, { account }), - }) + const cv = + fromExchange && + counterValueExchange && + CounterValues.calculateWithIntermediarySelector(state, { + value, + date, + from: account.currency, + fromExchange, + intermediary: intermediaryCurrency, + toExchange: counterValueExchange, + to: counterValueCurrency, + }) if (!cv && cv !== 0) { isAvailable = false return 0 diff --git a/src/components/CounterValue/index.js b/src/components/CounterValue/index.js index 5a1e726a..615f017b 100644 --- a/src/components/CounterValue/index.js +++ b/src/components/CounterValue/index.js @@ -4,8 +4,13 @@ import React, { PureComponent } from 'react' import { connect } from 'react-redux' import type { Currency } from '@ledgerhq/live-common/lib/types' -import { counterValueCurrencySelector } from 'reducers/settings' -import { calculateCounterValueSelector } from 'reducers/counterValues' +import { + counterValueCurrencySelector, + currencySettingsSelector, + counterValueExchangeSelector, + intermediaryCurrency, +} from 'reducers/settings' +import CounterValues from 'helpers/countervalues' import FormattedVal from 'components/base/FormattedVal' @@ -14,7 +19,6 @@ import type { State } from 'reducers' type OwnProps = { // wich market to query currency: Currency, - exchange: string, // when? if not given: take latest date?: Date, @@ -31,17 +35,23 @@ type Props = OwnProps & { } const mapStateToProps = (state: State, props: OwnProps) => { - const { currency, value, date, exchange } = props - if (__DEV__) { - if (!exchange) console.warn('CounterValue: exchange is required') - if (!currency) console.warn('CounterValue: currency is required') - } + const { currency, value, date } = props const counterValueCurrency = counterValueCurrencySelector(state) - const counterValue = calculateCounterValueSelector(state)( - currency, - counterValueCurrency, - exchange, - )(value, date) + const fromExchange = currencySettingsSelector(state, { currency }).exchange + const toExchange = counterValueExchangeSelector(state) + const counterValue = + fromExchange && + toExchange && + CounterValues.calculateWithIntermediarySelector(state, { + from: currency, + fromExchange, + intermediary: intermediaryCurrency, + toExchange, + to: counterValueCurrency, + value, + date, + }) + return { counterValueCurrency, value: counterValue, diff --git a/src/components/OperationsList/Operation.js b/src/components/OperationsList/Operation.js index c46606fc..565a058b 100644 --- a/src/components/OperationsList/Operation.js +++ b/src/components/OperationsList/Operation.js @@ -211,7 +211,6 @@ class OperationComponent extends PureComponent { date={time.toDate()} currency={currency} value={amount} - exchange={currencySettings.exchange} /> diff --git a/src/components/RequestAmount/index.js b/src/components/RequestAmount/index.js index acdf5bb6..a039e93f 100644 --- a/src/components/RequestAmount/index.js +++ b/src/components/RequestAmount/index.js @@ -4,18 +4,23 @@ import React, { PureComponent } from 'react' import { compose } from 'redux' import { translate } from 'react-i18next' import styled from 'styled-components' -import { createStructuredSelector } from 'reselect' import { connect } from 'react-redux' import type { Currency, Account } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' -import { counterValueCurrencySelector, exchangeSettingsForAccountSelector } from 'reducers/settings' -import { calculateCounterValueSelector, reverseCounterValueSelector } from 'reducers/counterValues' +import { + counterValueCurrencySelector, + currencySettingsSelector, + counterValueExchangeSelector, + intermediaryCurrency, +} from 'reducers/settings' +import CounterValues from 'helpers/countervalues' import InputCurrency from 'components/base/InputCurrency' import Button from 'components/base/Button' import Box from 'components/base/Box' +import type { State } from 'reducers' const InputRight = styled(Box).attrs({ ff: 'Rubik', @@ -35,15 +40,7 @@ const InputCenter = styled(Box).attrs({ width: 30px; ` -const mapStateToProps = createStructuredSelector({ - exchange: exchangeSettingsForAccountSelector, - // $FlowFixMe - rightCurrency: counterValueCurrencySelector, - getCounterValue: calculateCounterValueSelector, - getReverseCounterValue: reverseCounterValueSelector, -}) - -type Props = { +type OwnProps = { // translation t: T, @@ -58,21 +55,59 @@ type Props = { // change handler onChange: number => void, - exchange: string, - // used to determine the left input unit account: Account, + // display max button + withMax: boolean, +} + +type Props = OwnProps & { // used to determine the right input unit // retrieved via selector (take the chosen countervalue unit) rightCurrency: Currency, // used to calculate the opposite field value (right & left) - getCounterValue: *, - getReverseCounterValue: *, + getCounterValue: number => ?number, + getReverseCounterValue: number => ?number, +} - // display max button - withMax: boolean, +const mapStateToProps = (state: State, props: OwnProps) => { + const { + account: { currency }, + } = props + const counterValueCurrency = counterValueCurrencySelector(state) + const fromExchange = currencySettingsSelector(state, { currency }).exchange + const toExchange = counterValueExchangeSelector(state) + const getCounterValue = value => + fromExchange && + toExchange && + CounterValues.calculateWithIntermediarySelector(state, { + from: currency, + fromExchange, + intermediary: intermediaryCurrency, + toExchange, + to: counterValueCurrency, + value, + }) + + const getReverseCounterValue = value => + fromExchange && + toExchange && + CounterValues.reverseWithIntermediarySelector(state, { + from: currency, + fromExchange, + intermediary: intermediaryCurrency, + toExchange, + to: counterValueCurrency, + value, + }) + + return { + rightCurrency: counterValueCurrency, + getCounterValue, + getReverseCounterValue, + } } export class RequestAmount extends PureComponent { @@ -90,18 +125,18 @@ export class RequestAmount extends PureComponent { } handleChangeAmount = (changedField: string) => (val: number) => { - const { rightCurrency, getReverseCounterValue, account, max, onChange, exchange } = this.props + const { getReverseCounterValue, max, onChange } = this.props if (changedField === 'left') { onChange(val > max ? max : val) } else if (changedField === 'right') { - const leftVal = getReverseCounterValue(account.currency, rightCurrency, exchange)(val) || 0 + const leftVal = getReverseCounterValue(val) || 0 onChange(leftVal > max ? max : leftVal) } } renderInputs(containerProps: Object) { - const { value, account, rightCurrency, getCounterValue, exchange, canBeSpent } = this.props - const right = getCounterValue(account.currency, rightCurrency, exchange)(value) || 0 + const { value, account, rightCurrency, getCounterValue, canBeSpent } = this.props + const right = getCounterValue(value) || 0 const rightUnit = rightCurrency.units[0] return ( diff --git a/src/components/SelectExchange.js b/src/components/SelectExchange.js index 602958d8..0ee12b54 100644 --- a/src/components/SelectExchange.js +++ b/src/components/SelectExchange.js @@ -12,7 +12,7 @@ class ExchangeSelect extends Component< { from: Currency, to: Currency, - exchangeId: string, + exchangeId: ?string, onChange: (?Exchange) => void, style?: *, }, diff --git a/src/components/SettingsPage/sections/Currencies.js b/src/components/SettingsPage/sections/Currencies.js index 6fc3f33b..b44a998b 100644 --- a/src/components/SettingsPage/sections/Currencies.js +++ b/src/components/SettingsPage/sections/Currencies.js @@ -10,10 +10,10 @@ import React, { PureComponent } from 'react' import { connect } from 'react-redux' import { createStructuredSelector } from 'reselect' -import type { CryptoCurrency, Currency } from '@ledgerhq/live-common/lib/types' +import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' import type { T } from 'types/common' -import { counterValueCurrencySelector, currencySettingsLocaleSelector } from 'reducers/settings' +import { intermediaryCurrency, currencySettingsLocaleSelector } from 'reducers/settings' import type { SettingsState } from 'reducers/settings' import { currenciesSelector } from 'reducers/accounts' import { currencySettingsDefaults } from 'helpers/SettingsDefaults' @@ -32,7 +32,6 @@ import { } from '../SettingsSection' type Props = { - counterValueCurrency: Currency, currencies: CryptoCurrency[], settings: SettingsState, saveSettings: ($Shape) => void, @@ -44,7 +43,6 @@ type State = { } const mapStateToProps = createStructuredSelector({ - counterValueCurrency: counterValueCurrencySelector, currencies: currenciesSelector, }) @@ -61,7 +59,7 @@ class TabCurrencies extends PureComponent { handleChangeConfirmationsNb = (nb: number) => this.updateCurrencySettings('confirmationsNb', nb) handleChangeExchange = exchange => - this.updateCurrencySettings('exchange', exchange ? exchange.id : '') + this.updateCurrencySettings('exchange', exchange ? exchange.id : null) updateCurrencySettings = (key: string, val: *) => { // FIXME this really should be a dedicated action @@ -91,7 +89,7 @@ class TabCurrencies extends PureComponent { render() { const { currency } = this.state if (!currency) return null // this case means there is no accounts - const { t, currencies, counterValueCurrency, settings } = this.props + const { t, currencies, settings } = this.props const { confirmationsNb, exchange } = currencySettingsLocaleSelector(settings, currency) const defaults = currencySettingsDefaults(currency) return ( @@ -112,11 +110,14 @@ class TabCurrencies extends PureComponent { } /> - + { }) } + handleChangeExchange = (exchange: *) => + this.props.saveSettings({ counterValueExchange: exchange ? exchange.id : null }) + render() { - const { t } = this.props + const { t, settings } = this.props const { cachedMarketIndicator, cachedLanguageKey, @@ -117,6 +127,9 @@ class TabProfile extends PureComponent { cachedRegion, } = this.state + const counterValueCurrency = counterValueCurrencyLocalSelector(settings) + const counterValueExchange = counterValueExchangeLocalSelector(settings) + const languages = languageKeys.map(key => ({ value: key, label: t(`language:${key}`) })) const currentLanguage = languages.find(l => l.value === cachedLanguageKey) const regionsFiltered = regions.filter(({ language }) => cachedLanguageKey === language) @@ -149,6 +162,19 @@ class TabProfile extends PureComponent { value={cvOption} /> + + +