Commit Graph
18 Commits
Author SHA1 Message Date
SnapOtter 07e12754ba fix: resolve QA report issues across routing, editor, i18n, and pipeline
- Add /tools/:toolId legacy redirect and catch-all 404 page (P1-12, P1-13)
- Add Shift+O dodge/burn/sponge cycle and Ctrl+Y redo shortcut (P1-3, P1-4)
- Fix Fit on Screen menu action to properly compute fit zoom (P1-8)
- Add filename input to editor export dialog (P1-2)
- Fix password validation mismatch: frontend now requires 8 chars (P1-11)
- Add license info to Settings About section (P1-9)
- Replace hardcoded strings in dropzone, files, pipeline with i18n keys (P1-17 to P1-25)
- Add 20+ missing i18n keys to all 21 locale files
- Translate Japanese editor.shapes and settings.aiFeatures sections (P1-19, P1-20)
- Fix RTL: use logical CSS properties in sidebar, files, app-layout (P2-24 to P2-26)
- Add single-file download button to pipeline results (P1-28)
- Fix compress step settings restoration on pipeline load (P1-27)
- Increase mobile nav touch targets to 44px minimum (P2-29)
2026-06-05 22:31:28 +08:00
SnapOtter d38621d7b9 feat: add multi-language support for 20 locales
Add complete i18n infrastructure with 21 supported languages:
English, Simplified Chinese, Traditional Chinese, Japanese, Korean,
Spanish, French, Italian, Brazilian Portuguese, German, Dutch, Swedish,
Russian, Polish, Ukrainian, Arabic (RTL), Turkish, Hindi, Vietnamese,
Indonesian, and Thai.

- I18nProvider context with three-tier locale detection
  (user preference > navigator.languages > instance default > English)
- ~1500 translation keys per locale with TypeScript-enforced completeness
- Dynamic code-splitting: only the active locale is loaded at runtime
- Language selectors in footer, login page, settings, and mobile sidebar
- Arabic RTL support with CSS logical properties across all components
- Tool names, descriptions, and categories translated via i18n helpers
- Public API endpoint GET /api/v1/config/locale for instance default
- Multi-script font stack (CJK, Arabic, Devanagari, Thai, Cyrillic)
- format() and plural() helpers for interpolation and pluralization
- API error translation mapping (translateApiError)
- 36 Playwright e2e tests verifying all 21 locales load correctly
- 25 unit tests for format, plural, locale detection, and completeness
- Updated translations.md docs and CLAUDE.md conventions
2026-05-15 17:02:49 +08:00
SnapOtter ac7d9cd591 fix: restrict SVG-to-raster dropzone to only accept SVG files
Adds fileFilter and acceptDescription props to Dropzone so tools can
restrict accepted file types across all entry paths (file picker,
drag-and-drop, paste, single URL import, bulk URL import).
2026-05-13 10:32:18 +08:00
SnapOtter 095e3d9488 feat: add URL-based image import (single + bulk)
Add a fourth image ingestion path: importing images by URL.

Backend:
- POST /api/v1/fetch-urls endpoint with SSRF protection, image validation,
  preview generation, and p-queue concurrency
- SSRF utility blocking private IPs, validating redirect hops, with
  comprehensive IPv4/IPv6 range coverage

Frontend:
- Always-visible URL input in the dropzone for quick single-image import
- Bulk URL import modal with smart URL parsing (lists, markdown, HTML),
  per-URL progress tracking, retry on failure, and batch add
- useUrlImport hook managing the full fetch lifecycle

Tests: 48 new tests (23 SSRF unit, 10 URL parser unit, 15 integration)
2026-05-11 22:41:47 +08:00
SnapOtter b06906025c refactor: improve tool processing, dropzone, seam carving, and format encoding
- Refactor use-tool-processor and use-pipeline-processor hooks
- Enhance dropzone component with improved UX
- Improve seam carving with better error handling and tests
- Add JXL format encoding support to format-encoders
- Update tool routes for consistent format handling
- Add dropzone unit tests
2026-05-11 21:57:40 +08:00
SnapOtter b7af25862a feat: add inline URL input to dropzone 2026-05-11 21:32:55 +08:00
SnapOtter 50d1f532d1 fix: block PDF uploads, fix PBM/PGM/PPM batch failures, add tests
- Added isImageFile() filter to all drop handlers (dropzone, collage,
  file-upload-area) so PDFs and non-image files are rejected on drop.
  Previously only the file picker's accept attribute filtered; drag-and-
  drop accepted anything.

- Added ppm, pgm, pbm to CLI_DECODED_FORMATS in file-validation.ts.
  These formats were missing, causing Sharp metadata checks to fail for
  some files during batch validation, which silently dropped them from
  results ("File not found in batch results").

- Added integration tests for PBM, PGM, PPM, TIFF, QOI, JP2, SVGZ
  single-file processing, plus a test confirming PDF is rejected.
2026-05-11 17:33:51 +08:00
SnapOtter aec1e91c5a fix: add .avif to all file picker accept strings
AVIF was missing from expandAccept() and every inline accept attribute,
causing the OS file picker to gray out .avif files. Drag-and-drop was
unaffected because it bypasses the accept filter. Added .avif to
dropzone.tsx expandAccept (covers all Dropzone pickers) plus 12 inline
accept strings across tool settings, pages, and file-upload-area.
2026-05-11 16:59:49 +08:00
SnapOtter 5c9fa2de49 feat: add decode pipelines for JP2, EPS, QOI, DDS, CUR, DPX, FITS, PPM, SVGZ, APNG
Add input decode support for 10 new image format families:

