Надёжность main-процесса: - глобальные uncaughtException/unhandledRejection (лог + flushNow) - safeHandle/safeOn вокруг всех IPC-хендлеров (не падаем молча, generic-ошибка наружу) - таймаут 4s на tasklist, Atomics.wait вместо busy-spin на exit-записи - единый log.error для фоновых сбоев вместо console.error/тишины Тесты (178 -> 203): meeting-detect, scheduler-gating, store (миграции/карантин/cap). UI/UX: - prefers-reduced-motion через MotionConfig + CSS media-блок - Spinner/Skeleton примитивы, loading-состояния вместо пустых заглушек - aria-live анонсы достижений и выполнения (useAnnounce) - оформленные пустые состояния, клавиатура в меню ExerciseCard Лицензия: проприетарный LICENSE + правка README/CLAUDE.md, счётчик тестов. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
107 lines
7.2 KiB
Markdown
107 lines
7.2 KiB
Markdown
# Laude — Exercise Reminder
|
||
|
||
Windows desktop приложение, которое напоминает делать упражнения во время работы за компьютером. Опционально подключается к Dota 2 и после каждого матча превращает статистику (смерти, убийства, ассисты) в количество повторений.
|
||
|
||
[](https://xn--90adajar8af4h.xn--p1ai/git/AnRil/laude/releases/latest)
|
||
[]()
|
||
[]()
|
||
|
||
## Что внутри
|
||
|
||
- **Гибкие напоминания** — любое количество упражнений, интервал от минуты до часов, разные иконки.
|
||
- **История и стрики** — heatmap-календарь активности, ежедневный счётчик, серия дней подряд.
|
||
- **Тихие часы** — окно времени когда напоминания подавляются (например `22:00 → 08:00`), с выбором дней недели.
|
||
- **Сделал частично** — степпер `−/+` в окне напоминания: если ты сделал 5 из 10, в историю запишется честное число.
|
||
- **Игровая интеграция (Dota 2)** — Game State Integration читает статистику матча, после Победа/Поражение показывает экран с «причитающимися» повторениями (например `10 смертей × 3 = 30 приседаний`).
|
||
- **Apple-style интерфейс** — Plus Jakarta Sans + Bricolage Grotesque, iOS-палитра, vibrancy sidebar, spring-анимации, светлая/тёмная/системная тема.
|
||
- **Два языка** — русский и английский, переключение мгновенное.
|
||
- **Auto-update** — приложение само скачивает новые версии из фиксированного `update-channel` (проверка каждый час, силент-ретрай при сетевых сбоях).
|
||
|
||
## Скриншоты
|
||
|
||
> _TODO: вставить screenshots Dashboard / Reminder / Match summary (light + dark)._
|
||
|
||
## Установка
|
||
|
||
Скачай последний `Exercise-Reminder-Setup-X.Y.Z.exe` со страницы релизов и запусти. Установщик:
|
||
|
||
- Создаёт ярлык на рабочем столе и в Пуске
|
||
- Сохраняет настройки в `%APPDATA%\Exercise Reminder\`
|
||
- При запуске поверх существующей инсталляции — обновляет, настройки сохраняются
|
||
|
||
Windows SmartScreen может предупредить «не доверено» — приложение не подписано code-signing сертификатом. Нажми `Подробнее` → `Выполнить в любом случае`.
|
||
|
||
## Разработка
|
||
|
||
```bash
|
||
git clone https://xn--90adajar8af4h.xn--p1ai/git/AnRil/laude.git
|
||
cd laude
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
Полезные команды:
|
||
|
||
```bash
|
||
npm run typecheck # tsc по main + renderer
|
||
npm run test # vitest в watch-режиме
|
||
npm run test:run # vitest один раз (для CI)
|
||
npm run build # сборка без NSIS
|
||
npm run dist # сборка + NSIS-инсталлятор → release/
|
||
npm run release -- -Bump patch # bump версии + tag + push + upload в Gitea
|
||
```
|
||
|
||
Документ `RELEASING.md` описывает процесс выпуска новых версий.
|
||
|
||
## Архитектура
|
||
|
||
- **Electron 33** — multi-process: main (Node/scheduler/GSI) + preload (contextBridge) + renderer (React)
|
||
- **Renderer** — React 18, TypeScript 5, Vite 5, Tailwind 3, framer-motion, react-router, zustand
|
||
- **Persistence** — единственный JSON-файл `%APPDATA%\Exercise Reminder\app-state.json` (debounced writes)
|
||
- **IPC** — типизированные каналы через `src/shared/ipc.ts`, обёрнуто preload-ом
|
||
- **i18n** — самописная микро-система: `src/renderer/src/i18n/dict.ts` (плоский словарь ~200 ключей × 2 языка) + хук `useT()`
|
||
- **Auto-update** — `electron-updater` с `generic` provider, манифест `latest.yml` лежит в Gitea release attachments
|
||
- **GSI Dota 2** — локальный HTTP-сервер слушает GameStateIntegration коллбэки от Steam, парсит match-end events
|
||
|
||
## Тесты
|
||
|
||
```
|
||
src/main/validate.test.ts (68)
|
||
src/renderer/src/lib/history.test.ts (31)
|
||
src/renderer/src/i18n/i18n.test.ts (15)
|
||
src/renderer/src/lib/format.test.ts (14)
|
||
src/main/games/vdf.test.ts (11)
|
||
src/main/store.test.ts (10)
|
||
src/renderer/src/lib/achievements.test.ts (10)
|
||
src/shared/release-notes.test.ts (9)
|
||
src/main/scheduler.test.ts (8)
|
||
src/main/meeting-detect.test.ts (7)
|
||
src/shared/quiet-hours.test.ts (7)
|
||
src/main/adaptive.test.ts (6)
|
||
src/shared/types.test.ts (4)
|
||
src/renderer/src/lib/icon-choices.test.ts (3)
|
||
──────────────────────────────────────────
|
||
203 ✓
|
||
```
|
||
|
||
Покрытие: IPC-валидация, persistence (миграции, карантин битого JSON, history cap), scheduler-гейтинг (тихие часы, ВКС-пауза, daily-goal), детект ВКС, история/стрики (DST), тихие часы (wrap), парсер VDF для Steam-конфигов, достижения, i18n с плюрализацией RU/EN, дефолты shared-типов.
|
||
|
||
## Лицензия
|
||
|
||
Проприетарная — все права защищены. Личное некоммерческое использование
|
||
разрешено; копирование, распространение, модификация и реверс-инжиниринг — без
|
||
письменного разрешения автора. Полный текст — в файле [LICENSE](LICENSE). По
|
||
вопросам использования за рамками лицензии открой issue в репозитории.
|
||
|
||
## Stack
|
||
|
||
- [Electron](https://www.electronjs.org/) · runtime
|
||
- [electron-vite](https://electron-vite.org/) · build
|
||
- [React](https://react.dev/) + [TypeScript](https://www.typescriptlang.org/)
|
||
- [Tailwind CSS](https://tailwindcss.com/) · стили
|
||
- [framer-motion](https://motion.dev/) · анимации
|
||
- [lucide-react](https://lucide.dev/) · иконки
|
||
- [electron-updater](https://www.electron.build/auto-update) · auto-update
|
||
- [Vitest](https://vitest.dev/) · тесты
|
||
- Шрифты: [Plus Jakarta Sans](https://fonts.google.com/specimen/Plus+Jakarta+Sans), [Bricolage Grotesque](https://fonts.google.com/specimen/Bricolage+Grotesque), [JetBrains Mono](https://fonts.google.com/specimen/JetBrains+Mono)
|