diff --git a/src/actions/settings.js b/src/actions/settings.js index 1565662d..15170c6d 100644 --- a/src/actions/settings.js +++ b/src/actions/settings.js @@ -1,10 +1,10 @@ // @flow import type { Dispatch } from 'redux' -import type { Settings } from 'types/common' +import type { SettingsState as Settings } from 'reducers/settings' import type { Currency } from '@ledgerhq/live-common/lib/types' -export type SaveSettings = Settings => { type: string, payload: Settings } +export type SaveSettings = Settings => { type: string, payload: $Shape } export const saveSettings: SaveSettings = payload => ({ type: 'DB:SAVE_SETTINGS', payload, diff --git a/src/components/IsUnlocked.js b/src/components/IsUnlocked.js index 9a9c7226..5641c49a 100644 --- a/src/components/IsUnlocked.js +++ b/src/components/IsUnlocked.js @@ -7,7 +7,8 @@ import { compose } from 'redux' import styled from 'styled-components' import { translate } from 'react-i18next' -import type { Settings, T } from 'types/common' +import type { SettingsState as Settings } from 'reducers/settings' +import type { T } from 'types/common' import IconLockScreen from 'icons/LockScreen' import { ErrorMessageInput } from 'components/base/Input' diff --git a/src/components/SettingsPage/index.js b/src/components/SettingsPage/index.js index 81f1ec87..05e580e8 100644 --- a/src/components/SettingsPage/index.js +++ b/src/components/SettingsPage/index.js @@ -6,8 +6,9 @@ import { connect } from 'react-redux' import { translate } from 'react-i18next' import { Switch, Route } from 'react-router' +import type { SettingsState as Settings } from 'reducers/settings' import type { RouterHistory, Match, Location } from 'react-router' -import type { Settings, T } from 'types/common' +import type { T } from 'types/common' import type { SaveSettings } from 'actions/settings' import { saveSettings } from 'actions/settings' diff --git a/src/components/SettingsPage/sections/Currencies.js b/src/components/SettingsPage/sections/Currencies.js index c26124b5..2762e12b 100644 --- a/src/components/SettingsPage/sections/Currencies.js +++ b/src/components/SettingsPage/sections/Currencies.js @@ -11,10 +11,12 @@ import { connect } from 'react-redux' import { createStructuredSelector } from 'reselect' import type { CryptoCurrency, Currency } from '@ledgerhq/live-common/lib/types' -import type { Settings, CurrencySettings, T } from 'types/common' +import type { T } from 'types/common' -import { counterValueCurrencySelector } from 'reducers/settings' +import { counterValueCurrencySelector, currencySettingsLocaleSelector } from 'reducers/settings' +import type { SettingsState } from 'reducers/settings' import { currenciesSelector } from 'reducers/accounts' +import { currencySettingsDefaults } from 'helpers/SettingsDefaults' import SelectCurrency from 'components/SelectCurrency' import StepperNumber from 'components/base/StepperNumber' @@ -29,30 +31,11 @@ import { SettingsSectionRow as Row, } from '../SettingsSection' -// . -// /!\ Please note that this will likely not be like that in the future. -// I guess that all currencies should have those settings inside them -// instead of using same default for all. -// -const CURRENCY_DEFAULTS_SETTINGS: CurrencySettings = { - confirmationsToSpend: 10, - minConfirmationsToSpend: 10, - maxConfirmationsToSpend: 50, - - confirmationsNb: 10, - minConfirmationsNb: 10, - maxConfirmationsNb: 50, - - transactionFees: 10, - - exchange: '', -} - type Props = { counterValueCurrency: Currency, currencies: CryptoCurrency[], - settings: Settings, - saveSettings: Function, + settings: SettingsState, + saveSettings: ($Shape) => void, t: T, } @@ -70,12 +53,6 @@ class TabCurrencies extends PureComponent { currency: this.props.currencies[0], } - getCurrencySettings() { - const { settings } = this.props - const { currency } = this.state - return settings.currenciesSettings[currency.id] - } - handleChangeCurrency = (currency: CryptoCurrency) => this.setState({ currency }) handleChangeConfirmationsToSpend = (nb: number) => @@ -90,13 +67,12 @@ class TabCurrencies extends PureComponent { // FIXME this really should be a dedicated action const { settings, saveSettings } = this.props const { currency } = this.state - const currencySettings = this.getCurrencySettings() + const currencySettings = settings.currenciesSettings[currency.id] let newCurrenciesSettings = [] if (!currencySettings) { newCurrenciesSettings = { ...settings.currenciesSettings, [currency.id]: { - ...CURRENCY_DEFAULTS_SETTINGS, [key]: val, }, } @@ -115,9 +91,9 @@ class TabCurrencies extends PureComponent { render() { const { currency } = this.state if (!currency) return null // this case means there is no accounts - const { t, currencies, counterValueCurrency } = this.props - const { confirmationsToSpend, confirmationsNb, exchange } = - this.getCurrencySettings() || CURRENCY_DEFAULTS_SETTINGS + const { t, currencies, counterValueCurrency, settings } = this.props + const { confirmationsNb, exchange } = currencySettingsLocaleSelector(settings, currency) + const defaults = currencySettingsDefaults(currency) return (
{ style={{ minWidth: 200 }} /> - - - - - - - - + {defaults.confirmationsNb ? ( + + + + ) : null}
) diff --git a/src/components/SettingsPage/sections/Display.js b/src/components/SettingsPage/sections/Display.js index 15122051..343dc942 100644 --- a/src/components/SettingsPage/sections/Display.js +++ b/src/components/SettingsPage/sections/Display.js @@ -4,7 +4,8 @@ import React, { PureComponent } from 'react' import moment from 'moment' import { listFiatCurrencies } from '@ledgerhq/live-common/lib/helpers/currencies' -import type { Settings, T } from 'types/common' +import type { SettingsState as Settings } from 'reducers/settings' +import type { T } from 'types/common' import Select from 'components/base/Select' import RadioGroup from 'components/base/RadioGroup' diff --git a/src/components/SettingsPage/sections/Profile.js b/src/components/SettingsPage/sections/Profile.js index f3d96a45..b71ee462 100644 --- a/src/components/SettingsPage/sections/Profile.js +++ b/src/components/SettingsPage/sections/Profile.js @@ -5,7 +5,8 @@ import { connect } from 'react-redux' import { remote } from 'electron' import bcrypt from 'bcryptjs' -import type { Settings, T } from 'types/common' +import type { SettingsState } from 'reducers/settings' +import type { T } from 'types/common' import { unlock } from 'reducers/application' import db, { setEncryptionKey } from 'helpers/db' @@ -31,7 +32,7 @@ const mapDispatchToProps = { type Props = { t: T, - settings: Settings, + settings: SettingsState, unlock: Function, saveSettings: Function, } diff --git a/src/helpers/SettingsDefaults.js b/src/helpers/SettingsDefaults.js new file mode 100644 index 00000000..8c8456d8 --- /dev/null +++ b/src/helpers/SettingsDefaults.js @@ -0,0 +1,52 @@ +// @flow + +import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' + +type ConfirmationDefaults = { + confirmationsNb: ?{ + min: number, + def: number, + max: number, + }, +} + +// This is approximated to be a 30mn confirmation in number of blocks on blockchains +// to disable the confirmations feature simply set 0. +const confirmationsNbPerCoin = { + bitcoin: 2, + ethereum: 120, + ripple: 0, + bitcoin_cash: 2, + litecoin: 6, + dash: 12, + ethereum_classic: 120, + qtum: 15, + zcash: 12, + bitcoin_gold: 2, + stratis: 12, // FIXME can't grab the block time info anywhere... + dogecoin: 30, + hshare: 12, // FIXME can't grab the block time info anywhere... + komodo: 30, + pivx: 12, // FIXME can't grab the block time info anywhere... + zencash: 12, + vertcoin: 12, + peercoin: 4, + viacoin: 75, + stealthcoin: 12, // FIXME can't grab the block time info anywhere... + digibyte: 30, + bitcoin_testnet: 2, + ethereum_testnet: 120, +} + +export const currencySettingsDefaults = (currency: CryptoCurrency): ConfirmationDefaults => { + const confirmationsNbDef = confirmationsNbPerCoin[currency.id] + return { + confirmationsNb: confirmationsNbDef + ? { + min: 1, + def: confirmationsNbDef, + max: 100, + } + : null, + } +} diff --git a/src/helpers/countervalues.js b/src/helpers/countervalues.js index caee209b..0b0af42e 100644 --- a/src/helpers/countervalues.js +++ b/src/helpers/countervalues.js @@ -14,7 +14,7 @@ const pairsSelector = createSelector( currencies.map(currency => ({ from: currency, to: counterValueCurrency, - exchange: currencySettingsSelector(state, currency).exchange, + exchange: currencySettingsSelector(state, { currency }).exchange, })), ) diff --git a/src/reducers/settings.js b/src/reducers/settings.js index 856f6210..bcf5eb6e 100644 --- a/src/reducers/settings.js +++ b/src/reducers/settings.js @@ -10,8 +10,9 @@ import languages from 'config/languages' import { createSelector } from 'reselect' import type { InputSelector as Selector } from 'reselect' import type { CryptoCurrency, Currency, Account } from '@ledgerhq/live-common/lib/types' +import { currencySettingsDefaults } from 'helpers/SettingsDefaults' -import type { Settings, CurrencySettings } from 'types/common' +import type { CurrencySettings } from 'types/common' import type { State } from 'reducers' export type SettingsState = { @@ -24,7 +25,7 @@ export type SettingsState = { isEnabled: boolean, value: string, }, - marketIndicator: string, + marketIndicator: 'eastern' | 'western', currenciesSettings: { [currencyId: string]: CurrencySettings, }, @@ -42,21 +43,15 @@ if (!languages.includes(language)) { region = 'US' } -const CURRENCY_DEFAULTS_SETTINGS: CurrencySettings = { - confirmationsToSpend: 10, - minConfirmationsToSpend: 10, // FIXME DROP - maxConfirmationsToSpend: 50, // FIXME DROP - - confirmationsNb: 10, - minConfirmationsNb: 10, // FIXME DROP - maxConfirmationsNb: 50, // FIXME DROP - - transactionFees: 10, - - exchange: '', +const defaultsForCurrency: CryptoCurrency => CurrencySettings = crypto => { + const defaults = currencySettingsDefaults(crypto) + return { + confirmationsNb: defaults.confirmationsNb ? defaults.confirmationsNb.def : 0, + exchange: '', + } } -const state: SettingsState = { +const INITIAL_STATE: SettingsState = { hasCompletedOnboarding: false, counterValue: 'USD', language, @@ -105,11 +100,17 @@ const handlers: Object = { } return copy }, - SAVE_SETTINGS: (state: SettingsState, { payload: settings }: { payload: Settings }) => ({ + SAVE_SETTINGS: ( + state: SettingsState, + { payload: settings }: { payload: $Shape }, + ) => ({ ...state, ...settings, }), - FETCH_SETTINGS: (state: SettingsState, { payload: settings }: { payload: Settings }) => ({ + FETCH_SETTINGS: ( + state: SettingsState, + { payload: settings }: { payload: $Shape }, + ) => ({ ...state, ...settings, loaded: true, @@ -152,18 +153,26 @@ export const getOrderAccounts = (state: State) => state.settings.orderAccounts export const areSettingsLoaded = (state: State) => state.settings.loaded -export const currencySettingsSelector = ( - state: State, - currency: CryptoCurrency, +export const currencySettingsLocaleSelector = ( + settings: SettingsState, + currency: Currency, ): CurrencySettings => { - const currencySettings = state.settings.currenciesSettings[currency.id] - return { ...CURRENCY_DEFAULTS_SETTINGS, ...currencySettings } + const currencySettings = settings.currenciesSettings[currency.id] + return { ...defaultsForCurrency(currency), ...currencySettings } } +type CSS = Selector<*, { currency: CryptoCurrency }, CurrencySettings> + +export const currencySettingsSelector: CSS = createSelector( + storeSelector, + (_, { currency }) => currency, + currencySettingsLocaleSelector, +) + export const currencySettingsForAccountSelector = ( state: State, { account }: { account: Account }, -) => currencySettingsSelector(state, account.currency) +) => currencySettingsSelector(state, { currency: account.currency }) type ESFAS = Selector<*, { account: Account }, string> export const exchangeSettingsForAccountSelector: ESFAS = createSelector( @@ -173,4 +182,4 @@ export const exchangeSettingsForAccountSelector: ESFAS = createSelector( export const marketIndicatorSelector = (state: State) => state.settings.marketIndicator -export default handleActions(handlers, state) +export default handleActions(handlers, INITIAL_STATE) diff --git a/src/types/common.js b/src/types/common.js index 9305887e..fcf58d52 100644 --- a/src/types/common.js +++ b/src/types/common.js @@ -11,16 +11,7 @@ export type Device = { // -------------------- Settings export type CurrencySettings = { - confirmationsToSpend: number, - minConfirmationsToSpend: number, - maxConfirmationsToSpend: number, - confirmationsNb: number, - minConfirmationsNb: number, - maxConfirmationsNb: number, - - transactionFees: number, - exchange: string, } @@ -28,21 +19,6 @@ export type CurrenciesSettings = { [id: string]: CurrencySettings, } -export type Settings = { - hasCompletedOnboarding: boolean, - language: string, - orderAccounts: string, - counterValue: string, - password: { - isEnabled: boolean, - value: string, - }, - marketIndicator: 'eastern' | 'western', - currenciesSettings: CurrenciesSettings, - region: string, - developerMode: boolean, -} - export type T = (?string, ?Object) => string // -------------------- Manager