Files: 3451510316992d414ec76ba5b29681fe359b7428 / lib / depject / intl / sync / i18n.js
2750 bytesRaw
1 | const nest = require('depnest') |
2 | const { watch } = require('mutant') |
3 | const appRoot = require('app-root-path') |
4 | const i18nL = require('i18n') |
5 | const electron = require('electron') |
6 | |
7 | exports.gives = nest('intl.sync', [ |
8 | 'locale', |
9 | 'locales', |
10 | 'localeNames', |
11 | 'i18n', |
12 | 'i18n_n', |
13 | 'startsWith' |
14 | ]) |
15 | |
16 | exports.needs = nest({ |
17 | 'settings.obs.get': 'first' |
18 | }) |
19 | |
20 | exports.create = (api) => { |
21 | let _locale |
22 | |
23 | // TODO: this should probably follow the selected language |
24 | const collator = new Intl.Collator('default', { sensitivity: 'base', usage: 'search' }) |
25 | |
26 | return nest('intl.sync', { |
27 | locale, |
28 | locales, |
29 | startsWith, |
30 | localeNames, |
31 | i18n, |
32 | i18n_n: i18nN |
33 | }) |
34 | |
35 | function startsWith (text, startsWith) { |
36 | return collator.compare(text.slice(0, startsWith.length), startsWith) === 0 |
37 | } |
38 | |
39 | // Get locale value in setting |
40 | function locale () { |
41 | return api.settings.obs.get('patchwork.lang') |
42 | } |
43 | |
44 | // Get all locales loaded in i18nL |
45 | function locales () { |
46 | return i18nL.getLocales() |
47 | } |
48 | |
49 | function localeNames () { |
50 | const names = i18nL.__l('$name') |
51 | return locales().reduce((result, item, i) => { |
52 | result[item] = names[i] |
53 | return result |
54 | }, {}) |
55 | } |
56 | |
57 | // Get translation |
58 | function i18n (value, ...opts) { |
59 | _init() |
60 | return i18nL.__(value, ...opts) |
61 | } |
62 | |
63 | // Get translation |
64 | function i18nN (value, ...opts) { |
65 | _init() |
66 | return i18nL.__n(value, ...opts) |
67 | } |
68 | |
69 | // Init an subscribe to settings changes. |
70 | function _init () { |
71 | if (_locale) return |
72 | // TODO: Depject this! |
73 | i18nL.configure({ |
74 | directory: appRoot + '/locales', |
75 | defaultLocale: 'en' |
76 | }) |
77 | |
78 | watch(api.settings.obs.get('patchwork.lang'), currentLocale => { |
79 | currentLocale = currentLocale || navigator.language |
80 | const locales = i18nL.getLocales() |
81 | |
82 | // Try BCP47 codes, otherwise load family language if exist |
83 | if (locales.indexOf(currentLocale) !== -1) { |
84 | i18nL.setLocale(currentLocale) |
85 | } else { |
86 | i18nL.setLocale(getSimilar(locales, currentLocale)) |
87 | } |
88 | |
89 | // Only refresh if the language has already been selected once. |
90 | // This will prevent the update loop |
91 | if (_locale) { |
92 | electron.remote.getCurrentWebContents().reloadIgnoringCache() |
93 | } |
94 | }) |
95 | |
96 | _locale = true |
97 | } |
98 | } |
99 | |
100 | // For now get only global languages |
101 | function getSubLocal (loc) { |
102 | return typeof loc === 'string' && loc.split('-')[0] |
103 | } |
104 | |
105 | function getSimilar (locales, option) { |
106 | const reindexed = {} |
107 | locales.forEach(function (local) { |
108 | (reindexed[getSubLocal(local)]) |
109 | ? reindexed[getSubLocal(local)].concat(local) |
110 | : reindexed[getSubLocal(local)] = [local] |
111 | }, this) |
112 | if (reindexed[getSubLocal(option)]) { |
113 | return reindexed[getSubLocal(option)][0] |
114 | } |
115 | return option |
116 | } |
117 |
Built with git-ssb-web