summaryrefslogtreecommitdiffhomepage
path: root/gui/src/shared/gettext.ts
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-03-01 17:36:15 +0100
committerAndrej Mihajlov <and@mullvad.net>2019-03-01 17:36:15 +0100
commit65ef2fcc8a4b58a92219ea0ae269c91f80be0062 (patch)
treeb69a7e097fcf2ff61a06b053147c564f3c0f0296 /gui/src/shared/gettext.ts
parent2610bd23035901ba0e25824629d3768b4430a708 (diff)
parent1a1eb84364add292974d7dafe69761270c7397ef (diff)
downloadmullvadvpn-65ef2fcc8a4b58a92219ea0ae269c91f80be0062.tar.xz
mullvadvpn-65ef2fcc8a4b58a92219ea0ae269c91f80be0062.zip
Merge branch 'remove-workspaces'
Diffstat (limited to 'gui/src/shared/gettext.ts')
-rw-r--r--gui/src/shared/gettext.ts80
1 files changed, 80 insertions, 0 deletions
diff --git a/gui/src/shared/gettext.ts b/gui/src/shared/gettext.ts
new file mode 100644
index 0000000000..4722e16915
--- /dev/null
+++ b/gui/src/shared/gettext.ts
@@ -0,0 +1,80 @@
+import log from 'electron-log';
+import fs from 'fs';
+import { po } from 'gettext-parser';
+import Gettext from 'node-gettext';
+import path from 'path';
+
+const SOURCE_LANGUAGE = 'en';
+let SELECTED_LANGUAGE = SOURCE_LANGUAGE;
+const LOCALES_DIR = path.resolve(__dirname, '../../locales');
+
+// `{debug: false}` option prevents Gettext from printing the warnings to console in development
+// the errors are handled separately in the "error" handler below
+const catalogue = new Gettext({ debug: false });
+catalogue.setTextDomain('messages');
+catalogue.on('error', (error: string) => {
+ // Filter out the "no translation was found" errors for the source language
+ if (SELECTED_LANGUAGE === SOURCE_LANGUAGE && error.indexOf('No translation was found') !== -1) {
+ return;
+ }
+
+ log.warn(`Gettext error: ${error}`);
+});
+
+export function loadTranslations(currentLocale: string) {
+ // First look for exact match of the current locale
+ const preferredLocales = [];
+
+ if (currentLocale !== SOURCE_LANGUAGE) {
+ preferredLocales.push(currentLocale);
+ }
+
+ // In case of region bound locale like en-US, fallback to en.
+ const language = Gettext.getLanguageCode(currentLocale);
+ if (currentLocale !== language) {
+ preferredLocales.push(language);
+ }
+
+ for (const locale of preferredLocales) {
+ if (parseTranslation(locale, 'messages')) {
+ log.info(`Loaded translations for ${locale}`);
+ catalogue.setLocale(locale);
+
+ SELECTED_LANGUAGE = locale;
+ return;
+ }
+ }
+}
+
+function parseTranslation(locale: string, domain: string): boolean {
+ const filename = path.join(LOCALES_DIR, locale, `${domain}.po`);
+ let buffer: Buffer;
+
+ try {
+ buffer = fs.readFileSync(filename);
+ } catch (error) {
+ if (error.code !== 'ENOENT') {
+ log.error(`Cannot read the gettext file "${filename}": ${error.message}`);
+ }
+ return false;
+ }
+
+ let translations: object;
+ try {
+ translations = po.parse(buffer);
+ } catch (error) {
+ log.error(`Cannot parse the gettext file "${filename}": ${error.message}`);
+ return false;
+ }
+
+ catalogue.addTranslations(locale, domain, translations);
+
+ return true;
+}
+
+export const gettext = (msgid: string): string => {
+ return catalogue.gettext(msgid);
+};
+export const pgettext = (msgctx: string, msgid: string): string => {
+ return catalogue.pgettext(msgctx, msgid);
+};