Commit cb749f6a authored by valzav's avatar valzav
Browse files

add more languages support (wip)

parent 2b6919c1
......@@ -98,9 +98,10 @@ function runApp(initial_state) {
if (!window.Intl) {
require.ensure(['intl/dist/Intl'], (require) => {
window.IntlPolyfill = window.Intl = require('intl/dist/Intl')
require('intl/locale-data/jsonp/en-US.js')
require('intl/locale-data/jsonp/es.js')
window.IntlPolyfill = window.Intl = require('intl/dist/Intl');
require('intl/locale-data/jsonp/en-US.js');
require('intl/locale-data/jsonp/es.js');
require('intl/locale-data/jsonp/ru.js');
Iso.bootstrap(runApp);
}, "IntlBundle");
}
......
......@@ -3,14 +3,21 @@ import {connect} from 'react-redux'
import {IntlProvider, addLocaleData} from 'react-intl';
import en from 'react-intl/locale-data/en';
import es from 'react-intl/locale-data/es';
import ru from 'react-intl/locale-data/ru';
import {DEFAULT_LANGUAGE} from 'app/client_config';
import tt from 'counterpart';
addLocaleData([...en, ...es]);
addLocaleData([...en, ...es, ...ru]);
tt.registerTranslations('en', require('counterpart/locales/en'));
tt.registerTranslations('en', require('app/locales/en.json'));
tt.registerTranslations('es', require('app/locales/es.json'));
tt.registerTranslations('ru', require('counterpart/locales/ru'));
tt.registerTranslations('ru', require('app/locales/ru.json'));
if (process.env.NODE_ENV === 'production') {
tt.setFallbackLocale('en');
}
class Translator extends React.Component {
render() {
......@@ -30,7 +37,7 @@ class Translator extends React.Component {
export default connect(
(state, ownProps) => {
const locale = 'en'; // temporary, real i18n support will be added later
const locale = state.app.getIn(['user_preferences', 'locale']);
return {...ownProps, locale};
}
)(Translator);
......
......@@ -204,6 +204,11 @@
"zero": "Sin Respuestas",
"one": "%(count)s Respuesta",
"other": "%(count)s Respuestas"
},
"post_key_warning": {
"confirm": "You are about to publish a STEEM private key or master password. You will probably lose control of the associated account and all its funds.",
"warning": "Legitimate users, including employees of Steemit Inc., will never ask you for a private key or master password.",
"checkbox": "I understand"
}
},
"navigation": {
......
......@@ -67,7 +67,7 @@
"re": "RE",
"re_to": "RE: %(topic)s",
"recent_password": "Недавний пароль",
"receive": "Получить ",
"receive": "Получено ",
"remove": "Удалить",
"remove_vote": "Убрать голос",
"replied_to": "ответил %(account)s",
......@@ -76,6 +76,8 @@
"reply_count": {
"zero": "нет ответов",
"one": "1 ответ",
"few": "%(count)s ответа",
"many": "%(count)s ответов",
"other": "%(count)s ответов"
},
"reputation": "Репутация",
......@@ -96,11 +98,10 @@
"submit": "Отправить",
"power_up": "Усилить силу голоса",
"submit_a_story": "Добавить пост",
"tag": эг",
"tag": ег",
"to": " к ",
"topics": "Топики",
"all_tags": "All tags",
"transfer": "Передать ",
"transfer": "Перевод ",
"trending_topics": "Популярное",
"type": "Тип",
"unfollow": "Отписаться",
......@@ -198,12 +199,21 @@
"views": {
"zero": "Нет просмотров",
"one": "%(count)s просмотр",
"few": "%(count)s просмотра",
"many": "%(count)s просмотров",
"other": "%(count)s просмотров"
},
"responses": {
"zero": "Нет ответов",
"one": "%(count)s ответ",
"few": "%(count)s ответа",
"many": "%(count)s ответов",
"other": "%(count)s ответов"
},
"post_key_warning": {
"confirm": "Вы собираетесь опубликовать ваш приватный ключ или мастер-пароль, это может привести к потере вашего акканта и всех средств на нем.",
"warning": "Если кто-то попросил вас опубликовать или показать ваш приватный ключ, это возможно злоумышленник, который пытается украсть ваши токены.",
"checkbox": "Я понял"
}
},
"navigation": {
......@@ -240,7 +250,7 @@
"shorten_title": "Сократите заголовок",
"exceeds_maximum_length": "Превышает максимальную длину (%(maxKb)sKB)",
"including_the_category": "(включая категорию «%(rootCategory)s»)",
"use_limited_amount_of_tags": "У вас %(tagsLength)s тэгов, включая %(includingCategory)s. Пожалуйста, используйте не более 5 в посте и категории.",
"use_limited_amount_of_tags": "У вас %(tagsLength)s тегов, включая %(includingCategory)s. Пожалуйста, используйте не более 5 в посте и категории.",
"are_you_sure_you_want_to_clear_this_form": "Вы уверены, что вы хотите очистить эту форму?",
"uploading": "Загрузка",
"draft_saved": "Черновик сохранен.",
......@@ -260,13 +270,13 @@
"markdown_not_supported": "Markdown здесь не поддерживается"
},
"category_selector_jsx": {
"tag_your_story": "Добавь тэги (до 5 штук), первый тэг станет основной категорией.",
"select_a_tag": "Выбрать тэг",
"tag_your_story": "Добавь теги (до 5 штук), первый тег станет основной категорией.",
"select_a_tag": "Выбрать тег",
"maximum_tag_length_is_24_characters": "Максимальная длина категории 24 знака",
"use_limited_amount_of_categories": "Пожалуйста, используйте только %(amount)s категории",
"use_only_lowercase_letters": "Используйте только символы нижнего регистра",
"use_one_dash": "Используйте только одно тире",
"use_spaces_to_separate_tags": "Используйте пробел чтобы разделить тэги",
"use_spaces_to_separate_tags": "Используйте пробел чтобы разделить теги",
"use_only_allowed_characters": "Используйте только строчные буквы, цифры и одно тире",
"must_start_with_a_letter": "Должно начинаться с буквы",
"must_end_with_a_letter_or_number": "Должно заканчиваться с буквы или номера"
......@@ -337,23 +347,27 @@
"explore_trending_articles": "Посмотреть статьи, набирающие популярность",
"read_the_quick_start_guide": "Прочтите краткое руководство",
"browse_the_faq": "Просмотреть ЧаВО",
"users_curation_rewards": "Кураторские вознаграждения %(name)s",
"users_permissions": "Разрешения %(name)s",
"followers": "Подписчики",
"this_is_users_reputations_score_it_is_based_on_history_of_votes": "Это репутация %(name)s.\n\nРепутация рассчитывается на основе истории полученных голосов и используется для сокрытия низкокачественного контента.",
"follower_count": {
"zero": "Нет подписчиков",
"one": "1 подписчик",
"few": "%(count)s подписчика",
"many": "%(count)s подписчиков",
"other": "%(count)s подписчиков"
},
"followed_count": {
"zero": "Ни на кого не подписан",
"one": "1 подписок",
"few": "%(count)s подписки",
"many": "%(count)s подписок",
"other": "%(count)s подписок"
},
"post_count": {
"zero": "Постов нет",
"one": "1 пост",
"few": "%(count)s поста",
"many": "%(count)s постов",
"other": "%(count)s постов"
}
},
......@@ -391,6 +405,8 @@
"and_more": "и %(count)s больше",
"votes_plural": {
"one": "%(count)s голоса",
"few": "%(count)s голоса",
"many": "%(count)s голосов",
"other": "%(count)s голосов"
}
},
......@@ -400,6 +416,8 @@
"you_have_votes_remaining": {
"zero": "У Вас не осталось голосов",
"one": "У Вас остался 1 голос",
"few": "У Вас осталось %(count)s голоса",
"many": "У Вас осталось %(count)s голосов",
"other": "У Вас осталось %(count)s голосов"
},
"you_can_vote_for_maximum_of_witnesses": "Вы можете голосовать максимум за 30 делегатов",
......@@ -418,11 +436,15 @@
"response_count_tooltip": {
"zero": "ответов пока нет. Нажмите чтобы ответить.",
"one": "1 ответ. Нажмите чтобы ответить.",
"few": "%(count)s ответа. Нажмите чтобы ответить.",
"many": "%(count)s ответов. Нажмите чтобы ответить.",
"other": "%(count)s ответов. Нажмите чтобы ответить."
},
"vote_count": {
"zero": "нет голосов",
"one": "1 голос",
"few": "%(count)s голоса",
"many": "%(count)s голосов",
"other": "%(count)s голосов"
}
},
......@@ -551,8 +573,8 @@
"keep_me_logged_in": "Оставить меня залогиненным",
"amazing_community": "удивительное сообщество",
"to_comment_and_reward_others": " комментировать и вознаграждать других.",
"sign_up_now_to_earn": "Зарегистрируйтесь сейчас, чтобы заработать ",
"free_money": "ЛЕГКИЕ ДЕНЬГИ!",
"signup_button": "Зарегистрируйтесь",
"signup_button_emphasis": " сейчас!",
"returning_users": "Вернувшиеся пользователи: ",
"join_our": "Присоединяйтесь к нашему"
},
......
......@@ -6,17 +6,34 @@ import universalRender from '../shared/UniversalRender';
import models from 'db/models';
import secureRandom from 'secure-random';
import ErrorPage from 'server/server-error';
import fs from 'fs';
const path = require('path');
const ROOT = path.join(__dirname, '../..');
const DB_RECONNECT_TIMEOUT = process.env.NODE_ENV === 'development' ? 1000 * 60 * 60 : 1000 * 60 * 10;
function getSupportedLocales() {
const locales = [];
const files = fs.readdirSync(path.join(ROOT, 'src/app/locales'));
for (const filename of files) {
const match_res = filename.match(/(\w+)\.json?$/)
if (match_res) locales.push(match_res[1]);
}
return locales;
}
const supported_locales = getSupportedLocales();
async function appRender(ctx) {
const store = {};
try {
let login_challenge = ctx.session.login_challenge;
let userPreferences = {};
let locale = ctx.getLocaleFromHeader();
if (locale) locale = locale.substring(0, 2);
const locale_is_supported = supported_locales.find(l => l === locale);
if (!locale_is_supported) locale = 'en';
let userPreferences = {locale};
if (!login_challenge) {
login_challenge = secureRandom.randomBuffer(16).toString('hex');
ctx.session.login_challenge = login_challenge;
......
......@@ -30,6 +30,7 @@ import config from 'config';
import { routeRegex } from 'app/ResolveRoute';
import secureRandom from 'secure-random';
import userIllegalContent from 'app/utils/userIllegalContent';
import koaLocale from 'koa-locale';
if(cluster.isMaster)
console.log('application server starting, please wait.');
......@@ -61,6 +62,7 @@ csrf(app);
app.use(mount(grant));
app.use(flash({ key: 'flash' }));
koaLocale(app);
function convertEntriesToArrays(obj) {
return Object.keys(obj).reduce((result, key) => {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment