Commit Graph
434 Commits
Author SHA1 Message Date
github-actions[bot] 3193360cf6 chore: update social cache [skip ci] 2026-02-05 14:42:58 +00:00
github-actions[bot] ab15305be5 chore: update social cache [skip ci] 2026-02-05 14:23:53 +00:00
Frank Gregor 169423c54c Chore: Update test count badge to 514 tests [skip ci] 2026-02-05 14:01:28 +00:00
phranck d82b68cd93 Merge pull request #74 from phranck/feature/render-performance-phase2
Feat: Render Performance Phase 2 — Cache Invalidation, Equatable Conformances & Debug Tooling
2026-02-05 14:59:32 +01:00
phranck ea3cb6974e Fix: grant push permissions to social cache workflow
Checkout with DASHBOARD_GITHUB_TOKEN PAT so git push succeeds.
Also add explicit contents: write permission at workflow level.
Fixes 403 'Permission denied to github-actions[bot]' error.
2026-02-05 14:53:15 +01:00
phranck 7e9243c6c3 Docs: finalize render performance phase 2 plan and update status files
Mark all plan checkboxes as completed. Update to-dos.md with phase 2
completion entry, new performance backlog items (TupleView Equatable,
_printChanges equivalent), and GH Actions workflow issue. Update
whats-next.md with current branch/PR/test state.
2026-02-05 14:52:21 +01:00
phranck 71f6e12a42 Docs: add Subtree Memoization section to RenderCycle.md
Document the EquatableView/RenderCache system in the DocC article:
- How .equatable() works (5-step cache lookup)
- Cache invalidation triggers (State change, environment change)
- When to use / not use .equatable() (decision guide with tables)
- Which types support Equatable conformance
- Debug logging via TUIKIT_DEBUG_RENDER=1
- Code example using FeatureBox from the example app

Also updates existing sections:
- Correct 'no subtree memoization' claim in 'What Is NOT Diffed'
- Add EquatableView to Renderable lists (Direct Rendering, View-Level Modifiers)
2026-02-05 14:49:58 +01:00
phranck 20547de056 Feat: apply .equatable() to static example app subtrees
Add Equatable conformance and .equatable() wrapper to extracted views:
- FeatureBox (MainMenuPage): title/subtitle comparison, 3 instances
- ContainerTypesRow (ContainersPage): property-free, always cache-hits
- SettingsAndAlignmentRow (ContainersPage): property-free, always cache-hits

These subtrees are purely palette-driven with no @State dependencies.
During Spinner/Pulse animation frames (25 FPS), the render cache skips
their entire subtree rendering — only the animated views re-render.
2026-02-05 14:47:31 +01:00
phranck 095c67e021 Refactor: decompose ContainersPage and MainMenuPage into smaller view structs
Extract static, state-free subtrees into standalone View structs to
prepare for .equatable() memoization in Phase 5:

- FeatureBox: extracted from MainMenuPage's private featureBox() method
- ContainerTypesRow: Card/Box/Panel examples from ContainersPage
- SettingsAndAlignmentRow: settings panel + alignment demos

ButtonsPage left as-is — nearly all sections depend on @State clickCount
through Button actions, making decomposition ineffective for memoization.
2026-02-05 14:46:12 +01:00
phranck 08daee3258 Feat: render cache debug tooling with per-frame stats and review fixes
Add RenderCache.Stats for cache performance tracking:
- Hit/miss/store/clear counters with hit rate calculation
- Per-frame delta via Stats.delta(since:) for meaningful frame-level logging
- TUIKIT_DEBUG_RENDER=1 env var enables stderr logging (zero cost when off)
- logDebug uses @autoclosure to avoid string allocation in production

Review fixes applied:
- F1: logFrameStats() now logs per-frame delta, not cumulative totals
- F2: clearAll() no longer reads entries.count unconditionally
- F3: Remove unnecessary Sendable from Stats (main-thread only type)
- F5: reset() now also clears stats and frame snapshot
- F7: Move EnvironmentSnapshot to RenderLoop.swift (private, where it belongs)
- F8: Build snapshot from EnvironmentValues, not from ThemeManager directly
2026-02-05 14:40:58 +01:00
phranck 773bb15f2b Feat: render performance phase 2 — cache invalidation fix + Equatable conformances
Phase 1: Add EnvironmentSnapshot comparison in RenderLoop to automatically
clear render cache on theme/appearance changes. Eliminates latent bug where
EquatableView-cached subtrees could serve stale content after palette changes.

