== История и стрики (#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>
59 lines
1.6 KiB
TypeScript
59 lines
1.6 KiB
TypeScript
export const IPC = {
|
|
getState: 'state:get',
|
|
addExercise: 'exercise:add',
|
|
updateExercise: 'exercise:update',
|
|
deleteExercise: 'exercise:delete',
|
|
toggleExercise: 'exercise:toggle',
|
|
markDone: 'exercise:markDone',
|
|
snooze: 'exercise:snooze',
|
|
skip: 'exercise:skip',
|
|
|
|
updateSettings: 'settings:update',
|
|
getAccentColor: 'system:accentColor',
|
|
getOsTheme: 'system:osTheme',
|
|
|
|
pauseAll: 'app:pauseAll',
|
|
resumeAll: 'app:resumeAll',
|
|
quit: 'app:quit',
|
|
minimizeMain: 'window:minimize',
|
|
closeMain: 'window:close',
|
|
hideMain: 'window:hide',
|
|
|
|
reminderClose: 'reminder:close',
|
|
|
|
// Games
|
|
gamesList: 'games:list',
|
|
gameInstall: 'games:install',
|
|
gameUninstall: 'games:uninstall',
|
|
gameToggle: 'games:toggle',
|
|
gameOpenLaunchOptions: 'games:openLaunchOptions',
|
|
|
|
// Challenges
|
|
addChallenge: 'challenge:add',
|
|
updateChallenge: 'challenge:update',
|
|
deleteChallenge: 'challenge:delete',
|
|
toggleChallenge: 'challenge:toggle',
|
|
markChallengeDone: 'challenge:markDone',
|
|
closeMatchSummary: 'matchSummary:close',
|
|
|
|
// Auto-updater
|
|
updaterStatus: 'updater:status',
|
|
updaterCheck: 'updater:check',
|
|
updaterDownload: 'updater:download',
|
|
updaterInstall: 'updater:install',
|
|
|
|
// History
|
|
getHistory: 'history:get',
|
|
clearHistory: 'history:clear',
|
|
|
|
// events from main → renderer
|
|
evtTick: 'evt:tick',
|
|
evtFire: 'evt:fire',
|
|
evtMatchEnd: 'evt:matchEnd',
|
|
evtStateChanged: 'evt:stateChanged',
|
|
evtThemeChanged: 'evt:themeChanged',
|
|
evtAccentChanged: 'evt:accentChanged',
|
|
evtGamesChanged: 'evt:gamesChanged',
|
|
evtUpdaterStatus: 'evt:updaterStatus'
|
|
} as const
|