Files
laude/package.json
AnRil 973339ca62
Some checks failed
CI / Typecheck + Tests (push) Has been cancelled
CI / Build (Windows) (push) Has been cancelled
Release / Build installer + publish release (push) Has been cancelled
feat(i18n): bilingual UI (Russian + English) + language selector
Все UI-строки приложения переведены и переключаются на лету через
Settings → Язык интерфейса.

== i18n архитектура ==
- src/renderer/src/i18n/dict.ts — плоский словарь ru/en с ~190 ключами,
  поддержка интерполяции {var} и плюрализации
- src/renderer/src/i18n/index.ts — useT() React hook + чистые
  translate/translateN функции (для ReminderApp вне store context)
- Settings.language: 'ru' | 'en', default 'ru'
- Изменение языка применяется немедленно через Zustand reactive update

== Что переведено ==
- Sidebar nav + slogan + status
- Titlebar window controls (aria-labels)
- Dashboard: hero, 3 stat-карточки (Активных / До следующего /
  Трекинг матчей), Paused banner, empty state
- Exercises: hero, секции (активные / выключенные), row meta, empty
- Challenges: hero, formula subtitle, warning, row format
  «{stat} × {mult} → {exercise}», empty
- Games: hero, status badges (Live/Ready/Queued/Installed/Not found),
  queued/no_user banners, dev panel
- Settings: все секции + новый Language selector
- UpdaterCard: все состояния (checking/available/downloading/
  downloaded/error/idle) с интерполяцией версии и MB/s
- ReminderApp: kicker «Время тренировки», reps подпись, snooze label
  с динамическими минутами, кнопки done/skip
- Match summary: победа/поражение, плюрализация «N челлендж/-а/-ей»
  vs «N challenge/-s»
- Format helpers (formatCountdown, formatInterval) — теперь принимают
  Language параметр

== Локалезависимая дата ==
Dashboard hero показывает today в текущей локали:
  ru-RU → "воскресенье, 17 мая"
  en-US → "Sunday, May 17"

== STAT_LABELS bilingual ==
- shared/types.ts: STAT_LABELS_EN + statLabel(stat, lang) helper
- ChallengeResult получил поле stat?: GameStat (для resolve на стороне
  renderer'а с актуальным языком, вместо baked-in label)
- main/games/registry.ts кладёт stat в результат

== Тесты ==
- src/renderer/src/i18n/i18n.test.ts: 10 кейсов
  * translate: lookup, fallback, interpolation, multi-var, lang fallback
  * translateN: ru plural rules (1/21/101 → one; 2-4 → few; 0/5-20 → many)
    и en (1 → one, else → many)
- Всего 33 теста зелёные

== Известное ограничение ==
SAMPLE_EXERCISES (5-6 русских "Приседания / Отжимания / ...") остаются
русскими — это seed данных на первый запуск. Английский юзер сразу
переключит язык и сможет переименовать вручную. Делать seed-per-locale
оверкилл — слишком много кода ради малого.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 23:28:34 +07:00

96 lines
2.8 KiB
JSON

{
"name": "laude",
"version": "0.4.0",
"description": "Exercise reminder — Windows desktop app",
"main": "out/main/index.js",
"author": "AnRil",
"private": true,
"scripts": {
"dev": "electron-vite dev",
"build": "electron-vite build",
"preview": "electron-vite preview",
"typecheck:node": "tsc --noEmit -p tsconfig.node.json",
"typecheck:web": "tsc --noEmit -p tsconfig.web.json",
"typecheck": "npm run typecheck:node && npm run typecheck:web",
"test": "vitest",
"test:run": "vitest run",
"dist": "electron-vite build && electron-builder --win --x64",
"dist:dir": "electron-vite build && electron-builder --win --x64 --dir",
"publish": "electron-vite build && electron-builder --win --x64 --publish always",
"release": "powershell -ExecutionPolicy Bypass -File scripts/release.ps1",
"gen:icons": "powershell -ExecutionPolicy Bypass -File scripts/gen-icons.ps1"
},
"dependencies": {
"electron-updater": "^6.8.3",
"framer-motion": "^11.11.17",
"lucide-react": "^0.460.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.28.0",
"zustand": "^5.0.1"
},
"devDependencies": {
"@types/node": "^22.19.19",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"electron": "^33.2.0",
"electron-builder": "^25.1.8",
"electron-vite": "^2.3.0",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.15",
"typescript": "^5.6.3",
"vite": "^5.4.11",
"vitest": "^4.1.6"
},
"build": {
"appId": "com.anril.exercise-reminder",
"productName": "Exercise Reminder",
"directories": {
"output": "release",
"buildResources": "resources"
},
"files": [
"out/**/*",
"resources/**/*"
],
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
],
"icon": "resources/icon.ico"
},
"nsis": {
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": true,
"allowElevation": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"shortcutName": "Exercise Reminder",
"uninstallDisplayName": "Exercise Reminder",
"installerLanguages": [
"ru_RU",
"en_US"
],
"displayLanguageSelector": true,
"menuCategory": false,
"runAfterFinish": true,
"deleteAppDataOnUninstall": false,
"differentialPackage": true,
"artifactName": "Exercise-Reminder-Setup-${version}.${ext}"
},
"publish": {
"provider": "generic",
"url": "https://xn--90adajar8af4h.xn--p1ai/git/AnRil/laude/releases/download/v${version}",
"channel": "latest"
}
}
}