== История и стрики (#1) == - HistoryEntry { ts, exerciseId, action: done|skip|snooze, actualReps? } персистится в app-state.json, лимит 10k записей (~3 года), trim oldest 10% - markDone/snooze/skip пишут в историю; markDone принимает optional actualReps - IPC: getHistory(sinceMs?), clearHistory(beforeTs?) + preload bindings - Renderer helpers (src/renderer/src/lib/history.ts): * dayKey(ts) — YYYY-MM-DD local * dailyReps(entries, exs, dayKey) — суммирует actualReps || planned * dailyRepsRange(entries, exs, days) — для heatmap, заполняет gaps нулями * currentStreak(entries) — consecutive days, today или yesterday (grace) - Dashboard теперь 4 hero-карточки: Today (повторов за день) / Streak (дней подряд) / Next / Tracking - Новый компонент HistoryHeatmap — GitHub-style 12-недельный календарь с 5 интенсивностями, локализованными подписями дней/месяцев == Тихие часы (#2) == - shared/types.ts: QuietHours { enabled, from, to, days[] } + isQuietAt() helper с правильной обработкой wrap-around окон (22:00→08:00) - DEFAULT_SETTINGS.quietHours = disabled, 22:00→08:00, все дни - main/scheduler.ts: проверка isQuietAt перед fire; deferred fires поднимаются после окончания окна - Settings UI: новая секция "Тихие часы" с toggle, time-pickers, day-of-week pills == Сделал частично (#3) == - ReminderApp: stepper [−][число][+] вокруг счётчика повторов - При adjusted (actualReps !== exercise.reps) число подсвечивается accent и появляется подпись "Засчитаем X из Y" - markDone передаёт actualReps только если юзер реально изменил — иначе undefined чтобы история фиксировала планируемое значение чисто == README.md (#4) == - Описание, фичи, скриншоты (TODO-плейсхолдер), установка, dev-команды, архитектура, тесты, stack, ссылка на RELEASING.md - Бэйджи version / tests / platform == i18n == - ~14 новых ключей × 2 языка: dashboard.stat.today_done, streak, settings.quiet.* (3 row'а), reminder.partial == Тесты — 51 (было 33) == - shared/quiet-hours.test.ts (5): disabled, same-day, wrap-around, day filtering, zero-length - renderer/lib/history.test.ts (13): dayKey, dailyReps (planned vs actual vs ignore non-done), currentStreak (empty, today gap, consecutive, yesterday grace, multi-entry same day), dailyRepsRange Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
96 lines
2.8 KiB
JSON
96 lines
2.8 KiB
JSON
{
|
|
"name": "laude",
|
|
"version": "0.5.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"
|
|
}
|
|
}
|
|
}
|