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 1 – Jun 7Week 13 of 27
Sun, Jun 7
- fix(category): correct semantically wrong icons and visually indistinct accent colors (#31)lifelong-habit-app09:49
Sat, Jun 6
No commits.
Fri, Jun 5
- feat(category): make accentColor theme-aware with light/dark variants (#31)lifelong-habit-app15:19
- fix: round polygon stroke joins on CategoryRadarChart data polygons (#31)lifelong-habit-app15:05
- fix: resolve icon component in HabitHeatmapCard header instead of rendering raw icon_key string (#31)lifelong-habit-app14:50
- fix(intensity): remove 100% capping as snowball habit intensity_percent can be > 100%lifelong-habit-app09:26
- fix(unlog): add logged_at to IN_PROGRESS downgrade paths in useUnlogHabit (#27)lifelong-habit-app09:09
- feat(schema): add habit_config_history audit table (#27)lifelong-habit-app09:02
- fix(logged_at): advance logged_at on every log mutation (#27)lifelong-habit-app08:53
- fix(intensity): clamp intensity_percent to 100 at display layer only (#27)lifelong-habit-app08:33
- fix(intensity): remove write-time cap from SNOWBALL intensity_percent (#27)lifelong-habit-app06:23
- fix(sessions): delete ghost daily_log rows when all sessions are removed (#27)lifelong-habit-app02:05
Thu, Jun 4
No commits.
Wed, Jun 3
- chore: ignore the entire android directory for EAS build so it takes app.config.js into account and change app name for preview variant (#28)lifelong-habit-app14:23
- revert(android): remove product flavors, restore single variant buildlifelong-habit-app14:08
- chore(android): add product flavors for dev/preview/production with distinct package IDs and app names (#28)lifelong-habit-app13:36
- chore(android): set app_name to "Lifelong Habit (Dev)" for local dev buildlifelong-habit-app06:54
- fix(dependencies): update react-native-reanimated to ^4.4.0 and react-native-worklets to ^0.9.1 to solve dependency conflictslifelong-habit-app06:26
- chore: add .easignore to reduce file size (it was > 300mb and EAS doesn't accept such big files #28)lifelong-habit-app06:26
- fix(dashboard): replace absoluteFillObject with absoluteFill that's compatible with new deps (Expo SDK 56 #25)lifelong-habit-app03:45
- fix(AuthBackground): replace removed absoluteFillObject with absoluteFill (RN 0.85 breaking change #25)lifelong-habit-app01:37
- fix(android): update compileSdkVersion to 36 and ndkVersion to 27.1.12297006 (#25)lifelong-habit-app01:36
Tue, Jun 2
- feat: include Android project structure and config to repo (#25)lifelong-habit-app23:50
- chore(.gitignore): remove generated native folders from ignore list (#25)lifelong-habit-app23:49
- fix(android): pin Gradle to 8.13, Kotlin to 2.1.20, restore missing ext SDK versions (#25)lifelong-habit-app23:47
- feat: integrate Sentry for error trackinglifelong-habit-app05:16
- fix: replace BottomTabBarButtonProps with inline prop type in HapticTablifelong-habit-app02:36
- fix: migrate @react-navigation imports to expo-router/react-navigationlifelong-habit-app02:35
- fix(PickerSearchBar): remove borderTopWidth since tab bar already provides the separator (#22)lifelong-habit-app00:48
- chore: bump devDependencieslifelong-habit-app00:45
- refactor: remove unused local database and schema fileslifelong-habit-app00:41
- fix: replace StyleSheet.absoluteFillObject with explicit position propslifelong-habit-app00:40
- fix(app.config.js): add @sentry/react-native plugin and format splash screen configlifelong-habit-app00:39
- chore: bump expo dependencieslifelong-habit-app00:38
- fix(dependencies): update expo-router to version 56.2.8lifelong-habit-app00:17
Mon, Jun 1
- fix(SwatchRow): remove resolved contrast TODO — HabitColor.contrast is non-nullable (#22)lifelong-habit-app23:47
- refactor(color-habit-picker): normalize all imports to @/ aliaslifelong-habit-app23:43
- feat(slider-shim): restore LinearGradient track using expo-linear-gradient (#22)lifelong-habit-app23:38
- fix(color-habit-picker): replace placeholder icons and remove dead header buttonlifelong-habit-app23:25
- refactor(colorHabitPicker): move PickerSearchBar above panelWrap and below tabs (#22)lifelong-habit-app12:17
- perf(progress): add getItemLayout to eliminate fast-scroll blank space (#20)lifelong-habit-app11:12
- perf(progress): pass shared cardGrid to HabitHeatmapCard and tune FlatList window (#20)lifelong-habit-app10:42
- perf(progress): fix query waterfall, O(N²) metrics loop, streak scan, and per-card buildGrid (#20)lifelong-habit-app10:29
- fix(progress): count IN_PROGRESS toward category consistency score in daily and weekly views #19lifelong-habit-app10:13
- fix(dashboard): remove estimatedItemSize from FlashList as it's not in installed flash-list version (#16)lifelong-habit-app09:56
- perf(dashboard): virtualize habit list with FlashList above 15 habits, memo HabitCardRenderer with Set-aware comparator (#16)lifelong-habit-app09:56
- chore(deps): bump postcss in the npm_and_yarn group across 1 directorylifelong-habit-app05:47
- chore(dependencies): update expo version to ~54.0.35lifelong-habit-app05:44
- chore: remove unused dependencies from package.json and ran npm audit fixlifelong-habit-app05:38
- chore: add Dependabot config filelifelong-habit-app05:31
- fix(grove): extract writeTimeElapsedOnly service, fix manual session add/delete for Grove, fix + button guard on time-log screen, add missing query invalidations (#17)lifelong-habit-app05:25
- fix(snowball): debounce stepper flush to prevent dropped rapid taps (#15)lifelong-habit-app00:11