Commit Graph
254 Commits
Author SHA1 Message Date
SnapOtter 23f24c10d1 chore: gitignore Remotion project dir and add test fixture photo 2026-05-08 21:49:22 +08:00
SnapOtter 95386c1eb6 Merge branch 'feat/beautify' into main 2026-05-08 21:41:05 +08:00
SnapOtter e3e5fd5890 Merge branch 'testing/image-editor' into main
Merges all image editor work: RAW decode improvements, expanded format
export (AVIF/TIFF/GIF/JXL/PSD), Photoshop-style menu bar, custom Konva
filters, smart guides, clone stamp, dodge/burn, eyedropper, pixel brush,
selection and transform tool overlays, autosave blob URL persistence,
and 49+ bug fixes across editor canvas and E2E tests.

# Conflicts:
#	apps/api/src/routes/tool-factory.ts
#	apps/api/src/routes/tools/convert.ts
#	apps/web/src/components/editor/common/export-dialog.tsx
#	apps/web/src/components/editor/editor-canvas.tsx
2026-05-08 21:37:52 +08:00
SnapOtter 43b11102ca test: add comprehensive beautify integration tests (606 lines)
Covers dark frame detection, frame title variations, visual quality
assertions, and edge cases for the beautify screenshot tool.
2026-05-08 21:10:39 +08:00
SnapOtter 321c5da998 fix: menu bar dropdown transparent background, move test to e2e-editor
- Replace bg-popover with bg-card for dropdown backgrounds (popover CSS
  variable is not defined in this project's theme)
- Move menu bar test to tests/e2e-editor/ and adapt for editorPage fixture
- Fix click-outside test to handle welcome screen overlay
2026-05-08 20:47:05 +08:00
SnapOtter 5c64581496 feat: recover Photoshop-style menu bar from orphaned branch
Recovers the editor menu bar (File/Edit/Image/Layer/Select/Filter/View)
from orphaned commit b07ecd5 that was lost during a rebase. Integrates
it into the current editor-page layout with PSD/TGA/EXR/HDR file open
support and new document dialog.
2026-05-08 20:37:26 +08:00
SnapOtter a1a71e507f fix: 8 image editor bugs found during Docker-based E2E testing
- fix WebP export silently producing PNG when background is non-transparent
- fix autosave not converting blob: URLs inside image-type canvas objects
- fix project load not resetting selection/crop/clipboard state
- fix rotateCanvas not updating object rotation attributes
- fix flipCanvas not negating object rotation attributes
- fix line shadow props overridden by effect spread ordering
- fix "outside" stroke position rendering same as "center"
- add missing pencil tool keyboard shortcut (N)
- remove misleading resample dropdown from image resize dialog
- fix E2E autosave tests for production builds (no Vite dynamic imports)
- fix color picker test case sensitivity (CSS uppercase vs DOM text)
- add 4 unit tests for rotation attribute transforms
2026-05-08 20:27:06 +08:00
SnapOtter aa773addb4 merge: resolve conflict with main branch in tool-registry.tsx 2026-05-08 18:55:28 +08:00
SnapOtter e118717337 merge: resolve conflict with main branch in README.md 2026-05-08 17:32:16 +08:00
SnapOtter 6c56950f39 fix: repair 6 failing E2E tests (load test image, fix selectors, verify DOM state)
- Add loadTestImage helper using Playwright route interception to serve
  a fixture image via /editor?url= query parameter
- Filter/adjustment tests now load a real source image instead of drawing
  brush strokes (adjustments only apply to source images, not drawn objects)
- Blur/sharpen tests verify DOM state (checkbox checked, parameter input
  accepts and persists values) instead of fragile canvas pixel comparison
- Selection options test uses getByRole with waitForTimeout for robustness
2026-05-08 17:16:14 +08:00
SnapOtter d32c7a279e test(beautify): fix E2E test selectors for processing flow 2026-05-08 17:12:16 +08:00
SnapOtter e9151c5532 fix: update convert unsupported format test (BMP is now supported) 2026-05-08 16:56:35 +08:00
SnapOtter dd73a8a50a fix: resolve 41 bugs and wire 21 unimplemented features in image editor
Canvas rendering:
- Fix Konva filter application order (filters before cache)
- Implement 6 missing filters (motionBlur, radialBlur, surfaceBlur, vignette, grain, sharpen)
- Implement exposure, vibrance, warmth adjustments as custom Konva filters
- Apply layer blend modes via globalCompositeOperation
- Apply object effects (drop shadow, outer glow, stroke) to all shapes
- Mount SmartGuidesOverlay during move tool drag
- Clip pixel grid to visible viewport (200-line cap for performance)

Store logic:
- resizeImage now scales all objects proportionally (points, radii, fontSize)
- rotate/flip/trim handle line/arrow points arrays and center-based objects
- applyCrop creates cropped source image via offscreen canvas
- invertSelection creates mask from bounds when no mask exists
- cutObjects uses single atomic set() to prevent race conditions
- sendToBack respects layer ordering in multi-layer documents
- Add batchNudge() and commitHistory() for undoable nudge operations
- Add updateLayerThumbnail() method

Tool hooks:
- Fix clone stamp/dodge/burn perf (toDataURL only on mouseUp, not every move)
- Fix magic wand zoom/pixelRatio with explicit stage.toCanvas() viewport
- Fix eyedropper sampling with unzoomed canvas export
- Fix selection tool stale closure via isDrawingRef
- Implement polygonal lasso (click-to-place vertices, double-click to close)
- Implement selection subtract mode (geometric and mask-based)
- Implement gradient live preview during drag
- Fix transform/move tool to persist changes and handle ellipse/polygon/star

UI wiring:
- Mount rulers and guidelines in editor page
- Wire histogram with live canvas imageData
- Wire autosave recovery with blob-to-dataURL conversion
- Wire fill dialog to Shift+Backspace shortcut
- Wire eyedropper and transform options to options bar
- Fix history panel undo/redo button reactive state via useSyncExternalStore
- Fix layer row name click to select layer (timer-based click/dblclick)
- Fix zoom animation coordinate drift with progressive store sync
- Fix copy merged to use Konva stage composite export

Tests:
- 49 new unit tests (store fixes + konva filters)
- 8 new E2E test files with 39 test cases
2026-05-08 16:43:27 +08:00
SnapOtter 3d9324b82a chore: update tool count to 50 across all references 2026-05-08 16:33:12 +08:00
SnapOtter 53b717243b fix(meme-generator): add opentype.js types, fix no-dropzone registry test 2026-05-08 16:29:44 +08:00
SnapOtter 0deea29c37 test(beautify): add Playwright E2E tests 2026-05-08 16:28:12 +08:00
SnapOtter 136a4a0752 Merge branch 'feat/format-support-expansion'
# Conflicts:
#	README.md
#	apps/web/src/components/layout/app-layout.tsx
2026-05-08 16:21:11 +08:00
SnapOtter 7650844c8f test(beautify): add comprehensive integration tests 2026-05-08 16:20:44 +08:00
SnapOtter 6ec3a51fa4 feat(meme-generator): add meme generation API route with template and custom image modes
Custom route handler supporting template mode (JSON body with templateId)
and custom image mode (multipart upload). Registers process function for
pipeline compatibility. Includes 18 integration tests.
2026-05-08 16:13:34 +08:00
SnapOtter 69e107fbab feat(beautify): add device frame assets and PNG frame compositing 2026-05-08 16:12:46 +08:00
SnapOtter d8c1fdf5c2 feat(beautify): add SVG frame generators (macOS, Windows, browser) 2026-05-08 16:09:31 +08:00
SnapOtter 39358524cd feat(beautify): add shadow rendering (extracted from border.ts pattern) 2026-05-08 16:06:37 +08:00
SnapOtter b13df56273 feat(beautify): add background generation (solid, gradient, image, transparent) 2026-05-08 16:04:34 +08:00
SnapOtter 3d103d5092 test(meme-generator): add template manifest validation tests 2026-05-08 16:03:21 +08:00
SnapOtter 9dff59c400 feat(meme-generator): add text renderer with opentype.js SVG path generation 2026-05-08 16:01:46 +08:00
SnapOtter cb8684d796 test: remove JP2 and DDS from E2E exotic upload tests (Chromium rejects these extensions) 2026-05-08 15:40:23 +08:00
SnapOtter 98b2e5a269 test: add Playwright e2e spec for color-blindness tool 2026-05-08 15:21:39 +08:00
SnapOtter eedc2443d6 feat: add color-blindness API route and integration tests 2026-05-08 15:18:38 +08:00
SnapOtter 5deb25c9e3 test: expand format decoder and detection unit tests for all new formats 2026-05-08 15:18:04 +08:00
SnapOtter 9720e6409e test: expand new-formats integration tests with output matrix, resize, and preview tests 2026-05-08 15:17:18 +08:00
SnapOtter 93a246ce23 test: add QOI codec unit tests and E2E GUI format support tests
- QOI codec: 16 tests covering encode/decode round-trips, error handling, fixture validation
- E2E: 28 tests for format upload/resize, convert new outputs, dropdown verification,
  HEIC-to-JPG flow, and exotic format upload acceptance
2026-05-08 15:16:06 +08:00
SnapOtter 44608733c6 feat: add PPM/PGM/PBM CLI decoder fallback, QOI fixture and format-matrix entry
- Add ppm/pgm/pbm to CLI_DECODED_FORMATS with Sharp-first, ImageMagick fallback
- Create sample.qoi test fixture (10x10 solid color)
- Add QOI to format-matrix test FORMAT_SAMPLES
- Mark PPM/PGM/PBM as needsCliDecoder in tests (Sharp doesn't support them natively)
2026-05-08 15:12:23 +08:00
SnapOtter 0b6a970912 feat: add color blindness simulation image-engine operation
Add colorBlindness() operation with 8 simulation matrices (Vienot/Machado)
for protanopia, deuteranopia, tritanopia, protanomaly, deuteranomaly,
tritanomaly, achromatopsia, and blue cone monochromacy.
2026-05-08 15:11:36 +08:00
SnapOtter e9fb35b7cd test: add integration tests for new input and output formats 2026-05-08 00:24:45 +08:00
SnapOtter bd6f80ff3e test: add format fixtures for SVGZ, JP2, EPS, PPM, PGM, PBM, DDS, CUR, DPX, FITS, APNG 2026-05-08 00:22:22 +08:00
SnapOtter e99bae428a fix: resolve 50+ bugs across editor store, canvas, panels, and tools
- Store: loadImage resets state, applyCrop updates sourceImageSize,
  setTool clears stale cropState, layer ordering preserved across
  layers, rotateCanvas/flipCanvas account for object dimensions,
  trimCanvas implemented, resizeCanvas supports anchor positioning
- Canvas: crop overlay interactive, move tool drag events wired,
  hand tool panning, stage ref effect mount-only, checkerboard
  tracks pan offset, filter cache clearing
- Panels: hslToHex color fix for hue 240-360, adjustments single
  setAdjustment call, curves draggingIndex after sort, history
  panel fresh temporal reads, export transparent setting, canvas
  resize dialog re-sync, hex input respects picker target
- Tools: text tool fixed positioning and event cleanup, shape tool
  deferred addObject, selection mode wired to store, magic wand
  tolerance controlled, eyedropper coordinate transform
- Options: dodge-burn/shape/clone/fill/gradient/pixel-brush use
  proper store actions instead of raw setState
- Added 20+ store actions for tool settings
- Updated tests for corrected rotation/flip/trim behavior
- Excluded e2e-editor from vitest config
2026-05-07 23:47:08 +08:00
SnapOtter 1669e34909 Merge fix/129-face-enhancement-mediapipe: add mediapipe to upscale-enhance bundle
fix: add mediapipe to upscale-enhance bundle for face enhancement

The enhance-faces tool requires MediaPipe for face detection, but the
upscale-enhance feature bundle did not include mediapipe in its pip
packages. Added mediapipe to both amd64 and arm64 package lists.

Added 25 regression tests validating bundle dependency completeness.

Closes #129
2026-05-07 22:24:03 +08:00
SnapOtter 6fc767523c fix: add mediapipe to upscale-enhance bundle for face enhancement
The enhance-faces tool requires MediaPipe for face detection, but the
upscale-enhance feature bundle did not include mediapipe in its pip
packages. Users who installed only the upscale-enhance bundle got
"Face detection requires MediaPipe" errors. Added mediapipe to both
amd64 and arm64 package lists, matching the pattern used by the
face-detection and photo-restoration bundles.

Also added feature-manifest.test.ts with 25 tests validating bundle
dependency completeness to prevent similar missing-dependency bugs.

Closes #129
2026-05-07 22:21:45 +08:00
SnapOtter 14810c3c78 fix: prevent repeated redirect when switching from grid to sidebar view
The default-view redirect in HomePage fired on every mount, not just the
initial page load. A module-level flag now gates the redirect so it only
applies once per session, allowing users to switch to sidebar view when
grid is the default.

Closes #128
2026-05-07 22:16:26 +08:00
SnapOtter 16af9c573a feat: remove app name and logo customization feature
Users can no longer customize the app name or logo. The branding API
endpoints, permission, frontend UI, env vars (APP_NAME, MAX_LOGO_SIZE_KB),
and all related tests are removed. Includes a migration to clean up
branding data from existing databases.
2026-05-07 19:41:30 +08:00
SnapOtter 79897fcdb0 test: fix brush test assertion for hardness visibility 2026-05-07 19:22:50 +08:00
SnapOtter 8208acfb78 fix: restore missing text options and font loader, wire text tool options bar, fix e2e test selectors 2026-05-07 19:13:36 +08:00
SnapOtter 25a1dd7aba Merge fix/131-content-aware-resize-registry: add frontend registry for content-aware resize
fix: add frontend registry entry for content-aware resize tool

Closes #131
2026-05-07 09:44:14 +08:00
SnapOtter cc15821c5e fix: add frontend registry entry for content-aware resize tool
The content-aware-resize tool had a full backend implementation (API route,
caire binary, seam-carving bridge) but was missing from the frontend
toolRegistry Map. Navigating to /content-aware-resize showed "Tool not found"
because ToolPage could not resolve a registry entry for the tool ID.

Added a dedicated ContentAwareResizeSettings component and registered it in
the tool registry with side-by-side display mode. Also added a guard test
that verifies every tool in the shared TOOLS[] array has a matching registry
entry, preventing this class of bug from recurring.

Closes #131
2026-05-07 09:38:38 +08:00
SnapOtter e11e3660d9 test: add editor E2E test specs 2026-05-07 09:29:01 +08:00
SnapOtter 4a96d4b217 test: add editor store and types unit tests (161 tests) 2026-05-07 09:27:47 +08:00
SnapOtter 979a833978 fix: resolve analytics data gaps and resize validation failures
- Fix resize 20% failure rate: add Zod refine requiring at least one
  dimension, enforce integer/max constraints, clamp percentage scaling
  to minimum 1px, and guard against missing metadata in withoutEnlargement
- Fix PostHog init race condition: move consent check before async import
  so frontend events (search, pageview) are no longer silently dropped
- Fix identify() passing nested $set/$set_once wrappers instead of flat
  properties, so version person property now appears on PostHog profiles
- Add error_code and error_message to failed tool_used analytics events
  for debugging tool failures from PostHog
2026-05-06 23:21:45 +08:00
SnapOtter d705c863e3 Merge feat/transparency-fixer: add PNG Transparency Fixer tool
New AI-powered tool that fixes fake transparent PNGs in one click.
Uses BiRefNet HR-matting (2048x2048) with Sharp defringe post-processing.
2026-05-06 21:57:46 +08:00
SnapOtter 8f9ba701be fix: QR code logo causes preview to vanish and become unrecoverable
The QR code generator's logo feature was broken in production (Docker)
due to three interacting issues:

1. The CSP connect-src directive did not include data:, so the
   qr-code-styling library's internal XHR to convert logo data URLs to
   blobs was silently blocked. The library has no onerror handler, so the
   render promise hung forever after the container was already cleared.

2. crossOrigin: "anonymous" was unnecessarily set on imageOptions for
   data URLs, which can cause canvas taint issues.

3. The logo options used a conditional spread that omitted the image key
   when no logo was set. The library's update() deep-merges options, so
   removing the logo preserved the stale data URL and the QR stayed
   broken even after logo removal.

Closes #121
2026-05-06 21:38:12 +08:00
SnapOtter 84e62e6132 refactor: rename tool display name to "PNG Transparency Fixer" 2026-05-06 18:53:37 +08:00