Permalink
Browse files

feat(i18n): detect best-fit user currency

Use the locale information in order to select a best fit default
currency for the user.
  • Loading branch information...
mrfelton committed Sep 18, 2018
1 parent cc2e789 commit 27e46ccde841043928a059bdd1933decaecb2614
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import FaAngleLeft from 'react-icons/lib/fa/angle-left'
import ISO6391 from 'iso-639-1'
import { getLanguageName } from 'lib/utils/i18n'
import Isvg from 'react-inlinesvg'
import checkIcon from 'icons/check.svg'
@@ -29,7 +29,7 @@ const Translate = ({ locales, disableSubMenu, currentLocale, setLocale }) => {
className={currentLocale === lang ? styles.active : ''}
onClick={() => changeLocale(lang)}
>
<span>{ISO6391.getName(lang.split('-')[0])}</span>
<span>{getLanguageName(lang)}</span>
{currentLocale === lang && <Isvg src={checkIcon} />}
</li>
)
View
@@ -7,12 +7,13 @@ import Root from './containers/Root'
import { configureStore, history } from './store/configureStore'
import './styles/app.global.scss'
import { translationMessages, DEFAULT_LOCALE } from './lib/utils/i18n'
import { translationMessages, getLocale } from './lib/utils/i18n'
const locale = getLocale()
const initialState = {
intl: {
locale: DEFAULT_LOCALE,
messages: translationMessages[DEFAULT_LOCALE],
locale,
messages: translationMessages[locale],
timeZone: jstz.determine().name()
}
}
View
@@ -1,6 +1,9 @@
import { app, remote } from 'electron'
import Store from 'electron-store'
import { addLocaleData } from 'react-intl'
import Store from 'electron-store'
import get from 'lodash.get'
import { lookup } from 'country-data-lookup'
import createDebug from 'debug'
// Load locale data.
import bg from 'react-intl/locale-data/bg'
@@ -41,6 +44,8 @@ import ukTranslationMessages from '../../translations/uk-UA.json'
import zhCNTranslationMessages from '../../translations/zh-CN.json'
import zhTWTranslationMessages from '../../translations/zh-TW.json'
const debug = createDebug('zap:i18n')
// Add locale data.
addLocaleData([
...bg,
@@ -83,24 +88,31 @@ export const locales = [
'zh'
]
function getDefaltLocale() {
const store = new Store({ name: 'settings' })
// Detect user language.
let language = store.get('locale') || (app || remote.app).getLocale()
// If the detected language is not available, strip out any regional component and check again.
if (!locales.includes(language)) {
language = language.toLowerCase().split(/[_-]+/)[0]
}
// If we still can't find the users language, default to english.
if (!locales.includes(language)) {
language = 'en'
}
return language
}
export const DEFAULT_LOCALE = getDefaltLocale()
// Defaine list of currencies that we will support.
export const currencies = [
'USD',
'EUR',
'JPY',
'GBP',
'CAD',
'KRW',
'AUD',
'BRL',
'CHF',
'CLP',
'CNY',
'DKK',
'HKD',
'INR',
'ISK',
'NZD',
'PLN',
'RUB',
'SEK',
'SGD',
'THB',
'TWB'
]
// Collate all translations.
export const translationMessages = {
@@ -123,3 +135,62 @@ export const translationMessages = {
tr: trTranslationMessages,
uk: ukTranslationMessages
}
/**
* Get the most appropriate language code.
* @return {string} Language code.
*/
export const getLocale = () => {
const store = new Store({ name: 'settings' })
const userLocale = store.get('locale')
if (userLocale) {
debug('Determined locale as %s from settings', userLocale)
return userLocale
}
const defaultLocale = (app || remote.app).getLocale() || 'en-US'
const language = defaultLocale.toLowerCase().split(/[_-]+/)[0]
let locale = 'en'
if (locales.includes(language)) {
locale = language
}
if (locales.includes(defaultLocale)) {
locale = userLocale
}
debug('Determined locale as %s', locale)
return locale
}
/**
* Get the most appropriate language code.
* @return {string} Language code.
*/
export const getLanguageName = lang => {
const language = lang.toLowerCase().split(/[_-]+/)[0]
const data = lookup.languages({ alpha2: language })
const name = get(data, '[0]name', language)
debug('Determined language as %s', name)
return name
}
/**
* Get the most appropriate currency code.
* @return {string} Currency code.
*/
export const getCurrency = () => {
const store = new Store({ name: 'settings' })
const userCurrency = store.get('fiatTicker')
if (userCurrency) {
debug('Determined currency as %s from settings', userCurrency)
return userCurrency
}
const defaultLocale = (app || remote.app).getLocale() || 'en-US'
const country = defaultLocale.split(/[_-]+/)[1]
const data = lookup.countries({ alpha2: country })
const detectedCurrency = get(data, '[0]currencies[0]', 'USD')
let currency = 'USD'
if (currencies.includes(detectedCurrency)) {
currency = detectedCurrency
}
debug('Determined currency as %s', currency)
return currency
}
@@ -1,15 +1,14 @@
// @flow
import { app, Menu, shell, BrowserWindow, ipcMain } from 'electron'
import ISO6391 from 'iso-639-1'
import { locales, DEFAULT_LOCALE } from '../utils/i18n'
import { locales, getLocale, getLanguageName } from '../utils/i18n'
export default class ZapMenuBuilder {
mainWindow: BrowserWindow
locale: string
constructor(mainWindow: BrowserWindow) {
this.mainWindow = mainWindow
this.locale = DEFAULT_LOCALE
this.locale = getLocale()
ipcMain.on('setLocale', (event, locale) => this.buildMenu(locale))
}
@@ -281,7 +280,7 @@ export default class ZapMenuBuilder {
label: 'Language',
submenu: locales.map(locale => {
return {
label: ISO6391.getName(locale.split('-')[0]),
label: getLanguageName(locale),
type: 'radio',
checked: this.locale === locale,
click: () => this.mainWindow.webContents.send('receiveLocale', locale)
View
@@ -1,6 +1,7 @@
import { createSelector } from 'reselect'
import Store from 'electron-store'
import { requestTicker } from 'lib/utils/api'
import { currencies, getCurrency } from 'lib/utils/i18n'
import { infoSelectors } from './info'
// Settings store
@@ -141,31 +142,8 @@ const initialState = {
crypto: '',
btcTicker: null,
ltcTicker: null,
fiatTicker: store.get('fiatTicker', 'USD'),
fiatTickers: [
'USD',
'EUR',
'JPY',
'GBP',
'CAD',
'KRW',
'AUD',
'BRL',
'CHF',
'CLP',
'CNY',
'DKK',
'HKD',
'INR',
'ISK',
'NZD',
'PLN',
'RUB',
'SEK',
'SGD',
'THB',
'TWB'
],
fiatTicker: getCurrency(),
fiatTickers: currencies,
currencyFilters: [
{
key: 'btc',
View
@@ -286,6 +286,7 @@
"axios": "^0.18.0",
"bitcoinjs-lib": "^4.0.1",
"copy-to-clipboard": "^3.0.8",
"country-data-lookup": "^0.0.3",
"debug": "^4.0.1",
"debug-logger": "^0.4.1",
"devtron": "^1.4.0",
@@ -295,7 +296,6 @@
"electron-store": "^2.0.0",
"font-awesome": "^4.7.0",
"history": "^4.7.2",
"iso-639-1": "^2.0.3",
"javascript-state-machine": "^3.1.0",
"jstimezonedetect": "^1.0.6",
"lodash.get": "^4.4.2",
@@ -5,9 +5,14 @@ module.exports = {
match: jest.fn(),
app: {
getPath: name => normalize(`/tmp/zap-test/${name}`),
getAppPath: () => normalize('/tmp/zap-test')
getAppPath: () => normalize('/tmp/zap-test'),
getLocale: jest.fn()
},
remote: {
app: {
getLocale: jest.fn()
}
},
remote: jest.fn(),
dialog: jest.fn(),
BrowserWindow: jest.fn(),
ipcMain: {
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

0 comments on commit 27e46cc

Please sign in to comment.