Commit Graph
6 Commits
Author SHA1 Message Date
Lucas WintherandClaude Opus 5 ccc5d369bd feat: track events that repeat daily, and each game's dailies
A login campaign is not one job with a deadline. It is twenty small jobs
on twenty separate deadlines, and a day you miss is gone whatever you do
afterwards — which a single "done" tick cannot express.

Repeating events now get a checklist: today's tick, a strip of every day
in the run showing what you got and what you missed, the streak, and how
many chances are left. Past days stay editable, because people tick up
later and a checklist you cannot correct stops being trusted after the
first mistake. Alongside it sits today's dailies — commissions, sanity,
daily training — one tick per game, keyed `dailies:<game>`, since no
source publishes those and they are the only thing on the page that
expires tonight rather than next patch.

Days roll at 04:00 server time per region, not midnight: finishing at
02:00 is still yesterday, and a naive UTC date would tick the wrong box
for four hours every night.

Dailiness is read off what the source published — a login event type, or
"daily"/"check-in"/"7-day" wording — never from a game's habits or an
event's length. That adds no schema field, so the feed contract and every
event ID are untouched. An unannounced end yields a tick count, not a
checklist of invented length, and a tick is never removed except by the
reader, including ticks outside the window the feed now claims: a source
quietly moving a date must not erase a fortnight's streak that exists
nowhere else.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 21:18:22 +02:00
Lucas WintherandClaude Opus 5 2f7e5bdf79 feat: replace the completions store with per-event progress
Membership in a set can only say "done", so "started" was inexpressible.
Progress carries a status instead, plus an optional effort estimate and a
note.

The old completions key is read once to seed status: "done", and is never
written to or deleted. Someone who last opened the app six months ago still
has their marks under it, these live only in the browser, and nothing else
holds a copy to restore from.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 01:49:53 +02:00
Lucas WintherandClaude Opus 5 71bff72ee9 feat: let readers ignore events they don't care about
Ignoring is not completing. "Done" keeps an event visible and counted;
"not interested" removes it from both views, which is the entire point.

Completions and ignores are the same shape and want the same guarantees, so
they now share one mark-set implementation — union merge on import, never a
removal, since nothing else holds a copy. Both ride in the export file.

Ignored events stay recoverable: the count and a reveal toggle appear in
settings once there is something to reveal.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 01:18:11 +02:00
Lucas WintherandClaude Opus 5 ad45b52c84 feat: add Arknights: Endfield, and stop passing off requirements as summaries
Endfield was previously written off as undatable. That was wrong: a first
pass only inspected its Duration rows (all "Permanently Available") and its
year-less version grid, and missed an "Event | Schedule & Summary" table
whose cells read "Period: 08/09/26 - 08/30/26 During the event...". Two real
events, with a year.

Adds MM/DD/YY range parsing for that shape. Month-first ordering is not
assumed lightly — Endfield's own version grid reads 01/22, 04/17, 07/16 for
versions 1.0, 1.2 and 1.4, chronological only if the month comes first.

Also stops presenting unlock conditions as descriptions. Several templates
put "Reach Union Level 8" where a blurb would go; filling the summary slot
with text that never says what the event is is worse than leaving it empty.
Wuthering Waves correctly drops to zero summaries as a result.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 01:07:39 +02:00
Lucas WintherandClaude Opus 5 107179acfa feat: ask which games you play on first run
A calendar full of games you don't play is worse than an empty one — it
buries the thing you came for.

Nothing is preselected; the button stays disabled until a game is picked,
which is clearer than guessing and hoping the reader notices. The choice is
stored as hiddenGames, the inverse, so a game added later shows up by
default rather than staying invisible.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:39:42 +02:00
Lucas WintherandClaude Opus 5 ac165f0df7 feat: add local-only completion and preference state
Completions and prefs live in localStorage and never reach the server —
there is no account and nothing to log into. Reads never throw, so a corrupt
value costs a preference rather than the whole screen.

Import merges and never removes: a completion present on either side stays
completed, because nothing else holds a copy to restore from.

The feed client refuses a schemaVersion it does not know rather than
guessing at unfamiliar fields.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-15 00:28:45 +02:00