Commit Graph
204 Commits
Author SHA1 Message Date
Hiren Kangad 0d40b2b973 feat(markdown): add MarkdownOverlay DOM overlay manager 2026-03-13 11:21:27 +05:30
Hiren Kangad de527954da feat(markdown): add MarkdownSprite and register in SceneManager
Creates MarkdownSprite (Graphics-only background rect with header bar)
and wires it into SceneManager._createItem() under case 'markdown'.
2026-03-13 11:21:27 +05:30
Hiren Kangad f989a8111b feat(markdown): add markdownDefaults module with constants and extractTitle 2026-03-13 11:21:27 +05:30
Hiren Kangad 50c34a409f feat(markdown): add MarkdownObject type to scene format 2026-03-13 11:21:27 +05:30
Hiren Kangad cc38adb1d6 chore: add markdown block dependencies (react-markdown, blocknote, turndown) 2026-03-13 11:21:27 +05:30
Hiren Kangad dd1578110b refboard: support rotated image crop editing 2026-03-13 11:21:27 +05:30
Hiren Kangad 9502f89a06 refboard: tighten rotated image hit testing 2026-03-13 11:21:27 +05:30
Hiren Kangad 12410c0098 refboard: stabilize image flip and crop transforms 2026-03-13 11:21:27 +05:30
Hiren Kangad c40304464f chore: add .worktrees/ and .superpowers/ to .gitignore 2026-03-13 11:21:27 +05:30
Hiren Kangad 75a975447b chore: commit pending workspace changes 2026-03-13 08:43:44 +05:30
Hiren Kangad f77ac59e6c fix(sticky): make size presets absolute again 2026-03-13 00:50:21 +05:30
Hiren Kangad 9f69eae308 refine(sticky): reduce preset sizes and remove pan tool shortcuts 2026-03-13 00:46:37 +05:30
Hiren Kangad ce1cc60d67 fix(sticky): restore zoom-aware preset creation and live editing sync 2026-03-13 00:42:32 +05:30
Hiren Kangad 2d05226ddd fix(sticky): fixed-size creation, shared presets module, live resize sync
Fixes three review findings:

1. Sticky creation no longer zoom-adapts — always creates at M preset
   (28px/260w) in world space. Consistent at any zoom level.

2. Preset definitions extracted to stickyPresets.ts (shared domain module).
   TextFormatToolbar and tools.ts both import from there — no more
   canvas→component dependency inversion.

3. TextEditor.onLiveResize callback syncs spatial index and transform
   box as sticky background grows during typing.
2026-03-13 00:31:44 +05:30
Hiren Kangad 706b00cf35 feat(sticky): proportional card width per text size preset
Each S/M/L/XL/XXL preset now sets both fontSize and card width:
S(20px/200w), M(28px/260w), L(36px/320w), XL(48px/400w), XXL(60px/480w).

Creation picks preset based on zoom, toolbar toggle updates both.
Wider size toggle buttons for XL/XXL labels, font name maxWidth 110px.
Backward compatible — existing stickies keep original width.
2026-03-13 00:26:09 +05:30
Hiren Kangad b081ed7169 refactor(sticky): fixed-width card with S/M/L/XL/XXL font presets
Stickies are now fixed-width cards — no resize handles shown.
Text size controlled via 5 presets (10/14/18/24/32px).
On creation, zoom-aware screenToWorld snaps to nearest preset.
Height auto-adjusts from content. Plain text resize unchanged.

Removes: sticky width bake, live reflow drag, min width constraint.
Backward compatible — existing stickies map to nearest preset.
2026-03-13 00:18:41 +05:30
Hiren Kangad 1631185e4f feat(sticky): S/M/L text size toggle, live reflow resize, min width
Sticky UX overhaul — clear separation between card resize and text size:

- S/M/L toggle (12/14/18px) in contextual toolbar for sticky text size
- TransformBox: horizontal-only resize for stickies with live text
  reflow during drag (no more stretch-then-snap)
- Hide vertical handles (tc/bc) for sticky-only selections
- Minimum sticky width of 80px enforced in both drag and bake
- TextEditor: sticky background auto-resizes as user types
- textLimits.ts comment corrected to match actual usage

