Skip to content

Commit ee8d8be

Browse files
authored
feat(settings): default to user's local currency (#2504)
1 parent 79cf6e9 commit ee8d8be

File tree

11 files changed

+101
-34
lines changed

11 files changed

+101
-34
lines changed

__mocks__/react-native-localize.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "react-native-localize/mock/jest";

__tests__/fiat.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('Pulls latest fiat exchange rates and checks the wallet store for valid
7171
});
7272

7373
it('Blocktank FX rates with default selected currency', async () => {
74-
const res = await updateExchangeRates({});
74+
const res = await updateExchangeRates();
7575

7676
expect(res.isOk()).toEqual(true);
7777
if (res.isErr()) {
@@ -155,7 +155,7 @@ describe('Pulls latest fiat exchange rates and checks the wallet store for valid
155155
describe('convertToSats', () => {
156156
describe('can work with exchange rates', () => {
157157
beforeAll(async () => {
158-
const res = await updateExchangeRates({});
158+
const res = await updateExchangeRates();
159159
if (res.isErr()) {
160160
throw res.error;
161161
}

e2e/settings.e2e.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -535,14 +535,14 @@ d('Settings', () => {
535535
by.id('ConnectedUrl'),
536536
).getAttributes();
537537

538-
const alteredRelay = origRelay + '/';
538+
const alteredRelay = `${origRelay}/`;
539539
await element(by.id('UrlInput')).replaceText(alteredRelay);
540540
await element(by.id('WebRelayStatus')).tap(); // close keyboard
541541
await element(by.id('ConnectToUrl')).tap();
542542
await sleep(1000);
543543

544544
// url should be updated
545-
let { label: newRelay } = await element(
545+
const { label: newRelay } = await element(
546546
by.id('ConnectedUrl'),
547547
).getAttributes();
548548

@@ -570,14 +570,14 @@ d('Settings', () => {
570570
).getAttributes();
571571

572572
// add slash at the end
573-
const newUrl = origValue + '/';
573+
const newUrl = `${origValue}/`;
574574
await element(by.id('RGSUrl')).replaceText(newUrl);
575575
await element(by.id('RGSUrl')).tapReturnKey();
576576
await element(by.id('ConnectToHost')).tap();
577577
await sleep(1000);
578578

579579
// url should be updated
580-
let { label: newValue } = await element(
580+
const { label: newValue } = await element(
581581
by.id('ConnectedUrl'),
582582
).getAttributes();
583583

@@ -587,7 +587,7 @@ d('Settings', () => {
587587
await element(by.id('ResetToDefault')).tap();
588588
await element(by.id('ConnectToHost')).tap();
589589

590-
let { label: resetValue } = await element(
590+
const { label: resetValue } = await element(
591591
by.id('ConnectedUrl'),
592592
).getAttributes();
593593

ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,7 +1782,7 @@ PODS:
17821782
- ReactCommon/turbomodule/bridging
17831783
- ReactCommon/turbomodule/core
17841784
- Yoga
1785-
- RNLocalize (3.0.2):
1785+
- RNLocalize (3.4.1):
17861786
- React-Core
17871787
- RNNotifee (9.1.8):
17881788
- React-Core
@@ -2391,7 +2391,7 @@ SPEC CHECKSUMS:
23912391
RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8
23922392
RNGestureHandler: 9f3109e11ed88fe5bed280bf7762b25e4c52f396
23932393
RNKeychain: 824e7372c7e921d76c4ea4169bdc6c7a32025784
2394-
RNLocalize: 01b15a24a8f1856eeaeeb77f4179ccd88c117a73
2394+
RNLocalize: 15463c4d79c7da45230064b4adcf5e9bb984667e
23952395
RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168
23962396
RNPermissions: a03f8bd0e6c9d87597e39be694f90d208dd6f835
23972397
RNQrGenerator: afacf12b55dfba0e3aaca963eec23691e8426431

jest.setup.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import mockRNDeviceInfo from 'react-native-device-info/jest/react-native-device-info-mock';
22
import mockRNCNetInfo from '@react-native-community/netinfo/jest/netinfo-mock';
3-
import mockRNLocalize from 'react-native-localize/mock';
43
import * as mockLDK from '@synonymdev/react-native-ldk/dist/mock';
54

65
jest.mock('react-native-reanimated', () =>
@@ -12,7 +11,6 @@ jest.mock('react-native-permissions', () =>
1211
require('react-native-permissions/mock'),
1312
);
1413
jest.mock('@react-native-community/netinfo', () => mockRNCNetInfo);
15-
jest.mock('react-native-localize', () => mockRNLocalize);
1614
jest.mock('@synonymdev/react-native-ldk', () => mockLDK);
1715

1816
global.net = require('net'); // needed by Electrum client. For RN it is proviced in shim.js

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"react-native-image-picker": "8.1.0",
8787
"react-native-keyboard-accessory": "0.1.16",
8888
"react-native-keychain": "9.2.3",
89-
"react-native-localize": "3.0.2",
89+
"react-native-localize": "3.4.1",
9090
"react-native-mmkv": "2.12.2",
9191
"react-native-modal": "13.0.1",
9292
"react-native-permissions": "5.2.5",

src/screens/Settings/Currencies/index.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const CurrenciesSettings = ({
1919
const selectedCurrency = useAppSelector(selectedCurrencySelector);
2020

2121
const currencyListData: IListData[] = useMemo(() => {
22+
const currencies = Object.keys(exchangeRates).sort();
23+
2224
const onSetCurrency = (currency: string): void => {
2325
dispatch(updateSettings({ selectedCurrency: currency }));
2426
};
@@ -40,17 +42,15 @@ const CurrenciesSettings = ({
4042
},
4143
{
4244
title: t('general.currency_other'),
43-
data: Object.keys(exchangeRates)
44-
.sort()
45-
.map((ticker) => ({
46-
title: ticker,
47-
value: selectedCurrency === ticker,
48-
type: EItemType.button,
49-
onPress: (): void => {
50-
navigation.goBack();
51-
onSetCurrency(ticker);
52-
},
53-
})),
45+
data: currencies.map((ticker) => ({
46+
title: ticker,
47+
value: selectedCurrency === ticker,
48+
type: EItemType.button,
49+
onPress: (): void => {
50+
navigation.goBack();
51+
onSetCurrency(ticker);
52+
},
53+
})),
5454
},
5555
];
5656
}, [selectedCurrency, exchangeRates, navigation, t, dispatch]);

src/store/shapes/settings.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
11
import { ECoinSelectPreference, EProtocol, TServer } from 'beignet';
22
import cloneDeep from 'lodash/cloneDeep';
3+
import { getCurrencies } from 'react-native-localize';
34

45
import {
6+
__E2E__,
57
__ELECTRUM_REGTEST_HOST__,
68
__ELECTRUM_REGTEST_PROTO__,
79
__ELECTRUM_REGTEST_SSL_PORT__,
810
__ELECTRUM_REGTEST_TCP_PORT__,
911
__WEB_RELAY__,
1012
} from '../../constants/env';
13+
import { currencies } from '../../utils/exchange-rate/currencies';
1114
import { EAvailableNetwork } from '../../utils/networks';
1215
import { TSettings } from '../slices/settings';
1316
import { ETransactionSpeed } from '../types/settings';
1417
import { EDenomination, EUnit } from '../types/wallet';
1518

19+
const getDefaultCurrency = (): string => {
20+
if (__E2E__) {
21+
return 'USD';
22+
}
23+
24+
const localCurrencies = getCurrencies();
25+
26+
// Find the first currency that matches the user's preference
27+
const preferredCurrency = localCurrencies.find((currency) => {
28+
return currencies.includes(currency);
29+
});
30+
31+
return preferredCurrency ?? 'USD';
32+
};
33+
1634
export const defaultElectrumPeer: Record<EAvailableNetwork, TServer[]> = {
1735
bitcoin: [
1836
{
@@ -82,7 +100,7 @@ export const initialSettingsState: TSettings = {
82100
theme: 'dark',
83101
unit: EUnit.BTC,
84102
denomination: EDenomination.modern,
85-
selectedCurrency: 'USD',
103+
selectedCurrency: getDefaultCurrency(),
86104
selectedLanguage: 'english',
87105
customElectrumPeers: defaultElectrumPeer,
88106
rapidGossipSyncUrl: 'https://rgs.blocktank.to/snapshot/',
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// The currencies that are supported by the exchange rate API
2+
// https://blocktank.synonym.to/fx/rates/btc/
3+
4+
export const currencies = [
5+
'ARS',
6+
'AUD',
7+
'BHD',
8+
'BDT',
9+
'BMD',
10+
'BRL',
11+
'CAD',
12+
'CLP',
13+
'CNY',
14+
'CZK',
15+
'DKK',
16+
'EUR',
17+
'GEL',
18+
'GBP',
19+
'HKD',
20+
'HUF',
21+
'XDR',
22+
'INR',
23+
'IDR',
24+
'ILS',
25+
'JPY',
26+
'KWD',
27+
'MYR',
28+
'MXN',
29+
'MMK',
30+
'TWD',
31+
'NZD',
32+
'NOK',
33+
'PKR',
34+
'PHP',
35+
'PLN',
36+
'RUB',
37+
'SAR',
38+
'SGD',
39+
'ZAR',
40+
'KRW',
41+
'LKR',
42+
'SEK',
43+
'CHF',
44+
'USDT',
45+
'THB',
46+
'TRY',
47+
'USD',
48+
'UAH',
49+
'AED',
50+
'VEF',
51+
'VND',
52+
];

src/utils/i18n/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import i18n from 'i18next';
22
import ICU from 'i18next-icu';
33
import { initReactI18next } from 'react-i18next';
4-
import * as RNLocalize from 'react-native-localize';
4+
import { findBestLanguageTag, getTimeZone } from 'react-native-localize';
55

66
import { __ENABLE_I18NEXT_DEBUGGER__, __JEST__ } from '../../constants/env';
77
import { dispatch } from '../../store/helpers';
@@ -14,9 +14,7 @@ import locales, {
1414
} from './locales';
1515

1616
const getDeviceLanguage = (): string => {
17-
const lang =
18-
RNLocalize.findBestLanguageTag(Object.keys(locales))?.languageTag ?? 'en';
19-
return lang;
17+
return findBestLanguageTag(Object.keys(locales))?.languageTag ?? 'en';
2018
};
2119

2220
const resources = convert(locales);
@@ -41,7 +39,7 @@ i18nICU
4139
returnNull: false,
4240
})
4341
.then(() => {
44-
let timeZone = RNLocalize.getTimeZone();
42+
let timeZone = getTimeZone();
4543

4644
// if polyfill is used, we need to set default timezone
4745
// https://formatjs.io/docs/polyfills/intl-datetimeformat/#default-timezone

0 commit comments

Comments
 (0)