Conversation
Ports the ~800-line Electron main process to Rust while keeping the React/Redux renderer intact behind the existing ImagineAPI bridge: - src-tauri: commands (ready/file_add/file_select/optimize/save/sync/ store/about/progress-bar/open_external), events (FILE_SELECTED/SAVE/ SAVED), content-addressed tmp cache, dynamic localized menu (labels travel with SYNC so locales stay frontend-only), single-instance, macOS Opened + argv file associations, JSON config store - Phase 1 image pipeline on the image crate (png/jpg/webp/bmp, resize modes); mozjpeg/quantization/avif/heic parity lands in Phase 2 - modules/bridge/tauri.ts implements ImagineAPI over invoke/listen: paths are converted with convertFileSrc (asset protocol scoped to $TEMP/imagine), store-get stays sync via a boot-primed config cache, update check moves to a renderer-side GitHub API fetch - native drag-drop via onDragDropEvent (webviews have no File.path), data-tauri-drag-region on the action bar, async bridgeReady boot - jest stubs @tauri-apps/api (ESM); suite results match baseline macOS bundle: 6.7MB .app / 3.0MB dmg (Electron: ~100MB+). Run with: npm run tauri:dev / npm run tauri:build Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Feature parity with the sharp/libvips backend, statically linked: - JPEG: mozjpeg (same encoder as sharp's mozjpeg:true), quality + progressive; output size verified within 1% of sharp on a 12MP test (134.0KB vs 133.2KB at q80/resize-1600) - PNG: palette quantization for the `colors` option β quantette (Wu+kmeans+Floyd-Steinberg, MIT) for opaque images, NeuQuant for RGBA-with-alpha; interlaced output unsupported by the png crate (documented divergence). imagequant (GPL-3.0) noted in README as the quality upgrade if relicensing is acceptable - WebP: lossy libwebp; AVIF: ravif/rav1e with EXIF embedding - HEIC/AVIF input: macOS ImageIO (sips) decode to a cached PNG intermediate that doubles as the HEIC preview (sourcePreviewUrl, same contract as the Electron backend); other platforms error clearly until a WIC/webview fallback lands - resize: fast_image_resize SIMD Lanczos3, three modes ported with no-enlargement semantics - metadata: EXIF/ICC extract+embed via img-parts for jpg/png/webp - 8 pipeline tests incl. HEIC round-trip and metadata roundtrip; optional bench harness (IMAGINE_BENCH_SRC) macOS bundle with all codecs: 9.0MB .app / 4.0MB dmg. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two majors and a batch of parity gaps confirmed by a 4-dimension
review (IPC contract, Electron regression, Rust correctness, UX flows)
with per-finding adversarial verification:
- Fix pending-files flush race: the ready check and pending-queue
insert now happen under one mutex, so files ingested around renderer
READY can no longer be dropped or stuck
- Restore alone-mode close interception: Tauri never fires beforeunload
on window close, so the bridge replays onCloseRequested as a
cancelable synthetic beforeunload (Alone.tsx unchanged, works on both
runtimes); add core:window:allow-destroy capability
- READY now carries localized menu labels: the app menu is localized
from first paint instead of after the first Redux sync
- Add File > Open Folder⦠(folder_select command): Electron's Open
dialog allowed picking directories on macOS, Tauri's cannot mix
files and folders
- AVIF export converts pixels to sRGB via qcms when the source has an
ICC profile (ravif cannot embed ICC; colors now match sharp output)
- Gate heic/avif ingest + dialog filter behind native_decode support
so non-macOS builds don't accept files they cannot decode
- reext parity: 'photo.jpeg' -> png now appends ('photo.jpeg.png')
like the TS original; add reext unit tests
- Update check only fires on semver-greater remote (was: any string
difference, could flag a downgrade right after a version bump)
- Move @tauri-apps/api to devDependencies (it is bundled by Vite;
keeping it in dependencies shipped it inside the Electron asar)
cargo test 8 passed; tsc/vite/jest match baseline; smoke-tested.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
One code path for opaque and alpha images (pngquant engine, same as sharp), Floyd-Steinberg dithering built in; drops quantette and color_quant. libimagequant is GPL-3.0-or-later β noted in README that distributed Tauri builds are effectively GPL, per the decision to keep the project open source. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Platforms without macOS ImageIO now decode in the webview before
optimize runs: libheif-js (WASM, lazy-loaded 1.4MB chunk) for HEIC,
the webview's own codec via canvas for AVIF (WebView2 is Chromium).
Raw RGBA travels over binary IPC (has_intermediate / read_source /
write_intermediate commands, id/dims in headers) and lands as the same
{id}.1.png intermediate the pipeline and the HEIC preview already use.
Ingest and dialog filters accept heic/avif on all platforms again.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Frameless window on Windows (decorations(false) + shadow) with custom minimize / maximize / close buttons drawn in the action bar, Windows-styled (red close hover); close() goes through the close-requested path so alone-mode interception still works. The bridge exposes windowControls only where needed, so macOS traffic lights and Electron's titleBarOverlay are untouched - Fix drag region: data-tauri-drag-region only applies to the exact mousedown target, and the bar's biggest surfaces (.blank spacer, title text) lacked it β dragging now works across the whole bar, double-click-to-maximize included Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous set mixed Material fill glyphs, Material Symbols
(960-viewBox), and ad-hoc shapes with viewBoxes from 8x8 to 147x147.
All 20 icons are now hand-drawn on the same 24x24 grid with 2px
round-cap strokes in currentColor; the processing spinner and rainbow
keep their color but use the same stroke language and a matched flat
palette. Explicit fill/stroke attributes on each group override the
`.icon { fill: currentColor }` CSS, so no component changes needed.
Removes unused resize1.svg. Same benefit applies to the Electron
build since the renderer is shared.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root cause: core:window:default does NOT include allow-start-dragging (while internal-toggle-maximize is included), so every mousedown on a data-tauri-drag-region element invoked plugin:window|start_dragging and was silently denied by the ACL β the window never moved. Grant core:window:allow-start-dragging in the default capability. Also switch the action bar to data-tauri-drag-region="deep" (supported by this Tauri version's drag script): the entire bar subtree drags, clickable elements are excluded automatically, so Tooltip wrapper spans and future children can't create dead zones. Poppers render through a portal and are unaffected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replaces the cramped OptionsPanel popper with a fullscreen settings page (ESC / back to close), reorganized around what the data model already meant: - Format conversion: one input->output mapping row per source format, now including HEIC and BMP which had no mapping UI at all (the old panel's heic handler even wrote to the jpg entry by mistake) - Output options: encoding parameters keyed by OUTPUT format (JPEG quality, PNG colors, WebP/AVIF quality) β matching how task options are actually resolved (defaultOptions[exportExt]) - General: keep metadata, progressive/interlaced, update check, plus two new settings: UI language override (14 locales, stored in localStorage, applied on reload) and parallel task count (auto = cores-1, read live by the job runner) New locale keys added to en/zh-CN; other languages fall back to English. Pure UI reorganization β reducer/state shape unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Settings title now sits on the same row as the modal back button in a fixed header strip (which is also a drag region, so the window stays draggable while settings cover the action bar) - Format conversion rows flow in a two-column grid; the compact task-card select style is overridden with a full-width, normal-size, left-aligned variant inside the grid - macOS traffic lights moved from y=17 to y=19 to vertically center the 12px buttons in the 50px bar Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Rust backend has full feature parity, so the Node main process goes away entirely: backend/, optimizers/, bootstrap, preload, async-call, dev launcher, file-utils/env and their tests. Node.js remains a build tool only (Vite bundles the renderer) β the shipped app contains no Node runtime. - package.json: 10 runtime deps (sharp, electron-log/store/updater, fs-extra, file-type, heic-decode, ...) and 22 dev deps (electron, electron-builder, webpack-era loaders, ...) removed β 638 packages gone from node_modules; electron scripts and builder config replaced by dev/build = tauri dev/build - electron type imports replaced with local IUpdateInfo and ILogger; setProgressBar/store-get/store-set/about are now typed IPC channels (killing the @ts-ignore workarounds) - fixed the two long-failing jest tests: job-runner now mocks the bridge (optimize moved off apis long ago), store.test expectations updated for the avif/heic/bmp formats β suite is 18/18 green - eslint cleanup: --fix plus manual fixes for @ts-nocheck, unused members and naming β npm run lint passes with 0 errors for the first time - README build section rewritten for the Tauri toolchain Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- ci.yml: on every push/PR β typecheck, eslint, jest and a Vite build (frontend job), plus cargo test and a debug build against webkit2gtk-4.1 (rust job, with rust-cache) - release.yml: on v* tags β tauri-action builds and uploads bundles for macOS arm64 + x86_64, Windows and Linux to the GitHub release - removes the electron-builder workflow Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sync the app version across `package.json`, `src-tauri/Cargo.toml`, and `src-tauri/tauri.conf.json`. Also add a `.DS_Store` ignore entry for macOS metadata files.
rav1e's asm feature assembles x86_64 SIMD with NASM, which GitHub runners don't ship β the Linux/Windows/mac-x64 builds failed while local arm64 builds (NEON path) never hit it. ilammy/setup-nasm covers all three OSes; disabling the asm feature instead would make AVIF encoding several times slower. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New bundle job builds release packages on every push (Windows NSIS/MSI, macOS dmg, Linux AppImage/deb) and uploads them to the run's Artifacts section, so a build can be tried on another machine without any local toolchain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The primary action now sits top-right in the fixed header β always visible instead of requiring a scroll to the bottom β leaving the footer with just the version tag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The bundle matrix now builds both mac architectures via explicit --target triples (per-target output paths, per-entry rust-cache keys) alongside Windows and Linux - The bare Windows exe rides in the artifact as the portable (no-install) build β Tauri embeds the frontend in the binary, so it runs anywhere with WebView2 present - release.yml attaches the same portable exe to tagged releases as ImaginePlus_<version>_x64-portable.exe (tauri-action only uploads bundler outputs) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.