diff --git a/App.test.js b/App.test.js index 91f107e2..80759ab2 100644 --- a/App.test.js +++ b/App.test.js @@ -6,6 +6,7 @@ import Settings from './screen/settings/settings'; import Selftest from './screen/selftest'; import { BlueHeader } from './BlueComponents'; import MockStorage from './MockStorage'; +import { FiatUnit } from './models/fiatUnit'; global.crypto = require('crypto'); // shall be used by tests under nodejs CLI, but not in RN environment let assert = require('assert'); jest.mock('react-native-custom-qr-codes', () => 'Video'); @@ -302,10 +303,24 @@ describe('currency', () => { AsyncStorage.storageCache = {}; // cleanup from other tests let currency = require('./currency'); await currency.startUpdater(); - let cur = AsyncStorage.storageCache[AppStorage.CURRENCY]; + let cur = AsyncStorage.storageCache[AppStorage.EXCHANGE_RATES]; cur = JSON.parse(cur); assert.ok(Number.isInteger(cur[currency.STRUCT.LAST_UPDATED])); assert.ok(cur[currency.STRUCT.LAST_UPDATED] > 0); assert.ok(cur['BTC_USD'] > 0); + + // now, setting other currency as default + AsyncStorage.storageCache[AppStorage.PREFERRED_CURRENCY] = JSON.stringify(FiatUnit.JPY); + await currency.startUpdater(); + cur = JSON.parse(AsyncStorage.storageCache[AppStorage.EXCHANGE_RATES]); + assert.ok(cur['BTC_JPY'] > 0); + + // now setting with a proper setter + await currency.setPrefferedCurrency(FiatUnit.EUR); + await currency.startUpdater(); + let preferred = await currency.getPreferredCurrency(); + assert.equal(preferred.endPointKey, 'EUR'); + cur = JSON.parse(AsyncStorage.storageCache[AppStorage.EXCHANGE_RATES]); + assert.ok(cur['BTC_EUR'] > 0); }); }); diff --git a/class/app-storage.js b/class/app-storage.js index 9c17fd97..ad9d9c62 100644 --- a/class/app-storage.js +++ b/class/app-storage.js @@ -14,9 +14,9 @@ let encryption = require('../encryption'); export class AppStorage { static FLAG_ENCRYPTED = 'data_encrypted'; static LANG = 'lang'; - static CURRENCY = 'currency'; + static EXCHANGE_RATES = 'currency'; static LNDHUB = 'lndhub'; - static PREFERREDCURRENCY = 'preferredCurrency'; + static PREFERRED_CURRENCY = 'preferredCurrency'; constructor() { /** {Array.} */ diff --git a/currency.js b/currency.js index 373fa739..eb75e3b6 100644 --- a/currency.js +++ b/currency.js @@ -4,26 +4,41 @@ import { AppStorage } from './class'; import { FiatUnit } from './models/fiatUnit'; let BigNumber = require('bignumber.js'); let preferredFiatCurrency = FiatUnit.USD; -let lang = {}; -// let btcusd = 6500; // default +let exchangeRates = {}; const STRUCT = { LAST_UPDATED: 'LAST_UPDATED', }; +/** + * Saves to storage preferred currency, whole object + * from `./models/fiatUnit` + * + * @param item {Object} one of the values in `./models/fiatUnit` + * @returns {Promise} + */ +async function setPrefferedCurrency(item) { + await AsyncStorage.setItem(AppStorage.PREFERRED_CURRENCY, JSON.stringify(item)); +} + +async function getPreferredCurrency() { + return JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERRED_CURRENCY)); +} + async function updateExchangeRate() { - try { - preferredFiatCurrency = JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERREDCURRENCY)); - if (preferredFiatCurrency === null) { - throw Error(); - } - } catch (_error) { - preferredFiatCurrency = FiatUnit.USD; - } - if (+new Date() - lang[STRUCT.LAST_UPDATED] <= 30 * 60 * 1000) { + if (+new Date() - exchangeRates[STRUCT.LAST_UPDATED] <= 30 * 60 * 1000) { // not updating too often + console.log('not updating too often'); return; } + + try { + preferredFiatCurrency = JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERRED_CURRENCY)); + } catch (_) { + console.log('error :-( default will be used'); + } + preferredFiatCurrency = preferredFiatCurrency || FiatUnit.USD; + let json; try { const api = new Frisbee({ @@ -31,7 +46,7 @@ async function updateExchangeRate() { }); let response = await api.get('/v1/bpi/currentprice/' + preferredFiatCurrency.endPointKey + '.json'); json = JSON.parse(response.body); - if (typeof json === 'undefined' || typeof json.bpi[preferredFiatCurrency.endPointKey].rate_float === 'undefined') { + if (!json || !json.bpi || !json.bpi[preferredFiatCurrency.endPointKey] || !json.bpi[preferredFiatCurrency.endPointKey].rate_float) { throw new Error('Could not update currency rate: ' + response.err); } } catch (Err) { @@ -39,43 +54,31 @@ async function updateExchangeRate() { return; } - lang[STRUCT.LAST_UPDATED] = +new Date(); - lang['BTC_' + preferredFiatCurrency.endPointKey] = json.bpi[preferredFiatCurrency.endPointKey].rate_float * 1; - await AsyncStorage.setItem(AppStorage.CURRENCY, JSON.stringify(lang)); + exchangeRates[STRUCT.LAST_UPDATED] = +new Date(); + exchangeRates['BTC_' + preferredFiatCurrency.endPointKey] = json.bpi[preferredFiatCurrency.endPointKey].rate_float * 1; + await AsyncStorage.setItem(AppStorage.EXCHANGE_RATES, JSON.stringify(exchangeRates)); + await AsyncStorage.setItem(AppStorage.PREFERRED_CURRENCY, JSON.stringify(preferredFiatCurrency)); } -async function startUpdater(force = false) { - if (force) { - await AsyncStorage.removeItem(AppStorage.CURRENCY); - } - lang = await AsyncStorage.getItem(AppStorage.CURRENCY); - try { - preferredFiatCurrency = JSON.parse(await AsyncStorage.getItem(AppStorage.PREFERREDCURRENCY)); - if (preferredFiatCurrency === null) { - throw Error(); - } - } catch (_error) { - preferredFiatCurrency = FiatUnit.USD; +let interval = false; +async function startUpdater() { + if (interval) { + console.log('clear interval'); + clearInterval(interval); + exchangeRates[STRUCT.LAST_UPDATED] = 0; } - try { - lang = JSON.parse(lang); - } catch (Err) { - lang = {}; - } - lang = lang || {}; - lang[STRUCT.LAST_UPDATED] = lang[STRUCT.LAST_UPDATED] || 0; - lang['BTC_' + preferredFiatCurrency.endPointKey] = lang['BTC_' + preferredFiatCurrency.endPointKey] || 0; - setInterval(() => updateExchangeRate(), 2 * 60 * 100); + + interval = setInterval(() => updateExchangeRate(), 2 * 60 * 100); return updateExchangeRate(); } function satoshiToLocalCurrency(satoshi) { - if (!lang['BTC_' + preferredFiatCurrency.endPointKey]) return satoshi; + if (!exchangeRates['BTC_' + preferredFiatCurrency.endPointKey]) return satoshi; let b = new BigNumber(satoshi); b = b .dividedBy(100000000) - .multipliedBy(lang['BTC_' + preferredFiatCurrency.endPointKey]) + .multipliedBy(exchangeRates['BTC_' + preferredFiatCurrency.endPointKey]) .toString(10); b = parseFloat(b).toFixed(2); @@ -106,3 +109,5 @@ module.exports.STRUCT = STRUCT; module.exports.satoshiToLocalCurrency = satoshiToLocalCurrency; module.exports.satoshiToBTC = satoshiToBTC; module.exports.BTCToLocalCurrency = BTCToLocalCurrency; +module.exports.setPrefferedCurrency = setPrefferedCurrency; +module.exports.getPreferredCurrency = getPreferredCurrency; diff --git a/screen/settings/currency.js b/screen/settings/currency.js index d0cf0ad3..7f2f7158 100644 --- a/screen/settings/currency.js +++ b/screen/settings/currency.js @@ -1,11 +1,9 @@ import React, { Component } from 'react'; -import { FlatList, TouchableOpacity, AsyncStorage, ActivityIndicator, View } from 'react-native'; +import { FlatList, TouchableOpacity, ActivityIndicator, View } from 'react-native'; import { SafeBlueArea, BlueNavigationStyle, BlueListItem } from '../../BlueComponents'; import PropTypes from 'prop-types'; import { Icon } from 'react-native-elements'; -import { AppStorage } from '../../class'; import { FiatUnit } from '../../models/fiatUnit'; -/** @type {AppStorage} */ let loc = require('../../loc'); let currency = require('../../currency'); @@ -22,7 +20,7 @@ export default class Currency extends Component { async componentDidMount() { try { - const preferredCurrency = await AsyncStorage.getItem(AppStorage.PREFERREDCURRENCY); + const preferredCurrency = await currency.getPreferredCurrency(); if (preferredCurrency === null) { throw Error(); } @@ -37,8 +35,8 @@ export default class Currency extends Component { { this.setState({ isSavingNewPreferredCurrency: true, selectedCurrency: item }, async () => { - await AsyncStorage.setItem(AppStorage.PREFERREDCURRENCY, JSON.stringify(item)); - await currency.startUpdater(true); + await currency.setPrefferedCurrency(item); + await currency.startUpdater(); this.setState({ isSavingNewPreferredCurrency: false }); }); }}