- JPEG 2000 (JP2/J2K): opj_decompress with ImageMagick fallback
- EPS: ImageMagick + Ghostscript delegate with 50MB size guard
- DDS: ImageMagick decode, first frame extraction
- CUR: reuses ICO decoder (structurally identical)
- DPX/Cineon: ImageMagick with sRGB colorspace conversion
- FITS: ImageMagick with normalize + sRGB conversion
- QOI: stub decoder (real codec deferred to Task 4)
- PPM/PGM/PBM/PFM: Sharp-native via libvips (no CLI decoder needed)
- SVGZ: gzip decompression with bomb protection before SVG sanitization
- APNG: accepted via extension, decoded as PNG first frame by Sharp

Updates magic bytes, MIME mappings, and frontend accept lists across
all file picker entry points (dropzone, tool page, file upload, editor).
2026-05-08 00:05:50 +08:00
ashim-hq d299aa8a72 feat: rebrand user-facing strings from ashim to SnapOtter 2026-04-24 14:47:17 +08:00
ashim-hq b03c428e4f fix: prevent pipeline preview dropzone from clipping at bottom
Dropzone had a hardcoded min-h-[400px] that overflowed the preview
panel's h-[38%] constraint. Add compact prop for constrained contexts.
2026-04-23 22:08:20 +08:00
ashim-hq 2aadb66031 feat: add support for JXL, Camera RAW, ICO, TGA, PSD, EXR, HDR image formats
Extends the platform to handle 7 new image format families alongside
the existing AVIF support gap-fill. Uses the established HEIC decoder
pattern (CLI decode → PNG → Sharp) for formats Sharp can't handle
natively: Camera RAW via dcraw_emu/LibRaw, PSD/TGA/EXR/HDR via
ImageMagick. JXL and ICO are Sharp-native. Adds server-side preview
for non-browser-displayable formats and JXL as a new convert output
target. All 27 validateImageBuffer callers updated with filename for
extension-based format detection.
2026-04-21 09:59:57 +08:00
Siddharth Kumar Sah 85b1cfc10a chore: rename Stirling-Image to ashim across entire codebase
Complete rebrand from Stirling-Image to ashim following the project
move to https://github.com/ashim-hq/ashim.

Changes across 117 files:
- Package scope: @stirling-image/* → @ashim/*
- GitHub URLs: stirling-image/stirling-image → ashim-hq/ashim
- Docker Hub: stirlingimage/stirling-image → ashimhq/ashim
- GitHub Pages: stirling-image.github.io → ashim-hq.github.io
- All branding text: "Stirling Image" → "ashim"
- Docker service/volumes/user: stirling → ashim
- Database: stirling.db → ashim.db
- localStorage keys: stirling-token → ashim-token
- Environment variables: STIRLING_GPU → ASHIM_GPU
- Python cache dirs: .cache/stirling-image → .cache/ashim
- SVG filter IDs, test prefixes, and all other references
2026-04-14 20:55:42 +08:00
Siddharth Kumar Sah 6f5283019b feat: full HEIF/HEIC support, content-aware resize performance fix, UI improvements
- Add bidirectional HEIF support: decode (input) and encode (output) via system heif-convert/heif-enc
- Add server-side WebP preview generation for non-browser-previewable formats (HEIC, TIFF)
- Fix content-aware resize failing on HEIF input (decode before passing to caire)
- Fix content-aware resize timeout on large images by downscaling to max 1200px and using JPEG intermediate
- Add HEIF as target format in convert tool
- Add loading spinner for HEIF preview decode in file store
- Fix file picker not accepting HEIF files (explicit .heic,.heif,.hif extensions)
- Extend frontend timeout for medium tools to 180s with 45s progress animation
- Redesign rotate controls with preset buttons and compact flip section
- Remove misleading savings percentage from convert tool
2026-04-11 23:27:44 +08:00
Siddharth Kumar Sah 627ff8a82c chore: remove internal docs from repo, update public documentation
Remove docs/superpowers/, .claude/ config, and PRD.md from version
control (kept locally via .gitignore). Update README, CHANGELOG,
VitePress docs, and .env.example to reflect recent features: Files
page, teams, admin settings, persistent storage, and various API
improvements.
2026-03-26 01:11:40 +08:00
Siddharth Kumar Sah 585d66f0c9 refactor: rename Tool.alpha to Tool.experimental 2026-03-26 01:10:51 +08:00
Siddharth Kumar Sah 1a22522349 feat(web): add before/after image comparison slider component
Draggable split-view slider with clip-path reveals original vs processed
image. Shows file size badges with savings percentage. Supports pointer
events for both mouse and touch. Integrated into tool-page to replace
dropzone after processing completes. Updated file-store with
originalBlobUrl for comparison. Enhanced dropzone with multi-file count
badge and file list display.
2026-03-22 04:03:30 +08:00
Siddharth Kumar Sah e920021da1 feat: add Stirling-PDF-style layout with sidebar, tool panel, dropzone, and theme toggle 2026-03-22 03:01:23 +08:00