Phase 2: Add Equatable conformances to enable subtree memoization:
- Types: TextStyle, Alignment, ContainerConfig, ContainerStyle
- Leaf: Text
- Containers: VStack, HStack, ZStack, Box, Panel, Card, Dialog,
  ContainerView, BorderedView (conditional where Content: Equatable)
- Modifiers: FlexibleFrameView, OverlayModifier, DimmedModifier
  (conditional where Content/Base/Overlay: Equatable)

Also fixes two pre-existing SwiftLint violations:
- State.swift: vertical whitespace before closing brace
- ContainerView.swift: line length (extract local variable)
2026-02-05 14:21:12 +01:00
phranck 3e870335ef Chore: add 2026-02-05 completed items and render performance backlog entry 2026-02-05 13:05:50 +01:00
phranck f59f5330d4 Chore: finalize social-lookup plan and update status files 2026-02-05 13:05:38 +01:00
phranck 64fe55eda2 Feat: replace Branches stat card with Open Issues on dashboard 2026-02-05 12:17:39 +01:00
phranck 631d451eca Feat: optimize social lookup with GitHub Social API, instance validation, and timeouts
Add fetchGitHubSocialAccounts() using /users/{login}/social_accounts API
as primary source. Validate Mastodon domains via NodeInfo instead of
blocklists. Add 5s timeouts to all fetch calls. Expand known instances
list. Skip cross-verification for authoritative sources (github, keybase).
Full refresh now clears cache to prevent stale false positives.
2026-02-05 12:17:33 +01:00
phranck cca0f242fa Docs: update plan status markers for completed and superseded features 2026-02-05 02:01:00 +01:00
phranck 60c8edf795 Fix: pad heatmap to full year and update activity cache with 52 weeks 2026-02-05 01:27:16 +01:00
phranck 3ca22e1944 Fix: cap heatmap cell size via MIN_COLUMNS to prevent oversized cells 2026-02-05 01:10:39 +01:00
phranck c77142ede6 Fix: add missing useEffect import and fix AvatarMarquee overflow 2026-02-05 01:02:30 +01:00
phranck 32b30b7387 Reapply "feat: fall back to cached weeklyActivity from weekly-activity-cache.json when /stats/commit_activity is unavailable"
This reverts commit b89c78f014.
2026-02-04 22:04:31 +01:00
phranck 59b2a303ce Reapply "perf: preload stargazer avatars for instant Stargazers panel"
This reverts commit 15633047bc.
2026-02-04 22:04:31 +01:00
phranck b89c78f014 Revert "feat: fall back to cached weeklyActivity from weekly-activity-cache.json when /stats/commit_activity is unavailable"
This reverts commit c891e6ca6e.
2026-02-04 21:59:49 +01:00
phranck 15633047bc Revert "perf: preload stargazer avatars for instant Stargazers panel"
This reverts commit e9cea4b2bf.
2026-02-04 21:59:49 +01:00
phranck e9cea4b2bf perf: preload stargazer avatars for instant Stargazers panel 2026-02-04 21:57:19 +01:00
phranck c891e6ca6e feat: fall back to cached weeklyActivity from weekly-activity-cache.json when /stats/commit_activity is unavailable 2026-02-04 21:54:39 +01:00
phranck 4f57e49d0b Fix: Marquee hover stops only for visible avatars; prevent heatmap popover flicker 2026-02-04 21:42:22 +01:00
phranck abfc3a05e9 feat(dashboard): add iOS-like swipe/drag with momentum to marquee
- Touch swipe on mobile, mouse drag on desktop
- Momentum scrolling with friction-based deceleration
- Click vs drag detection (5px threshold)
- Cursor grab/grabbing visual feedback
- Popover visibility bounded to 5% edge margin
2026-02-04 21:28:42 +01:00
phranck a6930f17be feat(dashboard): add stargazer avatar marquee with horizontal scroll
- Create generic AvatarMarquee component for horizontal scrolling avatars
- Extract StargazerPopoverContent for social links display
- Refactor StargazersPanel to use AvatarMarquee
- Reorder StatCards: Stars, Contributors, Forks, Releases | Commits, Branches, Open PRs, Merged PRs
- Add fade-in/out masks at edges
- Smooth brake/accelerate on hover
- Popover visibility bounded to visible area
- Add cursor-pointer to Refresh button
- Performance: memoized callbacks, stable props
- Add .env.local to .gitignore
2026-02-04 21:23:15 +01:00
phranck c78d439c4d feat(dashboard): add social account lookup for stargazers
- Add multi-source social search (Keybase, about.me, Linktree, GitHub bio/blog)
- Implement avatar comparison and cross-platform verification
- Create GitHub Action for scheduled cache updates (2h incremental, weekly full)
- Display Mastodon, Bluesky, Twitter links in stargazer popover
- Add smooth hover animations with invisible bridge for better UX
- Add social-overrides.json for manual account mappings
2026-02-04 20:09:55 +01:00
phranck 304860ba37 Add stargazer Mastodon lookup plan, translate dashboard plan to English 2026-02-04 18:38:53 +01:00
phranck 51e02fb306 Add Ko-fi donation link to README 2026-02-04 18:15:37 +01:00
phranck 3cedf75376 Update README, added Copilot instructions file 2026-02-04 17:16:14 +01:00
phranck c6b4b3c77c Chore: Add project docs, plans, and Gource visualization
- .claude/: Agent rules (restructured), session context, permissions
- plans/: State Identity, Render Pipeline, Spinner, Toast, Focus Sections, Palette, Memoization, Dashboard
- papers/: Gource documentation
- Gource: Config, render script, avatar, background audio, history video
- to-dos.md: Task tracker with priorities
- .gitignore: Update exclusions
2026-02-04 16:47:04 +01:00
phranck df564fba42 Perf: Preload hard-drive-boot audio for faster playback 2026-02-04 16:11:12 +01:00
phranck cfc81d6172 Redeploy: Remove exposed token from build 2026-02-04 15:22:25 +01:00
phranck d58796f7ea Trigger redeploy without exposed token 2026-02-04 15:12:06 +01:00
phranck 756f23bc1f Fix: Disable StatePropertyWrapperTests on Linux due to Swift runtime race condition 2026-02-04 14:56:48 +01:00
phranck 3b1f25855e Fix: Only add Authorization header when token is non-empty 2026-02-04 14:49:54 +01:00
phranck 60e241699e update README 2026-02-04 14:37:37 +01:00
phranck 668029077d update README by adding a warning message 2026-02-04 14:35:34 +01:00
phranck a0f31a4e5e Merge pull request #73 from phranck/feat/project-dashboard
Feat: Unified IconBadge component & Dashboard rate limit
2026-02-04 14:32:17 +01:00
phranck f9b106e509 Feat: Unified IconBadge component for SF Symbols
- Add IconBadge component with sm/md/lg variants
- Refactor FeatureCard to use IconBadge
- Update ArchHighlight and RepoInfo for consistency
- Add DASHBOARD_GITHUB_TOKEN to CI for rate limit
2026-02-04 14:18:54 +01:00
phranck 5b3f23b213 Merge pull request #72 from phranck/feat/project-dashboard
add dashboard page
2026-02-04 03:24:24 +01:00
phranck 5855f10154 add dashboard page 2026-02-04 03:20:39 +01:00
Frank Gregor a930f9ffa8 Chore: Update test count badge to 503 tests [skip ci] 2026-02-03 23:43:34 +00:00
phranck f2f88a7a8f Merge pull request #71 from phranck/feat/subtree-memoization
Feat: Subtree memoization via EquatableView (render pipeline phase 5)
2026-02-04 00:28:11 +01:00
phranck 443aad2a90 Fix: Remove global RenderNotifier mutation from EquatableView test to prevent Linux race condition 2026-02-04 00:17:15 +01:00
phranck a705414c82 Feat: Add subtree memoization via EquatableView (render pipeline phase 5)
Equatable views can opt into render caching with .equatable(). On cache hit,
the entire subtree is skipped and the cached FrameBuffer returned directly.
Cache is cleared on every @State change; GC removes stale entries per frame.
2026-02-03 23:08:17 +01:00
phranck 2973d11cb9 Merge pull request #70 from phranck/refactor/palette-consolidation
Refactor: Consolidate 6 palette structs into PalettePreset enum + SystemPalette
2026-02-03 22:33:44 +01:00
phranck cb00b29d56 Refactor: Nest PalettePreset as SystemPalette.Preset 2026-02-03 22:31:33 +01:00