Commit Graph
226 Commits
Author SHA1 Message Date
Hiren 24fa9d1252 fix(refboard): remove loading overlay that got stuck due to viewport culling
The asset progress overlay (e.g. "Loading assets 6/22") was incompatible
with the viewport culling system — culling only loads nearby textures and
unloads distant ones, so loaded count could never reach total. Simplified
to a brief spinner during scene data parsing only.
2026-03-16 16:23:57 +05:30
Hiren 7bcb0fd071 fix(refboard): fix WebGL null texture crash and add loading overlay
- Set texture to Texture.EMPTY before destroying sprites in
  AnimatedGifSprite and PdfPageSprite (matches VideoSprite pattern)
- Add full-screen loading overlay that blocks interaction until
  scene and assets finish loading
2026-03-16 11:10:19 +05:30
Hiren Kangad 019e17ae59 fix: allow spacebar in contentEditable elements (markdown editor)
Space-to-pan handler was intercepting spacebar globally but only
excluded INPUT/TEXTAREA — missed contentEditable (BlockNote editor).
2026-03-15 13:15:00 +05:30
Hiren Kangad 479feb991c fix: block flip/rotate in SelectionToolbar for sticky, text, markdown, pdf-page
The toolbar buttons called ops directly without type filtering.
Now filters NON_TRANSFORMABLE types before applying flip/rotate ops.
2026-03-14 16:51:02 +05:30
Hiren Kangad 94ea1e3123 docs: mark Phase 3 (PDF support) as completed in expansion plan 2026-03-14 12:08:41 +05:30
Hiren Kangad 6f01c0fa54 feat: PDF support — upload, rasterize, page picker, canvas placement
Upload PDFs → server-side page rasterization via pdftoppm (poppler-utils)
→ page picker modal for selecting pages → placed on canvas as pdf-page
objects with lazy texture loading and progressive high-res upgrades.

Key features:
- New pdf-page scene object type with source PDF metadata
- Page picker modal with lazy thumbnail loading (first 20 + on-scroll)
- Priority queue: hires jobs (priority 10) jump ahead of thumbnails (0)
- Single-page PDFs skip picker, place directly
- No crop/rotate/flip on PDF pages (enforced in TransformBox, context
  menu, and keyboard shortcuts)
- Per-page socket events for progressive texture upgrades
- 500-page cap, 50-page batch placement limit
- Early validation (before MinIO upload) prevents orphaned assets
2026-03-14 12:07:15 +05:30
Hiren Kangad 4dbd755c41 fix: PdfPickerModal thumbnail URL uses /api/images/ not /api/assets/ 2026-03-14 11:40:49 +05:30
Hiren Kangad 9c8b3cc5f5 feat: wire PdfPickerModal into Editor with hires texture upgrade via socket 2026-03-14 11:31:45 +05:30
Hiren Kangad 656b0a9875 feat: PdfPickerModal — page selection grid with lazy thumbnail loading 2026-03-14 11:29:31 +05:30
Hiren Kangad bbf9b9484a feat: PDF upload response forks to picker callback or direct placement 2026-03-14 11:28:29 +05:30
Hiren Kangad 3bd6270990 feat: frontend accepts PDF uploads, UploadManager detects PDF type 2026-03-14 11:26:29 +05:30
Hiren Kangad e118ad632a feat: block rotate/flip for pdf-page in context menu and shortcuts 2026-03-14 11:22:29 +05:30
Hiren Kangad 07953ab18d feat: SceneManager creates pdf-page items with culling support 2026-03-14 11:21:08 +05:30
Hiren Kangad 332f12cafe feat: add PdfPageSprite — placeholder, lazy texture, page badge 2026-03-14 11:19:55 +05:30
Hiren Kangad 3511c54658 feat: add PdfPageObject type to scene format 2026-03-14 11:19:04 +05:30
Hiren Kangad 247145f545 fix: early PDF validation, type-aware errors, exact job dedup
- Move PDF page count check before MinIO upload and DB record creation
  to prevent orphaned objects when >500 page PDFs are rejected
