diff --git a/src/components/settings/app.tsx b/src/components/settings/app.tsx index a5c6f68..9ceec93 100644 --- a/src/components/settings/app.tsx +++ b/src/components/settings/app.tsx @@ -139,6 +139,7 @@ class AppTab extends React.Component { { key: "sv", text: "Svenska" }, { key: "tr", text: "Türkçe" }, { key: "uk", text: "Українська" }, + { key: "ru", text: "Русский" }, { key: "ko", text: "한글" }, { key: "ja", text: "日本語" }, { key: "zh-CN", text: "中文(简体)" }, diff --git a/src/scripts/i18n/README.md b/src/scripts/i18n/README.md index 5cf0889..18d0301 100644 --- a/src/scripts/i18n/README.md +++ b/src/scripts/i18n/README.md @@ -19,5 +19,6 @@ Currently, Fluent Reader supports the following languages. | it | Italiano | [@andrewasd](https://github.com/andrewasd) | | pt-BR | Português do Brasil | [@fabianski7](https://github.com/fabianski7) | | ko | 한글 | [@1drive](https://github.com/1drive) | +| ru | Russian | [@nxblnd](https://github.com/nxblnd) | Refer to the repo of [react-intl-universal](https://github.com/alibaba/react-intl-universal) to get started on internationalization. diff --git a/src/scripts/i18n/_locales.ts b/src/scripts/i18n/_locales.ts index 187ca82..229b6a2 100644 --- a/src/scripts/i18n/_locales.ts +++ b/src/scripts/i18n/_locales.ts @@ -10,6 +10,7 @@ import sv from "./sv.json" import tr from "./tr.json" import it from "./it.json" import uk from "./uk.json" +import ru from "./ru.json" import pt_BR from "./pt-BR.json" import fi_FI from "./fi-FI.json" import ko from "./ko.json" @@ -27,6 +28,7 @@ const locales = { "tr": tr, "it": it, "uk": uk, + "ru": ru, "pt-BR": pt_BR, "fi-FI": fi_FI, "ko": ko, diff --git a/src/scripts/i18n/ru.json b/src/scripts/i18n/ru.json new file mode 100644 index 0000000..64f53cd --- /dev/null +++ b/src/scripts/i18n/ru.json @@ -0,0 +1,241 @@ +{ + "allArticles": "Все статьи", + "add": "Добавить", + "create": "Создать", + "icon": "Иконка", + "name": "Название", + "openExternal": "Открыть внешней программой", + "emptyName": "Это поле не может быть пустым.", + "emptyField": "Это поле не может быть пустым.", + "edit": "Редактировать", + "delete": "Удалить", + "followSystem": "Как в системе", + "more": "Ещё", + "close": "Закрыть", + "search": "Поиск", + "loadMore": "Загрузить ещё", + "dangerButton": "Подтвердить {action}?", + "confirmMarkAll": "Вы действительно хотите отметить все статьи на этой странице прочитанными?", + "confirm": "Подтвердить", + "cancel": "Отмена", + "default": "По умолчанию", + "time": { + "now": "сейчас", + "m": "м", + "h": "ч", + "d": "д", + "minute": "{m, plural, =1 {# минута} other {# минут}}", + "hour": "{h, plural, =1 {# час} other {# часов}}", + "day": "{d, plural, =1 {# день} other {# дней}}" + }, + "log": { + "empty": "Нет уведомлений", + "fetchFailure": "Не удалось загрузить из источника \"{name}\".", + "fetchSuccess": "Успешно {count, plural, =1 {получена # статья} other {получены # статей}}.", + "networkError": "Ошибка сети.", + "parseError": "Возникла ошибка при разборе XML.", + "syncFailure": "Не удалось синхронизировать с сервисом" + }, + "nav": { + "menu": "Меню", + "refresh": "Обновить", + "markAllRead": "Отметить всё прочитанным", + "notifications": "Уведомления", + "view": "Вид", + "settings": "Настройки", + "minimize": "Свернуть", + "maximize": "Развернуть" + }, + "menu": { + "close": "Закрыть меню", + "subscriptions": "Подписки" + }, + "article": { + "error": "Не удалось загрузить статью.", + "reload": "Перезагрузить?", + "empty": "Нет статей", + "untitled": "(Без названия)", + "hide": "Спрятать статью", + "unhide": "Показать статью", + "markRead": "Отметить как прочитанное", + "markUnread": "Отметить как непрочитанное", + "markAbove": "Отметить выше как прочитанное", + "markBelow": "Отметить ниже как прочитанное", + "star": "В избранное", + "unstar": "Убрать из избранного", + "fontSize": "Размер шрифта", + "loadWebpage": "Загрузить веб-страницу", + "loadFull": "Загрузить полное содержимое", + "notify": "Уведомить, если получено в фоновом режиме", + "dontNotify": "Не уведомлять", + "textDir": "Направление текста", + "LTR": "Слева направо", + "RTL": "Справа налево", + "Vertical": "Вертикально", + "font": "Шрифт" + }, + "context": { + "share": "Поделиться", + "read": "Читать", + "copyTitle": "Копировать заголовок", + "copyURL": "Копировать ссылку", + "copy": "Копировать", + "search": "Искать \"{text}\" в {engine}", + "view": "Вид", + "cardView": "Карточки", + "listView": "Список", + "magazineView": "Журнал", + "compactView": "Компактный", + "filter": "Фильтры", + "unreadOnly": "Только непрочитанные", + "starredOnly": "Только избранные", + "fullSearch": "Поиск по всему тексту", + "showHidden": "Показывать скрытые", + "manageSources": "Управление источниками", + "saveImageAs": "Сохранить изображение как …", + "copyImage": "Копировать изображение", + "copyImageURL": "Копировать ссылку на изображение", + "caseSensitive": "С учётом регистра", + "showCover": "Показать обложку", + "showSnippet": "Показать отрывок", + "fadeRead": "Высветлять прочитанные статьи" + }, + "searchEngine": { + "name": "Поисковая система", + "google": "Google", + "bing": "Bing", + "baidu": "Baidu", + "duckduckgo": "DuckDuckGo" + }, + "settings": { + "writeError": "Произошла ошибка при записи файла.", + "name": "Настройки", + "fetching": "Обновление источников. Пожалуйста, подождите.", + "exit": "Выйти из настроек", + "sources": "Источники", + "grouping": "Группы", + "rules": "Правила", + "service": "Сервисы", + "app": "Предпочтения", + "about": "О программе", + "version": "Версия", + "shortcuts": "Сочетания клавиш", + "openSource": "Открытый исходный код", + "feedback": "Обратная связь" + }, + "sources": { + "serviceWarning": "Импортированные или добавленные здесь источники не будут синхронизированы с Вашим сервисом.", + "serviceManaged": "Этот источник управляется Вашим сервисом.", + "untitled": "Источник", + "errorAdd": "Возникла ошибка при добавлении источника.", + "errorParse": "Возникла ошибка при разборе OPML файла.", + "errorParseHint": "Пожалуйста, удостоверьтесь что файл не повреждён и использует кодировку UTF-8.", + "errorImport": "Ошибка импорта {count, plural, =1 {# источника} other {# источников}}.", + "exist": "Этот источник уже существует.", + "opmlFile": "OPML файл", + "name": "Название источника", + "editName": "Изменить название", + "fetchFrequency": "Ограничение частоты обновлений", + "unlimited": "Без ограничений", + "openTarget": "Метод открытия статей по умолчанию", + "delete": "Удалить источник", + "add": "Добавить источник", + "import": "Импорт", + "export": "Экспорт", + "rssText": "Полный текст RSS", + "loadWebpage": "Загрузить веб-страницу", + "inputUrl": "Введите URL", + "badIcon": "Недопустимая иконка", + "badUrl": "Недопустимый URL", + "deleteWarning": "Источник и все сохранённые статьи будут удалены.", + "selected": "Выберите источник", + "selectedMulti": "Выберите несколько источников" + }, + "groups": { + "exist": "Эта группа уже существует.", + "type": "Тип", + "group": "Группа", + "source": "Источник", + "capacity": "Ёмкость", + "exitGroup": "Назад к группам", + "deleteSource": "Удалить из группы", + "sourceHint": "Перетаскивайте источники для изменения порядка.", + "create": "Создать группу", + "selectedGroup": "Выбранная группа", + "selectedSource": "Выбранный источник", + "enterName": "Введите название", + "editName": "Изменить название", + "deleteGroup": "Удалить группу", + "chooseGroup": "Выбрать группу", + "addToGroup": "Добавить в …", + "groupHint": "Сделайте двойной щелчок по группе для редактирования источников. Перетаскивайте для изменения порядка." + }, + "rules": { + "intro": "Автоматически отмечать статьи или отправлять уведомления с помощью регулярных выражений.", + "help": "Узнать больше", + "source": "Источник", + "selectSource": "Выбрать источник", + "new": "Новое правило", + "if": "Если", + "then": "То", + "title": "Название", + "content": "Содержимое", + "fullSearch": "Название или содержимое", + "creator": "Автор", + "match": "совпадает", + "notMatch": "не совпадает", + "regex": "Регулярное выражение", + "badRegex": "Недопустимое регулярное выражение.", + "action": "Действия", + "selectAction": "Выберите действия", + "hint": "Правила применяются по порядку. Перетащите для изменения порядка.", + "test": "Проверить правила" + }, + "service": { + "intro": "Синхронизация между устройствами с помощью RSS сервисов.", + "select": "Выберите сервис", + "suggest": "Предложить новый сервис", + "overwriteWarning": "Локальные источники будут удалены если они существуют в сервисе.", + "groupsWarning": "Группы не синхронизируются автоматически через сервис.", + "rateLimitWarning": "Чтобы избежать ограничения частоты запросов, Вам нужно создать свой ключ API.", + "removeAd": "Убрать рекламу", + "endpoint": "Endpoint", + "username": "Имя пользователя", + "password": "Пароль", + "unchanged": "Без изменений", + "fetchLimit": "Ограничение синхронизации", + "fetchLimitNum": "{count, plural, =1 {# последняя статья} other {# последних статей}}", + "importGroups": "Импортировать группы", + "failure": "Нет подключения к сервису", + "failureHint": "Please check the service configuration or network status.", + "fetchUnlimited": "Без ограничений (не рекомендуется)", + "exportToLite": "Экспорт в Fluent Reader Lite" + }, + "app": { + "cleanup": "Очистка", + "cache": "Очистить кэш", + "cacheSize": "Закэшировано {size} данных", + "deleteChoices": "Удалить статьи старше … дней", + "confirmDelete": "Удалить", + "daysAgo": "{days, plural, =1 {# дня} other {# дней}} назад", + "deleteAll": "Удалить все статьи", + "calculatingSize": "Вычисление размера…", + "itemSize": "Статьями занято примерно {size} пространства локального хранилища", + "confirmImport": "Вы действительно хотите импортировать данные из файла резервной копии? Все текущие данные будут удалены.", + "data": "Данные приложения", + "backup": "Резервная копия", + "restore": "Восстановление", + "frData": "Данные Fluent Reader", + "language": "Язык интерфейса", + "theme": "Тема", + "lightTheme": "Светлая", + "darkTheme": "Тёмная", + "enableProxy": "Включить прокси", + "badUrl": "Недопустимый URL", + "pac": "PAC Адрес", + "setPac": "Установить PAC", + "pacHint": "Для Socks прокси рекомендуется, чтобы PAC возвращал \"SOCKS5\" для DNS на стороне прокси. Выключение прокси требует перезапуска.", + "fetchInterval": "Интервал автоматического обновления", + "never": "Никогда" + } +}