diff --git a/.eslintrc.json b/.eslintrc.json
index e92b6b9..411df8f 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -188,7 +188,7 @@
"react/jsx-max-props-per-line": ["warn", {"maximum": 3}],
"react/jsx-no-bind": "warn",
"react/jsx-no-duplicate-props": "warn",
- "react/jsx-no-literals": "warn",
+ "react/jsx-no-literals": "off",
"react/jsx-no-undef": "warn",
"react/jsx-pascal-case": "warn",
"react/jsx-uses-react": "warn",
@@ -206,7 +206,7 @@
"react/no-unknown-property": "warn",
"react/prefer-es6-class": "warn",
"react/prop-types": "warn",
- "react/react-in-jsx-scope": "warn",
+ "react/react-in-jsx-scope": "off",
"react/self-closing-comp": "warn",
"react/sort-comp": ["warn", {"order": ["lifecycle", "render", "everything-else"]}]
}
diff --git a/package.json b/package.json
index 755dc0e..dff6a5c 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"up": "npm update",
"test": "karma start ./karma.conf.js",
"lint": "eslint ./src",
- "i18n": "cd ./scripts && ./node_modules/.bin/babel-node i18n-collect.js",
+ "i18n": "cd ./scripts && ../node_modules/.bin/babel-node i18n-collect.js",
"build": "rm -rf dist/ && NODE_ENV=production webpack --progress --colors",
"render": ""
},
diff --git a/scripts/i18n-collect.js b/scripts/i18n-collect.js
index 10c2e44..6a4657c 100644
--- a/scripts/i18n-collect.js
+++ b/scripts/i18n-collect.js
@@ -52,38 +52,35 @@ let keysToAdd = [];
let keysToRemove = [];
const keysToRename = [];
const isNotMarked = (value) => value.slice(0, 2) !== '--';
-try {
- const prevMessages = JSON.parse(fs.readFileSync(defaultMessagesPath, 'utf8'));
- const prevMessagesMap = Object.entries(prevMessages).reduce((acc, [key, value]) => {
- if (acc[value]) {
- acc[value].push(key);
- } else {
- acc[value] = [key];
- }
- return acc;
- }, {});
- keysToAdd = Object.keys(collectedMessages).filter((key) => !prevMessages[key]);
- keysToRemove = Object.keys(prevMessages).filter((key) => !collectedMessages[key]).filter(isNotMarked);
- keysToUpdate = Object.entries(prevMessages).reduce((acc, [key, message]) =>
- acc.concat(collectedMessages[key] && collectedMessages[key] !== message ? key : [])
- , []);
+const prevMessages = readJSON(defaultMessagesPath);
+const prevMessagesMap = Object.entries(prevMessages).reduce((acc, [key, value]) => {
+ if (acc[value]) {
+ acc[value].push(key);
+ } else {
+ acc[value] = [key];
+ }
- // detect keys to rename, mutating keysToAdd and keysToRemove
- [].concat(keysToAdd).forEach((toKey) => {
- const keys = prevMessagesMap[collectedMessages[toKey]] || [];
- const fromKey = keys.find((fromKey) => keysToRemove.indexOf(fromKey) > -1);
+ return acc;
+}, {});
+keysToAdd = Object.keys(collectedMessages).filter((key) => !prevMessages[key]);
+keysToRemove = Object.keys(prevMessages).filter((key) => !collectedMessages[key]).filter(isNotMarked);
+keysToUpdate = Object.entries(prevMessages).reduce((acc, [key, message]) =>
+ acc.concat(collectedMessages[key] && collectedMessages[key] !== message ? key : [])
+, []);
- if (fromKey) {
- keysToRename.push([fromKey, toKey]);
+// detect keys to rename, mutating keysToAdd and keysToRemove
+[].concat(keysToAdd).forEach((toKey) => {
+ const keys = prevMessagesMap[collectedMessages[toKey]] || [];
+ const fromKey = keys.find((fromKey) => keysToRemove.indexOf(fromKey) > -1);
- keysToRemove.splice(keysToRemove.indexOf(fromKey), 1);
- keysToAdd.splice(keysToAdd.indexOf(toKey), 1);
- }
- });
-} catch (err) {
- console.log(chalk.yellow(`Can not read ${defaultMessagesPath}. The new file will be created.`), err);
-}
+ if (fromKey) {
+ keysToRename.push([fromKey, toKey]);
+
+ keysToRemove.splice(keysToRemove.indexOf(fromKey), 1);
+ keysToAdd.splice(keysToAdd.indexOf(toKey), 1);
+ }
+});
if (!keysToAdd.length && !keysToRemove.length && !keysToUpdate.length && !keysToRename.length) {
return console.log(chalk.green('Everything is up to date!'));
@@ -142,13 +139,7 @@ function buildLocales() {
SUPPORTED_LANGS.map((lang) => {
const destPath = `${LANG_DIR}/${lang}.json`;
-
- let newMessages = {};
- try {
- newMessages = JSON.parse(fs.readFileSync(destPath, 'utf8'));
- } catch (err) {
- console.log(chalk.yellow(`Can not read ${destPath}. The new file will be created.`), err);
- }
+ const newMessages = readJSON(destPath);
keysToRename.forEach(([fromKey, toKey]) => {
newMessages[toKey] = newMessages[fromKey];
@@ -181,3 +172,13 @@ function buildLocales() {
fs.writeFileSync(destPath, JSON.stringify(sortedNewMessages, null, 4) + '\n');
});
}
+
+function readJSON(destPath) {
+ try {
+ return JSON.parse(fs.readFileSync(destPath, 'utf8'));
+ } catch (err) {
+ console.log(chalk.yellow(`Can not read ${destPath}. The new file will be created.`), `(${err.message})`);
+ }
+
+ return {};
+}
diff --git a/src/App.jsx b/src/App.jsx
new file mode 100644
index 0000000..043b61b
--- /dev/null
+++ b/src/App.jsx
@@ -0,0 +1,51 @@
+import { PropTypes } from 'react';
+
+import { IntlProvider, addLocaleData } from 'react-intl';
+
+import enLocaleData from 'react-intl/locale-data/en';
+import ruLocaleData from 'react-intl/locale-data/ru';
+import beLocaleData from 'react-intl/locale-data/be';
+import ukLocaleData from 'react-intl/locale-data/uk';
+
+// till we have not so many locales, we can require their data at once
+addLocaleData(enLocaleData);
+addLocaleData(ruLocaleData);
+addLocaleData(beLocaleData);
+addLocaleData(ukLocaleData);
+
+const SUPPORTED_LANGUAGES = ['ru', 'en', 'be', 'uk'];
+const DEFAULT_LANGUAGE = 'en';
+
+export default function App({type, payload = {}, debug = false}) {
+ let {locale} = payload;
+
+ if (!locale || SUPPORTED_LANGUAGES.indexOf(locale) === -1) {
+ locale = DEFAULT_LANGUAGE;
+ }
+
+ const messages = require(`i18n/${locale}.json`);
+ const Email = require(`emails/${type}/index`).default;
+
+ return (
+