- Use job type label (PDF page / Video) in media-worker error messages
  instead of hardcoded "Video processing failed"
- Replace LIKE-based idempotency check with exact JSON match to prevent
  page 1 matching page 11/12/etc substring collisions
2026-03-14 11:16:58 +05:30
Hiren Kangad 4b68e337cf feat: media worker dispatches pdf-thumbnail and pdf-hires jobs 2026-03-14 11:12:41 +05:30
Hiren Kangad 1250ad1b72 feat: add PDF page selection and lazy thumbnail endpoints 2026-03-14 11:11:50 +05:30
Hiren Kangad 0b56ec7f6f feat: accept PDF uploads — pdfinfo extraction, pdf_pages rows, thumbnail job queuing 2026-03-14 11:10:45 +05:30
Hiren Kangad d28998e4d7 feat: add pdf-utils.js — pdfInfo, pdfRenderPage, bufferToTempFile 2026-03-14 11:10:01 +05:30
Hiren Kangad e1aedd721b feat(db): add pdf_pages table, priority column, and helper functions 2026-03-14 11:08:45 +05:30
Hiren Kangad 0e14790990 build: add poppler-utils to Dockerfile for PDF support 2026-03-14 11:07:03 +05:30
Hiren Kangad a901833b72 fix: rotated transform box, video texture crash, paste duplication, and loading UX
- TransformBox rotates with single-item selection (Figma-style), with
  handles and resize math projected into rotated coordinate space
- Fix VideoSprite alphaMode crash by swapping texture to EMPTY before
  destroying, preventing PixiJS render loop from reading null source
- Fix Ctrl+V double-paste: internal clipboard now always takes priority
  over system clipboard PNG, with wasRecentInternalPaste() guard
- Add asset loading progress bar and suppress "Drop images here" flash
  during initial scene load
2026-03-13 17:37:21 +05:30
Hiren Kangad e7e217d3d4 fix: restrict rotation to image/video selections only
Hide rotate handles and block rotation drag for sticky, markdown,
text, drawing, and group item types. Only images and videos support
rotation.
2026-03-13 17:07:26 +05:30
Hiren Kangad 05118330d6 feat: unified composition renderer for clipboard/export
Replace the split snapshot/native renderer paths with a single
composition pipeline (compositionRenderer.ts) that:

- Loads actual source images and uses naturalWidth/Height for
  correct full-resolution sampling (fixes top-left-corner-only bug
  caused by data.w/h being capped to 600px display dimensions)
- Routes image-only selections through native Canvas 2D composition
- Falls back to viewport snapshot for mixed/unsupported selections
  with explicit warnings instead of silent degradation
- Resolves group children via itemResolver for proper group export
- Rejects group children from native composition (local coords
  incompatible with world-space drawing)
- Adds canvas size safety limits with auto-downscale
- Guards VideoSprite._drawFrame against null texture source race
  condition during zoom-triggered culling

New files:
- compositionRenderer.ts — unified composition module
- compositionRenderer.test.ts — 16 tests for entry flattening,
  bounds, dimensions, group handling

Modified:
- clipboard.ts — uses composeSelection() instead of direct renderers
- export.ts — uses composeSelection() + getCompositionDimensions()
- Editor.tsx, useShortcutHandler.ts — pass scene for group resolution
- VideoSprite.ts — null guard on texture source in frame loop
2026-03-13 16:59:11 +05:30
Hiren Kangad 1ceafec67f refboard: fix native export pixel bounds rounding 2026-03-13 15:51:12 +05:30
Hiren Kangad 7b2fcfd6a8 refboard: add native image copy and export renderer 2026-03-13 15:48:12 +05:30
Hiren Kangad ae9b1ecefe refboard: avoid eager extract fallback for canvas snapshots 2026-03-13 15:36:12 +05:30
Hiren Kangad 80ec4808e8 refboard: await clipboard writes before copy success 2026-03-13 15:33:37 +05:30
Hiren Kangad 3dd110f491 refboard: restore clipboard copy and native paste flows 2026-03-13 15:30:23 +05:30
Hiren Kangad e9e0c25491 refboard: standardize clipboard copy on rendered canvas 2026-03-13 15:27:41 +05:30
Hiren Kangad cd8207e984 refboard: capture board previews from rendered canvas 2026-03-13 15:23:08 +05:30
Hiren Kangad c21a0c386d refboard: add corner rotation grips 2026-03-13 15:10:45 +05:30
Hiren Kangad 8d34d42377 refboard: preserve center when rotating items 2026-03-13 15:05:54 +05:30
Hiren Kangad 98fb7be77e refboard: add visible rotate controls 2026-03-13 15:01:25 +05:30
Hiren Kangad cb59fbb150 fix(crop): fix editor positioning for flipped images with asymmetric crops
The crop editor (getImageEditorGeometry) was anchoring on a view-space
point that maps differently in cropped vs uncropped local space when
flipped. For asymmetric crops + flip, the full image would appear
shifted from where the visible image was — the user saw the image
"jump" when entering crop mode.

