feat(dashboard): add momentum and game debt

This commit is contained in:
Codex
2026-06-07 12:08:21 +07:00
parent baf96ca0fa
commit 5ed80d7122
10 changed files with 789 additions and 33 deletions

View File

@@ -21,6 +21,60 @@ export type ReleaseNoteItem = {
export type ReleaseNotes = Record<Language, ReleaseNoteItem[]>
export const RELEASE_NOTES: Record<string, ReleaseNotes> = {
'0.6.3': {
ru: [
{
title: 'Новый главный экран “Не Залипай”',
detail:
'Сегодня теперь показывает не только план, но и недельный ритм, уровень и игровые долги.',
tag: 'new'
},
{
title: 'Мини-челленджи недели',
detail:
'5 дней без нуля, 1000 повторов, “сегодня не ноль” и закрытые катки считаются автоматически.',
tag: 'new'
},
{
title: 'Игровой долг после каток',
detail:
'На Dashboard видно, сколько Dota-долгов закрыто сегодня и за неделю.',
tag: 'new'
},
{
title: 'Мягкая система уровней',
detail:
'XP считается из повторов, активных дней и закрытых игровых челленджей.',
tag: 'new'
}
],
en: [
{
title: 'New “Ne Zalipay” Today screen',
detail:
'Today now shows the day plan, weekly rhythm, level and game debts.',
tag: 'new'
},
{
title: 'Weekly mini-challenges',
detail:
'5 non-zero days, 1000 reps, “today is not zero” and closed matches are tracked automatically.',
tag: 'new'
},
{
title: 'Game debt after matches',
detail:
'Dashboard shows how many Dota debts were closed today and this week.',
tag: 'new'
},
{
title: 'Soft level system',
detail:
'XP comes from reps, active days and completed game challenges.',
tag: 'new'
}
]
},
'0.5.8': {
ru: [
{
@@ -204,14 +258,12 @@ export const RELEASE_NOTES: Record<string, ReleaseNotes> = {
en: [
{
title: 'Reminder categories',
detail:
'Beyond exercises — hydration, eye rest (20-20-20), posture.',
detail: 'Beyond exercises — hydration, eye rest (20-20-20), posture.',
tag: 'new'
},
{
title: 'Voice prompts',
detail:
'Speaks the exercise name and count. Toggle in Settings.',
detail: 'Speaks the exercise name and count. Toggle in Settings.',
tag: 'new'
},
{
@@ -255,7 +307,8 @@ export const RELEASE_NOTES: Record<string, ReleaseNotes> = {
ru: [
{
title: 'Sandbox для окон',
detail: 'Окна изолированы на уровне OS — даже RCE в рендере не достанет main.',
detail:
'Окна изолированы на уровне OS — даже RCE в рендере не достанет main.',
tag: 'security'
},
{
@@ -282,7 +335,8 @@ export const RELEASE_NOTES: Record<string, ReleaseNotes> = {
en: [
{
title: 'Window sandbox',
detail: 'OS-level isolation — even RCE in the renderer cannot reach main.',
detail:
'OS-level isolation — even RCE in the renderer cannot reach main.',
tag: 'security'
},
{
@@ -311,24 +365,28 @@ export const RELEASE_NOTES: Record<string, ReleaseNotes> = {
ru: [
{
title: 'Фоновое скачивание апдейта',
detail: 'Можно уйти на Dashboard и заниматься — апдейт качается в фоне.',
detail:
'Можно уйти на Dashboard и заниматься — апдейт качается в фоне.',
tag: 'new'
},
{
title: 'Моментальный рестарт',
detail: 'Кнопка «Рестарт» — ~1-2 сек до открытия новой версии, без диалогов NSIS.',
detail:
'Кнопка «Рестарт» — ~1-2 сек до открытия новой версии, без диалогов NSIS.',
tag: 'new'
}
],
en: [
{
title: 'Background update download',
detail: 'You can go to Dashboard and work — the update keeps downloading.',
detail:
'You can go to Dashboard and work — the update keeps downloading.',
tag: 'new'
},
{
title: 'Instant restart',
detail: 'Restart button — ~1-2 sec to the new version, no NSIS dialogs.',
detail:
'Restart button — ~1-2 sec to the new version, no NSIS dialogs.',
tag: 'new'
}
]
@@ -352,7 +410,9 @@ export function unseenVersions(
// явный «What's new» из Settings.
return all.filter((v) => v === current)
}
return all.filter((v) => compareSemver(v, lastSeen) > 0 && compareSemver(v, current) <= 0)
return all.filter(
(v) => compareSemver(v, lastSeen) > 0 && compareSemver(v, current) <= 0
)
}
function parseSemver(v: string): [number, number, number] {