diff --git a/client/i18next-scanner.config.cjs b/client/i18next-scanner.config.cjs index 6607bf0e..de63e15d 100644 --- a/client/i18next-scanner.config.cjs +++ b/client/i18next-scanner.config.cjs @@ -2,6 +2,70 @@ const typescriptTransform = require('i18next-scanner-typescript'); const fs = require('fs'); const chalk = require('chalk'); +const eol = require('eol'); +const path = require('path'); +const VirtualFile = require('vinyl'); + +function flush(done) { + const { parser } = this; + const { options } = parser; + + // Flush to resource store + const resStore = parser.get({ sort: options.sort }); + const { jsonIndent } = options.resource; + const lineEnding = String(options.resource.lineEnding).toLowerCase(); + + Object.keys(resStore).forEach((lng) => { + const namespaces = resStore[lng]; + + Object.keys(namespaces).forEach((ns) => { + const resPath = parser.formatResourceSavePath(lng, ns); + let resContent; + try { + resContent = JSON.parse( + fs.readFileSync( + fs.realpathSync(path.join('public', 'locales', resPath)) + ).toString('utf-8') + ); + } catch (e) { + console.log("no previous translation found!") + resContent = {}; + } + const obj = { ...namespaces[ns], ...resContent }; + let text = JSON.stringify(obj, null, jsonIndent) + '\n'; + + if (lineEnding === 'auto') { + text = eol.auto(text); + } else if (lineEnding === '\r\n' || lineEnding === 'crlf') { + text = eol.crlf(text); + } else if (lineEnding === '\n' || lineEnding === 'lf') { + text = eol.lf(text); + } else if (lineEnding === '\r' || lineEnding === 'cr') { + text = eol.cr(text); + } else { // Defaults to LF + text = eol.lf(text); + } + + let contents = null; + + try { + // "Buffer.from(string[, encoding])" is added in Node.js v5.10.0 + contents = Buffer.from(text); + } catch (e) { + // Fallback to "new Buffer(string[, encoding])" which is deprecated since Node.js v6.0.0 + contents = new Buffer(text); + } + + this.push(new VirtualFile({ + path: resPath, + contents: contents + })); + }); + }); + + done(); +} + module.exports = { input: [ @@ -10,7 +74,6 @@ module.exports = { '!client/i18n/**', '!**/node_modules/**', ], - output: './client/public/locales', options: { debug: true, func: { @@ -45,8 +108,8 @@ module.exports = { return ''; // Return empty string for other languages }, resource: { - loadPath: './{{lng}}/{{ns}}.json', - savePath: './{{lng}}/{{ns}}.json', + loadPath: './client/public/locales/{{lng}}/{{ns}}.json', + savePath: './client/public/locales/{{lng}}/{{ns}}.json', jsonIndent: 2, lineEnding: '\n' }, diff --git a/client/public/locales/de/translation.json b/client/public/locales/de/translation.json index b201b0a1..24fb915e 100644 --- a/client/public/locales/de/translation.json +++ b/client/public/locales/de/translation.json @@ -8,5 +8,35 @@ "regular": "regulär", "relaxed": "relaxed", "none": "keine", - "Rules": "Regeln" + "Rules": "Regeln", + "Intro": "", + "Game Introduction": "", + "World selection": "", + "Start": "", + "Inventory": "", + "next level": "", + "Next": "", + "back to world selection": "", + "Leave World": "", + "previous level": "", + "Previous": "", + "Editor mode is enforced!": "", + "Editor mode": "", + "Typewriter mode": "", + "information, Impressum, privacy policy": "", + "Impressum": "", + "Preferences": "", + "Game Info & Credits": "", + "Game Info": "", + "Clear Progress": "", + "Erase": "", + "Download Progress": "", + "Download": "", + "Load Progress from JSON": "", + "Upload": "", + "Home": "", + "back to games selection": "", + "close inventory": "", + "show inventory": "", + "World": "" } diff --git a/client/public/locales/en/translation.json b/client/public/locales/en/translation.json index 03053fa7..85cb20fc 100644 --- a/client/public/locales/en/translation.json +++ b/client/public/locales/en/translation.json @@ -8,5 +8,35 @@ "regular": "regular", "relaxed": "relaxed", "none": "none", - "Rules": "Rules" + "Rules": "Rules", + "Intro": "Intro", + "Game Introduction": "Game Introduction", + "World selection": "World selection", + "Start": "Start", + "Inventory": "Inventory", + "next level": "next level", + "Next": "Next", + "back to world selection": "back to world selection", + "Leave World": "Leave World", + "previous level": "previous level", + "Previous": "Previous", + "Editor mode is enforced!": "Editor mode is enforced!", + "Editor mode": "Editor mode", + "Typewriter mode": "Typewriter mode", + "information, Impressum, privacy policy": "information, Impressum, privacy policy", + "Impressum": "Impressum", + "Preferences": "Preferences", + "Game Info & Credits": "Game Info & Credits", + "Game Info": "Game Info", + "Clear Progress": "Clear Progress", + "Erase": "Erase", + "Download Progress": "Download Progress", + "Download": "Download", + "Load Progress from JSON": "Load Progress from JSON", + "Upload": "Upload", + "Home": "Home", + "back to games selection": "back to games selection", + "close inventory": "close inventory", + "show inventory": "show inventory", + "World": "World" } diff --git a/client/src/i18n.ts b/client/src/i18n.ts index f7d148bb..10e25b1d 100644 --- a/client/src/i18n.ts +++ b/client/src/i18n.ts @@ -9,7 +9,7 @@ i18n lng: "en", // language to use, more information here: https://www.i18next.com/overview/configuration-options#languages-namespaces-resources // you can use the i18n.changeLanguage function to change the language manually: https://www.i18next.com/overview/api#changelanguage // if you're using a language detector, do not define the lng option - + returnEmptyString: false, interpolation: { escapeValue: false // react already safes from xss }