Fix: anchor on the container's local origin instead. In the cropped
sprite, local (0,0) corresponds to source pixel (srcRect.x, srcRect.y).
Position the editor so that same source pixel maps to the same world
point in both cropped and uncropped states. This works correctly for
all flip/rotation/crop combinations.
2026-03-13 14:54:36 +05:30
Hiren Kangad 21a724c0f4 fix: address code review findings from crop/text commit
- Fix crop confirm anchor drift for rotated images by using crop corner
  world point instead of AABB min in useCanvasSetup.ts
- Document ungroup shear limitation for non-uniform scale + rotation
- Add 6 integration tests covering crop confirm and ungroup paths
2026-03-13 13:47:14 +05:30
Hiren Kangad 9a4edd90c7 refboard: complete image geometry rework — consumer adoption + tests
- Fix grouping.ts ungroup: transform display position (with flip
  compensation) through group transform, then back-calculate canonical
  data.x/y. Fixes visual jump for flipped images in rotated groups.
- Fix clipboard.ts + export.ts resolution estimation: account for
  scale when computing effective rendered width for texture ratio.
- Add imageTransforms.test.ts: 32 unit tests covering source rect,
  visible local rect, display transform, display geometry, editor
  geometry anchor preservation, crop rect round-trips, coordinate
  conversions, negative scale normalization, and world bounds invariants.
- Add vitest as dev dependency with "test" script.
- Include canonical geometry layer (imageTransforms.ts) and crop
  session rewrite (CropOverlay.ts) from prior work.
- Add image geometry rework plan document.
2026-03-13 13:37:42 +05:30
Hiren Kangad c874e34577 refboard: export cropped images from visible frame 2026-03-13 13:05:31 +05:30
Hiren Kangad 407fa82915 refboard: fix flipped image crop coordinate mapping 2026-03-13 13:03:37 +05:30
Hiren Kangad cd9db8816c refboard: cull images by visible bounds 2026-03-13 12:59:20 +05:30
Hiren Kangad dc283124d7 refboard: centralize image visible frame transforms 2026-03-13 12:58:29 +05:30
Hiren Kangad 768de39463 refboard: use full image geometry in crop mode 2026-03-13 12:50:13 +05:30
Hiren Kangad ddd395444d refboard: resize images from visible bounds 2026-03-13 12:46:48 +05:30
Hiren Kangad 50dbb4e0cf refboard: anchor crop apply to selected region 2026-03-13 12:42:16 +05:30
Hiren Kangad 267deefc10 refboard: preserve image position when applying crop 2026-03-13 12:39:24 +05:30
Hiren Kangad 18c968b54f refboard: fix cropped image offset transforms 2026-03-13 12:36:57 +05:30
Hiren Kangad 4dc338cdb6 refboard: rebase cropped image rendering to visible frame 2026-03-13 12:33:03 +05:30
Hiren Kangad f6a937f598 refboard: use visible bounds for image layout ops 2026-03-13 12:25:29 +05:30
Hiren Kangad 5c13def2d2 refboard: improve crop preview and cropped bounds focus 2026-03-13 12:15:22 +05:30