Routines are the feature apps like Fabulous are built around: a morning run of water, stretch, journal, done in order with a guided “next step”. Building them in PaceStreak took one rule: a routine adds no new kind of progress.
What a routine stores
A name, an emoji, a time of day, and an ordered list of habit ids. That’s the whole table. No routine streak, no routine XP, no “routine completed” event.
Stepping through a routine in the app ticks each habit exactly as tapping it on Today would. That means the same API call, the same offline queue, the same streak, the same XP cap. A routine is a faster way to do things the product already counts, so it can’t become a way to count them twice.
Two consequences fell out for free:
- Archive or delete a habit and it simply drops out of any routine. The stored list isn’t rewritten; the API filters it against live habits.
- “Resume” starts at the first step not yet done today, because “done today” already lives on the habits.
The focus timer stores a timestamp
Minutes habits (practice, study, reading time) now have a focus timer.
The obvious build counts seconds with setInterval. It’s also wrong on
phones: a locked screen or a background tab throttles or kills the
interval, and the count quietly loses minutes.
So the timer stores when it started, plus minutes banked from earlier
runs, in local storage. The display is now − started + banked,
recomputed each second while visible. Lock the phone for twenty minutes
and the timer is right when you come back. Close the tab and it’s still
running when you reopen it.
Stop adds the whole minutes to today through the same “add to a day” call the + button uses. Under a minute adds nothing, and says so.
AlzyWelzy
Building PaceStreak. GitHub
Related
ProductHabits on chosen days, and pausing just one
A habit can now be planned for specific weekdays, and paused on its own while everything else carries on. Both had to mean the same thing to the streak, the reminders and the badge.
2 min
ProductA coach made of rules
The new daily coach is a few if-statements over your own data. Why that beats a generated paragraph, and why the app shows only the notes its existing cards don't already cover.
1 min
ProductImporting another app's history, and refusing 03/04
Switching habit apps shouldn't cost a streak. How PaceStreak reads Loop's export and generic CSVs, why only year-first dates are accepted, and why an import never overwrites a day.
2 min