diff --git a/common/actions/rates.js b/common/actions/rates.js index fd62b6d0..2255c832 100644 --- a/common/actions/rates.js +++ b/common/actions/rates.js @@ -1,17 +1,29 @@ // @flow +export type FiatRequestedRatesAction = { + type: 'RATES_FIAT_REQUESTED' +}; + +export function fiatRequestedRates() { + return { + type: 'RATES_FIAT_REQUESTED' + }; +} + /*** Set rates ***/ -export type SetRatesAction = { - type: 'RATES_SET', +export type FiatSucceededRatesAction = { + type: 'RATES_FIAT_SUCCEEDED', payload: { [string]: number } }; -export function setRates(payload: { [string]: number }): SetRatesAction { +export function fiatSucceededRates(payload: { + [string]: number +}): FiatSucceededRatesAction { return { - type: 'RATES_SET', + type: 'RATES_FIAT_SUCCEEDED', payload }; } /*** Union Type ***/ -export type RatesAction = SetRatesAction; +export type RatesAction = FiatSucceededRatesAction | FiatRequestedRatesAction; diff --git a/common/components/BalanceSidebar/AccountInfo.jsx b/common/components/BalanceSidebar/AccountInfo.jsx index e23a6d9a..efbd28f0 100644 --- a/common/components/BalanceSidebar/AccountInfo.jsx +++ b/common/components/BalanceSidebar/AccountInfo.jsx @@ -7,11 +7,13 @@ import { formatNumber } from 'utils/formatters'; import type { IWallet } from 'libs/wallet'; import type { NetworkConfig } from 'config/data'; import { Ether } from 'libs/units'; +import type { FiatRequestedRatesAction } from 'actions/rates'; type Props = { balance: Ether, wallet: IWallet, - network: NetworkConfig + network: NetworkConfig, + fiatRequestedRates: () => FiatRequestedRatesAction }; export default class AccountInfo extends React.Component { @@ -23,6 +25,7 @@ export default class AccountInfo extends React.Component { }; componentDidMount() { + this.props.fiatRequestedRates(); this.props.wallet.getAddress().then(addr => { this.setState({ address: addr }); }); @@ -67,11 +70,10 @@ export default class AccountInfo extends React.Component { {this.state.showLongBalance - ? balance.toString() - : formatNumber(balance.amount)} + ? balance ? balance.toString() : '???' + : balance ? formatNumber(balance.amount) : '???'} {` ${network.name}`} diff --git a/common/components/BalanceSidebar/EquivalentValues.jsx b/common/components/BalanceSidebar/EquivalentValues.jsx index afec1345..3c9ffaec 100644 --- a/common/components/BalanceSidebar/EquivalentValues.jsx +++ b/common/components/BalanceSidebar/EquivalentValues.jsx @@ -2,16 +2,14 @@ import './EquivalentValues.scss'; import React from 'react'; import translate from 'translations'; -import { Link } from 'react-router'; import { formatNumber } from 'utils/formatters'; -import type Big from 'bignumber.js'; import { Ether } from 'libs/units'; const ratesKeys = ['BTC', 'REP', 'EUR', 'USD', 'GBP', 'CHF']; type Props = { - balance: Ether, - rates: { [string]: number } + balance: ?Ether, + rates: ?{ [string]: number } }; export default class EquivalentValues extends React.Component { @@ -27,19 +25,23 @@ export default class EquivalentValues extends React.Component { ); diff --git a/common/components/BalanceSidebar/Promos.jsx b/common/components/BalanceSidebar/Promos.jsx index 4e1b467a..d2334fff 100644 --- a/common/components/BalanceSidebar/Promos.jsx +++ b/common/components/BalanceSidebar/Promos.jsx @@ -66,6 +66,7 @@ export default class Promos extends React.Component { ? diff --git a/common/components/BalanceSidebar/index.jsx b/common/components/BalanceSidebar/index.jsx index 1c3e9848..5801619a 100644 --- a/common/components/BalanceSidebar/index.jsx +++ b/common/components/BalanceSidebar/index.jsx @@ -9,6 +9,8 @@ import type { TokenBalance } from 'selectors/wallet'; import { getNetworkConfig } from 'selectors/config'; import * as customTokenActions from 'actions/customTokens'; import { showNotification } from 'actions/notifications'; +import { fiatRequestedRates } from 'actions/rates'; +import type { FiatRequestedRatesAction } from 'actions/rates'; import AccountInfo from './AccountInfo'; import Promos from './Promos'; @@ -24,14 +26,22 @@ type Props = { rates: { [string]: number }, showNotification: Function, addCustomToken: typeof customTokenActions.addCustomToken, - removeCustomToken: typeof customTokenActions.removeCustomToken + removeCustomToken: typeof customTokenActions.removeCustomToken, + fiatRequestedRates: () => FiatRequestedRatesAction }; export class BalanceSidebar extends React.Component { props: Props; render() { - const { wallet, balance, network, tokenBalances, rates } = this.props; + const { + wallet, + balance, + network, + tokenBalances, + rates, + fiatRequestedRates + } = this.props; if (!wallet) { return null; } @@ -40,7 +50,12 @@ export class BalanceSidebar extends React.Component { { name: 'Account Info', content: ( - + ) }, { @@ -91,5 +106,6 @@ function mapStateToProps(state: State) { export default connect(mapStateToProps, { ...customTokenActions, - showNotification + showNotification, + fiatRequestedRates })(BalanceSidebar); diff --git a/common/components/WalletDecrypt/DeterministicWalletsModal.jsx b/common/components/WalletDecrypt/DeterministicWalletsModal.jsx index 06c94429..3fd7b6eb 100644 --- a/common/components/WalletDecrypt/DeterministicWalletsModal.jsx +++ b/common/components/WalletDecrypt/DeterministicWalletsModal.jsx @@ -7,11 +7,9 @@ import { getDeterministicWallets, setDesiredToken } from 'actions/deterministicWallets'; -import { toUnit } from 'libs/units'; import { getNetworkConfig } from 'selectors/config'; import { getTokens } from 'selectors/wallet'; import { isValidPath } from 'libs/validators'; - import type { DeterministicWalletData, GetDeterministicWalletsArgs, diff --git a/common/reducers/rates.js b/common/reducers/rates.js index b555afbf..d0203d18 100644 --- a/common/reducers/rates.js +++ b/common/reducers/rates.js @@ -1,5 +1,5 @@ // @flow -import type { SetRatesAction, RatesAction } from 'actions/rates'; +import type { FiatSucceededRatesAction, RatesAction } from 'actions/rates'; // SYMBOL -> PRICE TO BUY 1 ETH export type State = { @@ -8,7 +8,10 @@ export type State = { export const INITIAL_STATE: State = {}; -function setRates(state: State, action: SetRatesAction): State { +function fiatSucceededRates( + state: State, + action: FiatSucceededRatesAction +): State { return action.payload; } @@ -17,8 +20,8 @@ export function rates( action: RatesAction ): State { switch (action.type) { - case 'RATES_SET': - return setRates(state, action); + case 'RATES_FIAT_SUCCEEDED': + return fiatSucceededRates(state, action); default: return state; } diff --git a/common/reducers/wallet.js b/common/reducers/wallet.js index 4a9c8221..2ba14684 100644 --- a/common/reducers/wallet.js +++ b/common/reducers/wallet.js @@ -14,7 +14,7 @@ import { Ether } from 'libs/units'; export type State = { inst: ?IWallet, // in ETH - balance: Ether, + balance: ?Ether, tokens: { [string]: Big }, @@ -23,14 +23,14 @@ export type State = { export const INITIAL_STATE: State = { inst: null, - balance: new Ether(0), + balance: null, tokens: {}, isBroadcasting: false, transactions: [] }; function setWallet(state: State, action: SetWalletAction): State { - return { ...state, inst: action.payload, balance: new Ether(0), tokens: {} }; + return { ...state, inst: action.payload, balance: null, tokens: {} }; } function setBalance(state: State, action: SetBalanceAction): State { diff --git a/common/sagas/rates.js b/common/sagas/rates.js index 250bf1d0..4d483b38 100644 --- a/common/sagas/rates.js +++ b/common/sagas/rates.js @@ -1,28 +1,28 @@ // @flow -import { put, call } from 'redux-saga/effects'; - +import { put, call, takeLatest } from 'redux-saga/effects'; import { handleJSONResponse } from 'api/utils'; - -import { setRates } from 'actions/rates'; -import { showNotification } from 'actions/notifications'; - +import { fiatSucceededRates } from 'actions/rates'; import type { Yield, Return, Next } from 'sagas/types'; const symbols = ['USD', 'EUR', 'GBP', 'BTC', 'CHF', 'REP']; const symbolsURL = symbols.join(','); +// TODO - internationalize +const ERROR_MESSAGE = 'Could not fetch rate data.'; const fetchRates = () => fetch( `https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=${symbolsURL}` - ).then(response => - handleJSONResponse(response, 'Could not fetch rate data.') - ); + ).then(response => handleJSONResponse(response, ERROR_MESSAGE)); -export default function* ratesSaga(): Generator { +export function* handleRatesRequest(): Generator { try { const rates = yield call(fetchRates); - yield put(setRates(rates)); + yield put(fiatSucceededRates(rates)); } catch (error) { - yield put(showNotification('danger', error)); + yield put({ type: 'RATES_FIAT_FAILED', payload: error }); } } + +export default function* ratesSaga(): Generator { + yield takeLatest('RATES_FIAT_REQUESTED', handleRatesRequest); +} diff --git a/common/sagas/swap/rates.js b/common/sagas/swap/rates.js index 7b79f430..414944f9 100644 --- a/common/sagas/swap/rates.js +++ b/common/sagas/swap/rates.js @@ -15,7 +15,7 @@ export function* loadBityRates(_action?: any): Generator { const data = yield call(getAllRates); yield put(loadBityRatesSucceededSwap(data)); } catch (error) { - yield put(yield showNotification('danger', error)); + yield put(yield showNotification('danger', error.message)); } yield call(delay, 5000); } diff --git a/spec/reducers/wallet.spec.js b/spec/reducers/wallet.spec.js index cec0d2e1..db00bdf5 100644 --- a/spec/reducers/wallet.spec.js +++ b/spec/reducers/wallet.spec.js @@ -13,7 +13,7 @@ describe('wallet reducer', () => { expect(wallet(undefined, walletActions.setWallet(walletInstance))).toEqual({ ...INITIAL_STATE, inst: walletInstance, - balance: new Ether(0), + balance: null, tokens: {} }); });