185 lines
16 KiB
TypeScript
185 lines
16 KiB
TypeScript
// Russian primary copy. To add a string:
|
||
// 1. add the key + RU value here (this file is the canonical key list — `en.ts`
|
||
// and the `StringKey` type derive from it),
|
||
// 2. add the same key + EN value in `en.ts`,
|
||
// 3. consume via `t('key', { var: 'x' })` in components.
|
||
// Interpolation uses `{name}` placeholders resolved against the second arg.
|
||
|
||
export const RU = {
|
||
// --- Status pill ---------------------------------------------------------
|
||
'status.checking': 'Проверка статуса…',
|
||
'status.disconnected': 'WhatsApp не привязан',
|
||
'status.connected-as': 'Привязан как {handle}',
|
||
|
||
// --- Action cards ----------------------------------------------------------
|
||
// User flow по сути такой же, как в Telegram: сабмит номера → код. Отличие:
|
||
// в TG код вводится в виджет, в WA — в само приложение WhatsApp. Имя кнопки
|
||
// одинаковое для consistency между виджетами.
|
||
'card.login.name': 'Войти по номеру',
|
||
'card.login.desc': 'Ввести номер и получить 8-символьный код для WhatsApp',
|
||
'card.login-qr.name': 'Войти по QR-коду',
|
||
'card.login-qr.desc': 'Отсканировать QR из мобильного приложения WhatsApp',
|
||
'card.refresh.name': 'Обновить статус',
|
||
'card.refresh.desc': 'Перепроверить, привязан ли WhatsApp',
|
||
'card.refresh.in-flight': 'Проверяю…',
|
||
'card.logout.name': 'Выйти из WhatsApp',
|
||
'card.logout.desc': 'Завершить сеанс на этом аккаунте',
|
||
'card.logout.confirm-prompt': 'Точно выйти?',
|
||
'card.logout.confirm-yes': 'Выйти',
|
||
'card.logout.confirm-no': 'Отмена',
|
||
|
||
// --- About panel -----------------------------------------------------------
|
||
// WhatsApp-only Meta-ToS risk disclosure is folded into the About modal as
|
||
// an amber callout at the top of the body. The About card itself carries
|
||
// `command-card warn` (amber border + amber name) and a triangle warning
|
||
// glyph in the lead slot — instead of the info-circle TG / Discord use —
|
||
// so the «риски» half of the hybrid description («о работе и рисках») is
|
||
// visible at a glance before the user opens the modal. TG / Discord get
|
||
// the plain «вход, безопасность, исходный код» variant because they don't
|
||
// carry an account-loss risk in the same way (Telegram user ToS doesn't
|
||
// forbid third-party clients; Discord's restriction on self-bots lives in
|
||
// developer policies, not user ToS proper).
|
||
//
|
||
// ToS reference for the body: https://www.whatsapp.com/legal/terms-of-service
|
||
// section «Harm To WhatsApp Or Our Users» forbids «software or APIs that
|
||
// function substantially the same as our Services» and «accounts for our
|
||
// Services through unauthorized or automated means».
|
||
'card.about.name': 'Как работает WhatsApp-бот',
|
||
'card.about.desc': 'Информация о работе и рисках — нажмите, чтобы прочесть',
|
||
'warning.title': 'Важно знать до подключения WhatsApp',
|
||
'warning.body-1':
|
||
'Mautrix-whatsapp подключает ваш аккаунт через тот же механизм связанных устройств, что и WhatsApp Web. Технически это стандартный API — но в отличие от других мессенджеров, условия использования WhatsApp прямо запрещают подключение через сторонние клиенты, и Meta может заблокировать аккаунт за это.',
|
||
// Источник про запрет в ToS — даём юзеру возможность дойти до оригинала
|
||
// самому, не доверять нам на слово. Кликается потому что host-side iframe
|
||
// sandbox получил allow-popups (см. src/app/features/bots/BotWidgetEmbed.ts).
|
||
'warning.tos-label': 'Условия использования WhatsApp:',
|
||
'warning.tos-url': 'https://www.whatsapp.com/legal/terms-of-service',
|
||
'about.title': 'О боте WhatsApp',
|
||
'about.body-1':
|
||
'Этот бот подключает WhatsApp к Vojo. После входа личные чаты и группы из WhatsApp появятся в списке чатов Vojo, а ответы из приложения Vojo будут отправляться собеседникам как обычные сообщения в WhatsApp.',
|
||
'about.body-2':
|
||
'Для входа нужно мобильное приложение WhatsApp на телефоне с активным аккаунтом. Можно либо отсканировать QR-код через «Настройки → Связанные устройства → Привязка устройства», либо ввести 8-символьный код через «Настройки → Связанные устройства → Связать по номеру телефона».',
|
||
'about.body-3':
|
||
'Подключение работает через open-source мост mautrix-whatsapp. Он создаёт WhatsApp-сессию на сервере Vojo и использует её для связи WhatsApp с вашим аккаунтом Vojo: получает сообщения из WhatsApp и отправляет ваши ответы обратно. WhatsApp-аккаунт продолжит работать на телефоне как обычно — мост подключается параллельно, как ещё одно связанное устройство.',
|
||
'about.github-label': 'Исходный код моста открыт на GitHub:',
|
||
'about.github-url': 'https://github.com/mautrix/whatsapp',
|
||
'about.body-4':
|
||
'Отозвать доступ можно в любой момент — кнопкой «Выйти из WhatsApp» здесь, либо в самом WhatsApp через «Настройки → Связанные устройства → Выйти со всех устройств».',
|
||
'about.close': 'Закрыть',
|
||
'about.aria-close': 'Закрыть «О боте»',
|
||
|
||
// --- Phone form (pairing-code flow) -----------------------------------------
|
||
'auth-card.phone.title': 'Вход по номеру телефона',
|
||
'auth-card.phone.label': 'Номер телефона',
|
||
'auth-card.phone.placeholder': '+79991234567',
|
||
// Подсказка, объясняющая что произойдёт после сабмита: мост создаст
|
||
// 8-символьный код, который надо ввести в WhatsApp app. Пользователь
|
||
// должен понимать, что код не SMS-OTP, а pairing-token.
|
||
'auth-card.phone.hint':
|
||
'Введите номер с кодом страны. После этого WhatsApp создаст 8-символьный код — его нужно будет ввести в приложении.',
|
||
'auth-card.phone.submit': 'Получить код',
|
||
'auth-card.phone.cooldown': 'Повтор через {seconds} сек',
|
||
'auth-card.phone.invalid': 'Похоже, номер ещё не полный или введён с ошибкой.',
|
||
|
||
// --- Pairing-code panel --------------------------------------------------
|
||
'auth-card.pairing-code.title': 'Введите этот код в WhatsApp',
|
||
'auth-card.pairing-code.hint':
|
||
'Откройте WhatsApp на телефоне и введите этот код в форме «Связанные устройства → Связать по номеру телефона».',
|
||
'auth-card.pairing-code.aria': 'Код для входа в WhatsApp. Введите его в приложении на телефоне.',
|
||
'auth-card.pairing-code.countdown': 'На ввод осталось {minutes}:{seconds}',
|
||
'auth-card.pairing-code.expired': 'Окно входа истекло. Нажмите «Отмена» и попробуйте снова.',
|
||
'auth-card.pairing-code.step-1': 'Откройте WhatsApp на телефоне.',
|
||
'auth-card.pairing-code.step-2': 'Перейдите в «Настройки → Связанные устройства».',
|
||
'auth-card.pairing-code.step-3':
|
||
'Нажмите «Привязка устройства», затем «Связать по номеру телефона».',
|
||
'auth-card.pairing-code.step-4': 'Введите этот код и подтвердите вход на телефоне.',
|
||
'auth-card.pairing-code.copy': 'Скопировать код',
|
||
'auth-card.pairing-code.copied': 'Скопировано',
|
||
|
||
// --- Shared form chrome ------------------------------------------------
|
||
'auth-card.cancel': 'Отмена',
|
||
'auth-card.waiting-hint': 'Мост ещё думает… ответ может идти до 30 секунд.',
|
||
|
||
// --- QR panel ------------------------------------------------------------
|
||
'auth-card.qr.title': 'Вход по QR-коду',
|
||
'auth-card.qr.hint': 'Откройте WhatsApp на телефоне и отсканируйте этот QR-код.',
|
||
'auth-card.qr.preparing': 'Готовим QR-код…',
|
||
'auth-card.qr.aria': 'QR-код для входа в WhatsApp. Отсканируйте его телефоном.',
|
||
// Обратный отсчёт до серверного таймаута. Whatsmeow ротирует QR по
|
||
// расписанию 60 с + 5 × 20 с = 2 мин 40 с активного окна. Сам QR в панели
|
||
// всегда свежий (long-poll приносит новый на каждой ротации), отсчёт
|
||
// показывает оставшееся окно ВСЕГО входа.
|
||
'auth-card.qr.countdown': 'На сканирование осталось {minutes}:{seconds}',
|
||
'auth-card.qr.expired': 'Окно входа истекло. Нажмите «Отмена» и попробуйте снова.',
|
||
'auth-card.qr.step-1': 'Откройте WhatsApp на телефоне.',
|
||
'auth-card.qr.step-2': 'Перейдите в «Настройки → Связанные устройства».',
|
||
'auth-card.qr.step-3': 'Нажмите «Привязка устройства» и отсканируйте QR-код.',
|
||
|
||
// --- Global errors / notices ---------------------------------------------
|
||
'error.network': 'Нет связи с сервером. Проверьте интернет и попробуйте ещё раз.',
|
||
'error.auth':
|
||
'Не удалось подтвердить ваш аккаунт у моста. Обновите страницу; если не помогает — попробуйте позже.',
|
||
'error.not-logged-in':
|
||
'Сессия WhatsApp больше не активна. Вернитесь назад и привяжите аккаунт заново.',
|
||
'error.openid-blocked':
|
||
'Хост не выдал виджету разрешение на вход — в config.json у бота нет capability vojo.openid.',
|
||
'error.rate-limited': 'WhatsApp просит подождать: слишком много запросов кода. Попробуйте позже.',
|
||
'error.phone-invalid':
|
||
'WhatsApp не принял этот номер. Укажите его в международном формате и попробуйте снова.',
|
||
'error.multidevice':
|
||
'На телефоне не включён мультиустройственный режим WhatsApp. Обновите приложение WhatsApp и попробуйте снова.',
|
||
'error.client-outdated':
|
||
'Мост устарел, и WhatsApp отказывает ему в подключении. Сообщите администратору Vojo.',
|
||
'error.pair-failed': 'WhatsApp не подтвердил привязку. Начните вход заново.',
|
||
'error.login-timeout': 'Время входа истекло. Начните вход заново.',
|
||
'error.login-restart': 'Сессия входа потерялась. Начните вход заново.',
|
||
'error.too-many-logins': 'Достигнут лимит привязанных аккаунтов. Сначала выйдите из текущего.',
|
||
'error.generic': 'Что-то пошло не так: {reason}',
|
||
'notice.login-success': 'WhatsApp привязан! Чаты появятся в списке в течение минуты.',
|
||
'notice.logged-out': 'Сеанс WhatsApp завершён.',
|
||
|
||
// --- Contacts ------------------------------------------------------------
|
||
'card.contacts.name': 'Контакты',
|
||
'card.contacts.desc': 'Записная книжка WhatsApp: поиск по имени или номеру',
|
||
'contacts.back': 'Назад',
|
||
'contacts.search-placeholder': 'Имя или +номер…',
|
||
'contacts.hint':
|
||
'Это контакты вашей записной книжки WhatsApp. Выберите, с кем начать чат в Vojo, — остальные никуда не денутся.',
|
||
'contacts.loading': 'Загружаем контакты…',
|
||
'contacts.error': 'Не удалось загрузить контакты.',
|
||
'contacts.retry': 'Повторить',
|
||
'contacts.empty': 'В записной книжке WhatsApp пока пусто.',
|
||
'contacts.empty-filtered': 'Никого не нашли с таким именем.',
|
||
'contacts.start-chat': 'Начать чат',
|
||
'contacts.open-chat': 'Открыть чат',
|
||
'contacts.creating': 'Создаём чат…',
|
||
'contacts.opening': 'Открываем…',
|
||
'contacts.probe-check': 'Проверить {handle} в WhatsApp',
|
||
'contacts.probe-checking': 'Проверяем {handle}…',
|
||
'contacts.probe-not-found': '{handle} не найден в WhatsApp.',
|
||
'contacts.probe-found': 'Есть такой! Можно написать.',
|
||
'contacts.probe-self': 'Это ваш собственный номер.',
|
||
'contacts.refresh': 'Обновить список',
|
||
|
||
// --- Account tab -----------------------------------------------------------
|
||
'account.state-bad':
|
||
'Мост сообщает о проблеме с подключением: {reason}. Попробуйте выйти и привязать WhatsApp заново.',
|
||
// TRANSIENT_DISCONNECT — телефон давно не в сети / keepalive потерян
|
||
// (connector phoneping.go). Обычно чинится само, перепривязка не нужна.
|
||
'account.state-transient':
|
||
'Мост временно потерял связь с WhatsApp. Проверьте, что телефон в сети, — обычно подключение восстанавливается само.',
|
||
|
||
// --- Boot / config ---------------------------------------------------------
|
||
'boot.connecting': 'Подключение к мосту…',
|
||
'config.missing.title': 'Нужна настройка на сервере',
|
||
'config.missing.body':
|
||
'Виджет работает через API моста, но его адрес не задан в конфигурации (experience.provisioningUrl в config.json) или не выдано разрешение vojo.openid.',
|
||
'error.retry': 'Повторить',
|
||
|
||
// --- Bootstrap failure -------------------------------------------------
|
||
'bootstrap.failed': 'Виджет не запустился',
|
||
'bootstrap.missing-params': 'Отсутствуют обязательные параметры URL: {names}.',
|
||
'bootstrap.embedded-only': 'Эта страница предназначена для встраивания Vojo по маршруту {route}.',
|
||
} as const;
|
||
|
||
export type StringKey = keyof typeof RU;
|