Plain text unchanged: resize gesture scales fontSize via bake.
Fully backward compatible — existing stickies map to nearest preset.
2026-03-13 00:12:23 +05:30
Hiren Kangad a20cab3fcd refactor: extract TextCore shared text engine + sticky width-only resize
TextCore.ts: shared text rendering with dirty-check caching, zoom-bucket
resolution, and optional word-wrap. TextSprite and StickySprite now
compose TextCore instead of duplicating text logic.

Sticky resize now bakes width only (fontSize stays stable), so dragging
a sticky wider/narrower reflows text with auto-adjusted height — like
a resizable text box.
2026-03-12 23:53:06 +05:30
Hiren Kangad d9c1f4c600 fix(sticky): bake scale into fontSize + width on sticky resize
Sticky text was blurry after scaling because sx/sy stretched the
texture without re-rasterizing. Now bakes fontSize and card width
on drag-end (same as plain text), so StickySprite recomputes layout
at native resolution.
2026-03-12 23:44:43 +05:30
Hiren Kangad eb4591dca0 fix: remove font-size clamp from resize-bake path
Direct manipulation (scaling text up/down) should respect user intent
without artificial caps. Clamps remain on creation defaults only.
2026-03-12 23:38:47 +05:30
Hiren Kangad 150bb91a27 refactor: centralize font-size clamps in textLimits.ts
Single source of truth for font-size constraints (text 6–160, sticky
8–96) used by creation defaults, resize-bake, and any future mutation
paths. Replaces scattered hardcoded min/max values.
2026-03-12 23:35:25 +05:30
Hiren Kangad 1ac727ea60 feat: zoom-bucket text sharpness + remove fontSize toolbar controls
Add TextSharpnessManager for crisp text rendering at all zoom levels:
- Discrete zoom buckets (0.5–3x) avoid texture churn on small zoom changes
- Initial bucket applied to all items on setup and newly created items
  via SceneManager.onItemCreated callback (fixes blurry-on-load)
- Visibility check uses getItemWorldBounds for correct grouped item coords
- TextSprite/StickySprite gain setZoomBucket() for resolution control

Remove fontSize +/- controls from contextual toolbar — font size is now
controlled purely through direct manipulation (resize → bake).
2026-03-12 23:23:30 +05:30
Hiren Kangad 9fac16e6a4 feat: contextual text formatting toolbar + resize fontSize baking
- Remove persistent font-size slider from main toolbar (tools only)
- Lock in zoom-aware creation defaults as named constants
- Split contextual toolbar by object type: text vs sticky
  - Text: fontSize + fontFamily + text color
  - Sticky: fontSize + fontFamily + text color + note fill color
  - Mixed selection: hide toolbar
