Craft
Main quests and fun experiments. Code, art, and community 
My main project now is Lifelong Habit, a habit app for people who want to focus on long-term habit formation and detailed insights. Most of the things I’ve made and played around with circle back to self-development, with some funsies and whimsies here and there. Open to work and collaborations!~ 
Jun 22 – Jun 28Week 10 of 27
Sun, Jun 28
- perf(dashboard): lift runningHabitIds default to module-level constantlifelong-habit-app22:51
- perf(queries): set staleTime: Infinity on useHabitStatusLogslifelong-habit-app22:51
- fix(mutations): invalidate consistency cache on habit creationlifelong-habit-app22:50
- perf(queries): set staleTime: 30_000 on useTodayLogslifelong-habit-app22:49
- perf(queries): set staleTime: Infinity on useConsistencylifelong-habit-app22:49
- fix(bento): optimistically update all_habit_logs_by_date on checkbox taplifelong-habit-app22:44
- fix(theme): remove whitespace text nodes from AppThemeProvider JSXlifelong-habit-app16:04
- perf(progress): keep overview sections mounted across tab switcheslifelong-habit-app15:42
- feat(progress): implement usePrefetchAdjacentYears hook for snappier year navigationlifelong-habit-app15:41
- feat(progress): add year chevron navigation to yearly viewlifelong-habit-app15:27
- feat(progress): replace yearly picker with chevron navigationlifelong-habit-app15:17
- chore(progress): implement YearlyOverviewSection with summary bar, radar chart, and category breakdown (copied the wrong file, my bad)lifelong-habit-app15:04
- fix(progress): dedupe logs by date in useYearlyOverview summary countlifelong-habit-app14:50
- feat(progress): add YearlyOverviewSection with summary, radar, and category breakdownlifelong-habit-app14:47
- refactor(settings): make GroupedRow.onPress optional and add disabled statelifelong-habit-app14:32
- refactor(settings): replace all Alert.alert with in-app modalslifelong-habit-app14:27
- feat(settings): add discard guard to TimeOfDayScreenlifelong-habit-app14:22
- perf(theme): convert useTheme from hook to Contextlifelong-habit-app13:48
- fix(progress): virtualize weekly and monthly habit rowslifelong-habit-app13:28
- perf(quarterly): virtualize habit rows with scrollEnabled=false FlatListlifelong-habit-app13:04
- perf(progress): gate useQuarterlyOverview behind viewMode via LazyQuarterlySectionlifelong-habit-app13:04
- fix(progress): exclude paused and archived habits from all progress viewslifelong-habit-app12:50
- feat(progress): add quarterly overview viewlifelong-habit-app08:44
- feat(AddSessionScreen): block end time in the future when logging for todaylifelong-habit-app07:53
- feat(progress): add monthly calendar viewlifelong-habit-app07:44
- feat(progress): navigate to habit details from progress rowslifelong-habit-app07:05
- refactor(progress): consolidate shared date helpers and category constantslifelong-habit-app06:43
- fix(habitFormStyles): center timePickerSpinner content horizontallylifelong-habit-app06:27
- refactor(TrailingTimestampText): replace shadow-height technique with onTextLayoutlifelong-habit-app04:48
- fix(TrailingTimestampText): always anchor timestamp to bottom-rightlifelong-habit-app03:52
- fix(journal): reduce timestamp text size to rowMeta (bodyXs is too small)lifelong-habit-app02:24
- fix(journal): adjust timestamp positioning againlifelong-habit-app02:24
- fix(journal): measure timestamp width correctlylifelong-habit-app01:47
Sat, Jun 27
- fix(journal): restore bubble shrink-wrap for inline timestampslifelong-habit-app23:04
- fix(journal): restore inline timestamps for short entrieslifelong-habit-app15:24
- refactor(journal): extract screen logic into focused componentslifelong-habit-app14:07
- fix: progress bar left-to-right fill via onLayout and prevent rapid-tap revert with mutationInFlightReflifelong-habit-app12:41
- feat(optimistic-ui): instant feedback for Snowball stepper and Ladder rung interactionslifelong-habit-app12:39
- fix(TrailingTimestampText): make single-line detection robust on Androidlifelong-habit-app11:39
- fix(journal): restore bubble shrink-wrap behaviorlifelong-habit-app10:57
- fix(journal): prevent timestamp overlap and expand bubble widthlifelong-habit-app10:33
- fix(TrailingTimestampText): correct timestamp placement logic for inline renderinglifelong-habit-app10:22
- fix(screenLayout): add insets.bottom to subScreenContainerPaddinglifelong-habit-app09:42
- refactor: update text componentslifelong-habit-app09:04
Fri, Jun 26
- feat(TrailingTimestampText): add dynamic trailing timestamp for habit journallifelong-habit-app14:23
- refactor(RecentlyDeletedScreen): improve alert copy textlifelong-habit-app14:22
- chore: remove AddSessionSheet component (dead code)lifelong-habit-app14:21
- refactor(themeRegistry): add subtle card field on ThemePalette interfacelifelong-habit-app14:21
- refactor(auth components): adjust margin and placeholder text for input fieldslifelong-habit-app14:21
- refactor(dashboard): adjust component styleslifelong-habit-app14:20
- refactor(alerts): update alert text to include Discord community supportlifelong-habit-app14:13
Thu, Jun 25
- refactor(validateHabit): update bento wording from component to partlifelong-habit-app23:33
- fix(ladder): align tooltip/error copy with existing "level" terminologylifelong-habit-app23:18
- refactor: improve alert and text messages for clarity across various componentslifelong-habit-app22:56
- refactor: update description for ArchetypeSelector and pause messages for hookslifelong-habit-app14:53
- feat(journal): WhatsApp-style trailing timestamp on journal bubbleslifelong-habit-app10:42
- feat(journal): multi-day journal thread with cursor paginationlifelong-habit-app10:05
- fix(AddSessionScreen): suppress validation warning while any picker field is openlifelong-habit-app08:25
- feat(TimeSpinnerPicker): add onEditingChange callback to signal active text editlifelong-habit-app08:24
- fix(TimeSpinnerPicker): clamp out-of-range typed values instead of silently revertinglifelong-habit-app08:19
- feat(TimeSpinnerPicker): add tap-to-edit inline input for hour and minute fieldslifelong-habit-app08:18
- feat(toast): show habit name in pause confirmation toastlifelong-habit-app07:42
- feat(toast): show habit name in pause confirmation toastlifelong-habit-app07:22
- fix(toast): preserve toast payload across navigation, user-dismiss onlylifelong-habit-app06:55
- fix(toast): remove duplicate ToastProvider from (tabs)/_layoutlifelong-habit-app06:52
- fix(toast): move NavigationToastGate outside Stack to sibling positionlifelong-habit-app06:51
- fix(toast): scope ToastProvider to (tabs) subtreelifelong-habit-app06:14
- feat(toast): scope overlay visibility to (tabs) group onlylifelong-habit-app06:05
- refactor: extract TimeSpinnerPicker shared component from HabitTimePicker and AddSessionlifelong-habit-app04:08
- fix: move AM/PM toggle inline next to MM field in AddSessionlifelong-habit-app03:18
- fix: center HabitTimePicker spinner and stack AddSession time inputs verticallylifelong-habit-app03:14
- fix: use time_display_24h in session display and manual session input so the time format follows user optionlifelong-habit-app02:40
Wed, Jun 24
- fix(grove): pass isPastDate not strictMode as isLockIn to journal routelifelong-habit-app23:10
- fix(grove): auto-complete past-date Grove logs on journal/session/stepper writelifelong-habit-app22:52
- chore(HabitTimeLogScreen): remove dead codelifelong-habit-app22:50
- refactor(ArchetypeSelector UX): replace em dash to parentheses #41lifelong-habit-app13:53
- fix(GroveForm UI): fix toggle color (no longer transparent), adjust text size and text #73lifelong-habit-app13:50
- refactor(TimeOfDayScreen): move the toggle for 12-hour and 24-hour options abovelifelong-habit-app13:45
- fix(grove): use lower-level hooks that accept null to fix conditional hook errorlifelong-habit-app12:13
- fix (grove): fix grove completion from detail sheet for all track types [#80, part of #73]lifelong-habit-app10:41
- Add timeElapsedSeconds to SelectedDateLogResult [#80, part of #73]lifelong-habit-app10:40
- fix (grove): Allow Grove completion from detail sheet when data exists [#80, part of #73]lifelong-habit-app10:33
- feat(progress): include uncategorized habits in category breakdownlifelong-habit-app08:58
- refactor(dashboard): expose schedule via DashboardData, fix O(N²) todayLogs lookup [#70, part of #35]lifelong-habit-app08:26
- feat(dashboard): schedule-aware two-line daily summary banner (Scopes B + C) [#70, part of #35]lifelong-habit-app08:23
- chore: change migration name to follow the standard (with -010 suffix)lifelong-habit-app07:41
- fix(settings): eliminate maskEmail duplication, useEffect race, select() overhead [#78, part of #75]lifelong-habit-app07:05
- feat(settings): add Edit Name screen and wire display_name to ProfileHeader [#75, part of #70]lifelong-habit-app00:01
Tue, Jun 23
- refactor(HabitTimePicker): update time caption [#41 copy audit]lifelong-habit-app16:49
- feat: capture display_name at signup and Google OAuth, fix guest name fallback [#75, part of #70]lifelong-habit-app13:09
- refactor(OverviewSummaryBar): update label from "Not completed" to "Not Started" and adjust styleslifelong-habit-app13:05
- refactor: correct spelling of "Customize Fields" and adjust padding in HabitSheetFieldsScreen [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app12:52
- style: correct spelling of "Customize Fields" in comments [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app12:52
- refactor(habitSheetFieldConfig): correct spelling and update field hints [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app12:51
- fix(HabitSheetFieldsScreen): add caption-to-button gap and tighten field row padding [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app12:50
- feat(HabitSheetFieldsScreen): add reset to default button and tighten field row spacing [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app12:23
- feat(HabitSheetFieldsScreen): add reset to default button [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app12:02
- refactor(habitSheetFieldConfig): reorder DEFAULT_SHEET_FIELDS to match UX grouping [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app11:25
- refactor(habit-sheet-fields): delegate route to feature component, remove duplicate implementation [#66, part of DASHBOARD #35 and SETTINGS #51]lifelong-habit-app11:05
- fix(HabitSheetFieldsScreen): use colors.accent for switch to match GroveForm pattern [#66, part of DASHBOARD #35 and settings #51]lifelong-habit-app11:04
Mon, Jun 22
No commits.