feat(routines): record which games' built-ins are on, and who was asked

Both prefs are absent unless the reader answers, so built-ins are opt-in
for every install, old ones included. The question is asked only about a
game on screen, and only once. A built-in the reader made their own
stays hidden while the copy exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5.5 committed 2026-10-13 14:07:31 +02:00
1 parent 8aa820e2c0
commit bfd79c295e
3 files changed
+87 -1

No files matched your search

+17
View File
@@ -184,6 +184,14 @@ export interface Prefs {
regionConfirmed: boolean;
/** False until the reader has picked their games on first run. */
onboarded: boolean;
/**
* Games whose built-in weekly tasks the reader turned on (routines.ts, PRD
* F17). Absent means none: built-ins are opt-in, so an install from before
* they existed gets none rather than all.
*/
routineGames?: LaneId[] | undefined;
/** Games already asked "track its weekly tasks?", so the question is asked once. */
routinesAsked?: LaneId[] | undefined;
}
export function defaults(): Prefs {
@@ -313,6 +321,15 @@ export function restorePrefsValue(incoming: unknown): Prefs {
}
}
// Built-in tasks: string arrays, or absent.
for (const key of ["routineGames", "routinesAsked"] as const) {
const value: unknown = result[key];
if (value === undefined) continue;
result[key] = Array.isArray(value)
? value.filter((g): g is LaneId => typeof g === "string")
: undefined;
}
// focusGame
if (result.focusGame !== null && typeof result.focusGame !== "string") {
result.focusGame = null;