- Bake scale into fontSize on text resize (reset sx/sy to 1)
- Sticky resize stays layout-driven (no font change)
2026-03-12 22:47:48 +05:30
Hiren Kangad 83e753bb69 perf: remove thumbnail generation from hot autosave path
extract.canvas(viewport) snapshots the entire viewport to a WebGL
texture on the main thread. When viewport dimensions × devicePixelRatio
exceed GPU limits, this causes texImage2D errors and ~1000ms stalls
that block focus, typing, and scroll. Thumbnails can be generated on
idle or server-side instead.
2026-03-12 22:24:59 +05:30
Hiren Kangad 93c7c792db fix(text): use requestAnimationFrame for editor open timing
queueMicrotask fires before the click event settles, causing the
textarea to blur immediately and trigger empty-text cleanup.
requestAnimationFrame waits one paint frame — enough for the pointer
event to fully resolve without the sluggishness of setTimeout(50).
2026-03-12 22:15:20 +05:30
Hiren Kangad d365049470 perf(text): remove 50ms editor delay + zoom-aware creation defaults
Replace setTimeout(50) with queueMicrotask for TEXT tool editor open
(matching STICKY tool). Add screenToWorld helper for zoom-aware font
sizes and sticky card dimensions. Remove unused Text/TextStyle imports.
2026-03-12 22:09:12 +05:30
Hiren Kangad 5158938eb3 refactor(text): update Editor TextFormatToolbar to use TextSprite API 2026-03-12 22:09:12 +05:30
Hiren Kangad 2efcd0e622 refactor(text): update TextEditor to use TextSprite API 2026-03-12 22:09:12 +05:30
Hiren Kangad 2e24500746 feat(text): wire TextSprite into SceneManager, eliminate inline text mutation 2026-03-12 22:09:12 +05:30
Hiren Kangad d85de4ba9e feat(text): add TextSprite with dirty-check caching 2026-03-12 22:09:12 +05:30
Hiren Kangad f12b75395a perf(sticky): remove creation delay + add dirty-checking to StickySprite
- Replace 50ms setTimeout with queueMicrotask for editor open
- Skip updateFromData() entirely when no inputs changed
- Cache background redraw inputs, skip Graphics clear+redraw when shape unchanged
- Separate text-only, style-only, and bg-only update paths
2026-03-12 22:09:12 +05:30
Hiren Kangad 565b7c6c19 fix(sticky): prevent crash on editor re-entry during sticky lifecycle
Clear editor state before scene callbacks to prevent blur timer or
startEditing re-entry from calling updateFromData on a destroyed sprite.
Guard all display object access with .destroyed checks.
2026-03-12 22:09:12 +05:30
Hiren Kangad a191f74c31 fix(sticky): wire fontSize from toolbar slider + update shortcuts help 2026-03-12 22:09:12 +05:30
Hiren Kangad a7faf004ae feat(sticky): enable double-click editing for sticky notes 2026-03-12 22:09:12 +05:30
Hiren Kangad e183e4b9d2 feat(sticky): extend TextEditor to support sticky note editing 2026-03-12 22:09:12 +05:30
Hiren Kangad 6eb78a2608 feat(sticky): add sticky note button to toolbar 2026-03-12 22:09:12 +05:30
Hiren Kangad 17680a4d8f feat(sticky): add STICKY tool type with click-to-place handler 2026-03-12 22:09:12 +05:30
Hiren Kangad 9fc62dbdc7 feat(sticky): wire StickySprite into SceneManager create/update 2026-03-12 22:09:12 +05:30
Hiren Kangad 92f6200f4b feat(sticky): add StickySprite renderer 2026-03-12 22:09:12 +05:30
Hiren Kangad 6ee6060600 feat(sticky): add StickyObject to scene format schema 2026-03-12 22:09:12 +05:30
Hiren Kangad 69fcab717c fix(review): add recursion depth guard to group child resolution
Prevents stack overflow from corrupted data with circular group references.
2026-03-12 22:09:12 +05:30
Hiren Kangad ecd4408d8a feat(review): group-aware comment targeting — resolve clicks to stable children
New reviewTargeting.ts provides resolveReviewTargetAtPoint() which:
- descends into groups to find the deepest commentable child under the click
- walks children in z-order (front-to-back) for correct visual stacking
- handles nested groups recursively
- returns null if no valid child exists under the point

Editor.tsx review click handler now delegates to the resolver instead of
raw queryRegion + topmost-z pick. Defensive guard rejects group objectIds
before draft creation.

Existing group-anchored threads continue to render and open normally.
2026-03-12 22:09:12 +05:30
Hiren Kangad 1134ddb5c9 refactor(review): use shared getPointAnchorWorld in jump-to-object 2026-03-12 22:09:12 +05:30
Hiren Kangad 40153751f6 refactor(review): remove panel draft composer, move suppression to Editor 2026-03-12 22:09:12 +05:30
Hiren Kangad 54a7557233 feat(review): wire InlineCommentComposer into Editor with anchored positioning 2026-03-12 22:09:12 +05:30
Hiren Kangad e5cf3d3632 feat(review): add useAnchoredOverlayPosition hook for world→screen conversion 2026-03-12 22:09:12 +05:30
Hiren Kangad cf879b34d5 feat(review): add draftCommentText state and double-submit guard 2026-03-12 22:09:12 +05:30
Hiren Kangad 6e1d9df7f0 feat(review): add InlineCommentComposer presentational component 2026-03-12 22:09:12 +05:30
Hiren Kangad 7aa55b66f0 refactor(review): extract shared anchor math into reviewAnchors.ts 2026-03-12 22:09:12 +05:30
Hiren Kangad 318b7358e1 fix(review): address code review findings — tool conflicts, dual inputs, pin animation
1. TEXT and ERASER tool clicks now suppressed during review mode via
   reviewMode flag on ToolContext (read from ref for live value)
2. Object-comment input hidden when draftPin is active — only one
   creation input visible at a time
3. PinOverlay entrance animation removed — focus styling (scale 1.15x,
   alpha changes) no longer fights with fade-in animation loop
2026-03-12 22:09:12 +05:30