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