Skip to content
This repository was archived by the owner on Feb 23, 2021. It is now read-only.

Commit 8e97a93

Browse files
authored
Merge pull request #501 from lightninglabs/detect-locale-updated
Detect locale updated
2 parents 1f0e0ae + 7297222 commit 8e97a93

File tree

20 files changed

+242
-44
lines changed

20 files changed

+242
-44
lines changed

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"electron-log": "^2.2.14",
3131
"electron-updater": "^2.21.10",
3232
"grpc": "^1.10.0",
33+
"locale-currency": "0.0.2",
3334
"mobx": "^3.6.2",
3435
"mobx-react": "^4.4.3",
3536
"qr-image": "^3.2.0",

public/electron.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ log.transports.console.level = 'info';
4343
log.transports.file.level = 'info';
4444
ipcMain.on('log', (event, arg) => log.info(...arg));
4545
ipcMain.on('log-error', (event, arg) => log.error(...arg));
46+
ipcMain.on('locale-get', event =>
47+
event.sender.send('locale', { response: app.getLocale() })
48+
);
4649

4750
let logQueue = [];
4851
let logsReady = false;

public/preload.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
const _ipcRenderer = require('electron').ipcRenderer;
66

77
const filter = event => {
8-
if (!/^(lnd)|(unlock)|(log)|(open-url)[a-zA-Z_-]{0,20}$/.test(event)) {
8+
if (
9+
!/^(lnd)|(unlock)|(log)|(locale)|(open-url)[a-zA-Z_-]{0,20}$/.test(event)
10+
) {
911
throw new Error(`Invalid IPC: ${event}`);
1012
}
1113
return event;

src/action/grpc.js

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
/**
22
* @fileOverview a low level action to proxy GRPC api calls to and from lnd
3-
* over electron's IPC renderer api. This module should not be invokes directly
3+
* over an IPC api. This module should not be invokes directly
44
* from the UI but rather used within other higher level actions.
55
*/
66

77
import { Duplex } from 'stream';
88
import * as log from './log';
99

1010
class GrpcAction {
11-
constructor(store, ipcRenderer) {
11+
constructor(store, ipc) {
1212
this._store = store;
13-
this._ipcRenderer = ipcRenderer;
13+
this._ipc = ipc;
1414
}
1515

1616
//
@@ -96,14 +96,14 @@ class GrpcAction {
9696
const stream = new Duplex({
9797
write(data) {
9898
data = JSON.parse(data.toString('utf8'));
99-
self._ipcRenderer.send('lndStreamWrite', { method, data });
99+
self._ipc.send('lndStreamWrite', null, { method, data });
100100
},
101101
read() {},
102102
});
103-
this._ipcRenderer.on(`lndStreamEvent_${method}`, (e, arg) => {
103+
this._ipc.listen(`lndStreamEvent_${method}`, (e, arg) => {
104104
stream.emit(arg.event, arg.data || arg.err);
105105
});
106-
this._ipcRenderer.send('lndStreamRequest', { method, body });
106+
this._ipc.send('lndStreamRequest', null, { method, body });
107107
return stream;
108108
}
109109

@@ -112,17 +112,8 @@ class GrpcAction {
112112
//
113113

114114
_sendIpc(event, listen, method, body) {
115-
return new Promise((resolve, reject) => {
116-
listen = method ? `${listen}_${method}` : listen;
117-
this._ipcRenderer.once(listen, (e, arg) => {
118-
if (arg.err) {
119-
reject(arg.err);
120-
} else {
121-
resolve(arg.response);
122-
}
123-
});
124-
this._ipcRenderer.send(event, { method, body });
125-
});
115+
listen = method ? `${listen}_${method}` : listen;
116+
return this._ipc.send(event, listen, { method, body });
126117
}
127118
}
128119

src/action/index.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { AsyncStorage, Clipboard } from 'react-native';
99
import { nap } from '../helper';
1010
import store from '../store';
1111
import AppStorage from './app-storage';
12+
import IpcAction from './ipc';
1213
import GrpcAction from './grpc';
1314
import NavAction from './nav';
1415
import WalletAction from './wallet';
@@ -21,18 +22,17 @@ import PaymentAction from './payment';
2122
import InvoiceAction from './invoice';
2223
import SettingAction from './setting';
2324

24-
const ipcRenderer = window.ipcRenderer; // exposed to sandbox via preload.js
25-
2625
//
2726
// Inject dependencies
2827
//
2928

3029
store.init(); // initialize computed values
3130

31+
export const ipc = new IpcAction(window.ipcRenderer);
3232
export const db = new AppStorage(store, AsyncStorage);
33-
export const log = new LogAction(store, ipcRenderer);
33+
export const log = new LogAction(store, ipc);
3434
export const nav = new NavAction(store);
35-
export const grpc = new GrpcAction(store, ipcRenderer);
35+
export const grpc = new GrpcAction(store, ipc);
3636
export const notify = new NotificationAction(store, nav);
3737
export const wallet = new WalletAction(store, grpc, db, nav, notify);
3838
export const info = new InfoAction(store, grpc, nav, notify);
@@ -47,9 +47,9 @@ export const invoice = new InvoiceAction(
4747
Clipboard
4848
);
4949
export const payment = new PaymentAction(store, grpc, transaction, nav, notify);
50-
export const setting = new SettingAction(store, wallet, db);
50+
export const setting = new SettingAction(store, wallet, db, ipc);
5151

52-
payment.listenForUrl(ipcRenderer); // enable incoming url handler
52+
payment.listenForUrl(ipc); // enable incoming url handler
5353

5454
//
5555
// Init actions
@@ -71,6 +71,14 @@ observe(store, 'unlockerReady', async () => {
7171
await wallet.init();
7272
});
7373

74+
/**
75+
* Triggered the first time the app was started e.g. to set the
76+
* local fiat currency only once.
77+
*/
78+
observe(store, 'firstStart', async () => {
79+
await setting.detectLocalCurrency();
80+
});
81+
7482
/**
7583
* Triggered after the user's password has unlocked the wallet.
7684
*/

src/action/ipc.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* @fileOverview a low level action to wrap electron's IPC renderer api.
3+
*/
4+
5+
class IpcAction {
6+
constructor(ipcRenderer) {
7+
this._ipcRenderer = ipcRenderer;
8+
}
9+
10+
/**
11+
* A wrapper around electron's ipcRenderer send api that can be
12+
* reused wherever IPC to the main process is necessary.
13+
* @param {string} event The event name the main process listens to
14+
* @param {string} listen (optional) The response event name this process listens to
15+
* @param {*} payload The data sent over IPC
16+
* @return {Promise<Object>}
17+
*/
18+
send(event, listen, payload) {
19+
return new Promise((resolve, reject) => {
20+
this._ipcRenderer.send(event, payload);
21+
if (!listen) return resolve();
22+
this._ipcRenderer.once(listen, (e, arg) => {
23+
if (arg.err) {
24+
reject(arg.err);
25+
} else {
26+
resolve(arg.response);
27+
}
28+
});
29+
});
30+
}
31+
32+
/**
33+
* A wrapper around electron's ipcRenderer listen api that can be
34+
* reused wherever listening to IPC from the main process is necessary.
35+
* @param {string} event The event name this process listens to
36+
* @param {Function} callback The event handler for incoming data
37+
* @return {undefined}
38+
*/
39+
listen(event, callback) {
40+
this._ipcRenderer.on(event, callback);
41+
}
42+
}
43+
44+
export default IpcAction;

src/action/log.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import { MAX_LOG_LENGTH } from '../config';
99

1010
let _store;
11-
let _ipcRenderer;
11+
let _ipc;
1212

1313
/**
1414
* Log an info event e.g. when something relevant but non-critical happens.
@@ -19,7 +19,7 @@ let _ipcRenderer;
1919
*/
2020
export function info(...args) {
2121
console.log(...args);
22-
_ipcRenderer && _ipcRenderer.send('log', args);
22+
_ipc && _ipc.send('log', null, args);
2323
}
2424

2525
/**
@@ -39,7 +39,7 @@ export function error(...args) {
3939
pushLogs(JSON.stringify(args[i], null, ' '));
4040
}
4141
pushLogs(''); // newline
42-
_ipcRenderer && _ipcRenderer.send('log-error', args);
42+
_ipc && _ipc.send('log-error', null, args);
4343
}
4444

4545
function pushLogs(message) {
@@ -52,11 +52,11 @@ function pushLogs(message) {
5252
}
5353

5454
class LogAction {
55-
constructor(store, ipcRenderer) {
55+
constructor(store, ipc) {
5656
_store = store;
57-
_ipcRenderer = ipcRenderer;
58-
_ipcRenderer.on('logs', (event, message) => pushLogs(message));
59-
_ipcRenderer.send('logs-ready', true);
57+
_ipc = ipc;
58+
_ipc.listen('logs', (event, message) => pushLogs(message));
59+
_ipc.send('logs-ready', null, true);
6060
}
6161
}
6262

src/action/payment.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ class PaymentAction {
2929
* @param {Object} ipcRenderer Electron's IPC api for the rendering process
3030
* @return {undefined}
3131
*/
32-
listenForUrl(ipcRenderer) {
33-
ipcRenderer.on('open-url', async (event, url) => {
32+
listenForUrl(ipc) {
33+
ipc.listen('open-url', async (event, url) => {
3434
log.info('open-url', url);
3535
if (!isLnUri(url)) {
3636
return;

src/action/setting.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
*/
55

66
import { UNITS, FIATS } from '../config';
7+
import localeCurrency from 'locale-currency';
8+
import * as log from './log';
79

810
class SettingAction {
9-
constructor(store, wallet, db) {
11+
constructor(store, wallet, db, ipc) {
1012
this._store = store;
1113
this._wallet = wallet;
1214
this._db = db;
15+
this._ipc = ipc;
1316
}
1417

1518
/**
@@ -38,6 +41,21 @@ class SettingAction {
3841
this._wallet.getExchangeRate();
3942
this._db.save();
4043
}
44+
45+
/**
46+
* Detect the user's local fiat currency based on their OS locale.
47+
* If the currency is not supported use the default currency `usd`.
48+
* @return {Promise<undefined>}
49+
*/
50+
async detectLocalCurrency() {
51+
try {
52+
let locale = await this._ipc.send('locale-get', 'locale');
53+
const fiat = localeCurrency.getCurrency(locale).toLowerCase();
54+
this.setFiatCurrency({ fiat });
55+
} catch (err) {
56+
log.error('Detecting local currency failed', err);
57+
}
58+
}
4159
}
4260

4361
export default SettingAction;

0 commit comments

Comments
 (0)