feat(gamification): today count + sparkline on Tasks header

Badge renders when today's count > 0. Sparkline renders when the
setting is enabled and any of the last 7 days has a completion.
Wrapped in a narrow aria-live region so increments announce without
re-reading the rest of the header.

Fix: converted todayCount from $derived module export to a getter
function (Svelte 5 derived_invalid_export constraint).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 20:45:47 +01:00
parent 54ddd41265
commit 3cadbb0f82
2 changed files with 34 additions and 5 deletions

View File

@@ -21,10 +21,13 @@ const DAYS = 7;
export const recentCompletions = $state<DailyCompletionCount[]>([]);
// Reactive derived value. Svelte 5 template consumers read it as a
// plain property (no parens) and it recomputes when recentCompletions
// changes.
export const todayCount = $derived(recentCompletions.at(-1)?.count ?? 0);
// Reactive getter. Svelte 5 does not allow exporting $derived at module
// level ("derived_invalid_export"), so we expose a function instead.
// Template consumers call todayCount() in reactive contexts and it
// recomputes when recentCompletions changes.
export function todayCount(): number {
return recentCompletions.at(-1)?.count ?? 0;
}
export async function refresh(): Promise<void> {
if (!hasTauriRuntime()) return;