Snapshots: in-editor checkpoints of the full edit state - #1335
Snapshots: in-editor checkpoints of the full edit state#1335SandeepSubba wants to merge 5 commits into
Conversation
|
Nice PR! Some questions:
Thanks a lot! |
Addresses review on PR CyberTimon#1335: - Perf: executeApplyAdjustments structuredClone'd the full adjustments, including adjustments.snapshots, and shipped it to apply_adjustments on every interactive tick. Each snapshot is a full edit-state copy (and can nest base64 mask/AI-patch data), and the existing mask/patch stripping only reached top-level masks, not the copies inside snapshots. Destructure snapshots out before cloning; the renderer never reads them and they still persist through the separate sidecar save path. - Styling: snapshot rows now use the same tokens as preset rows (rounded-lg, bg-surface, hover:bg-surface-hover, small secondary metadata) so they read as part of the panel rather than bolted on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 5b0777b)
|
Thanks for the review! Good catches — pushed a fix for both (cd006d2). 1. Snapshots on every applyAdjustments tick — you're right, and fixed.
The fix just destructures const { snapshots: _snapshots, ...renderAdjustments } = currentAdjustments;
const payload = structuredClone(renderAdjustments);Unlike masks/AI patches, snapshots don't need the send-once hydration dance — the renderer never reads them at all, so they can be dropped outright. They still persist fine because that goes through the separate sidecar save path ( 2. Styling to match presets — done. Snapshot rows now use the same tokens as preset rows ( tsc clean (no new errors over baseline). |
|
Please style them as looks (exactly like presets). Don't duplicate too much unnecessary code. Try to reuse some logic. :) Thanks! My goal is to have the presets panel like this: Snapshots (titel) Presets (titel) What do you think about this? If you prefer snapshots should be text only, we can move it into the dropdown component imo. |
|
Done — snapshots are now styled exactly like presets, reusing the same card and preview pipeline rather than duplicating either. What changed
Rename (this came up in testing): snapshots are user-renameable — hover a card for a pencil, or right-click → Rename. The name edits inline in place (Enter saves, Esc cancels), so it stays within the card. Kept snapshots as cards rather than moving them into the dropdown, since with thumbnails they read as looks now. Happy to adjust the section spacing/titles if you'd like them tighter. |
Adds named snapshots stored inside the sidecar, so you can checkpoint an
edit, keep working, and flip between looks without leaving the editor.
Complements library-level Virtual Copies (Duplicate Image > Virtual Copy):
virtual copies are parallel library entries for deliverables; snapshots
are in-place checkpoints while working on one entry.
- New "Snapshots" section at the top of the Presets panel: save the
current edit with one click, click a snapshot to apply it, context menu
for apply / overwrite-with-current / rename / delete
- Schema: adjustments.snapshots[] = {id, name, createdAt, state}, where
state is a full adjustments snapshot (masks, AI edits, crop included).
The sidecar stores adjustments as raw JSON, so this round-trips with no
backend schema change; snapshots are excluded from copy/paste and
multi-select sync via the existing copyable-key whitelist
- Applying/renaming/deleting go through setAdjustments, so every snapshot
operation is undoable and auto-saved like any other edit
- Reset Adjustments preserves snapshots, so wiping the working state
cannot destroy checkpoints
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Addresses review on PR CyberTimon#1335: - Perf: executeApplyAdjustments structuredClone'd the full adjustments, including adjustments.snapshots, and shipped it to apply_adjustments on every interactive tick. Each snapshot is a full edit-state copy (and can nest base64 mask/AI-patch data), and the existing mask/patch stripping only reached top-level masks, not the copies inside snapshots. Destructure snapshots out before cloning; the renderer never reads them and they still persist through the separate sidecar save path. - Styling: snapshot rows now use the same tokens as preset rows (rounded-lg, bg-surface, hover:bg-surface-hover, small secondary metadata) so they read as part of the panel rather than bolted on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 5b0777b)
Addresses review feedback (style snapshots exactly like presets, reuse logic):
- Extract the preset card into a shared PresetItemDisplay component. Presets and
snapshots now render through the same card; a subtitle prop switches it to
snapshot mode (date instead of TOOL/STYLE, no preset-only badges) and a nameSlot
prop lets the name become an inline input for renaming.
- Snapshots reuse the preset preview pipeline: each is fed in as a preset-shaped
{ id, adjustments: state } item, so its thumbnail is the current image rendered
with that snapshot's edit state. The preview id embeds createdAt, so overwriting
a snapshot refreshes its thumbnail and the stale one is revoked for free.
- Presets panel is now a 'Snapshots' section (title + cards) above a 'Presets'
section (title + cards), matching the requested layout.
- Snapshots are renameable: hover a card for a pencil, or right-click > Rename;
the name edits inline in place (Enter saves, Esc cancels).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pre-existing formatting drift on main (from the CyberTimon#1339 Android LUT fix) that fails cargo fmt --check in CI; collapses three multi-line calls that fit on one line. Not part of the snapshots feature. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fcd8153 to
20f2f08
Compare
- Collapse the four snapshot mutators onto one updateSnapshots(list, adj) helper. - Drop the redundant pre-filter in generateSnapshotPreviews (enqueuePreviews already skips already-generated ids). - Trim over-explanatory comments. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

What
Adds Snapshots — named checkpoints of the complete edit state, stored inside the sidecar — so you can save a look, keep editing, and flip between looks without leaving the editor.
How this relates to Virtual Copies
RapidRAW already has Virtual Copies (Duplicate Image → Virtual Copy), which create a parallel library entry with its own sidecar — great for deliverables you want side by side in the grid, rated and exported independently:
Snapshots cover the other half of that workflow (Lightroom ships both concepts for the same reason): checkpoints while working on one entry. Try a bolder grade, keep the safe state one click away, overwrite a checkpoint as the edit evolves — no extra grid entries, and the looks travel inside the one sidecar. An earlier draft of this PR (#1334) was withdrawn because it didn't make this distinction clear.
UI
A Snapshots section at the top of the Presets panel:
Design notes
adjustments.snapshots[]({id, name, createdAt, state}); the sidecar stores adjustments as raw JSON, so they round-trip untouched.setAdjustments, participating in history and the normal save path.reset_adjustments_for_pathspreserves thesnapshotskey — clearing the working edit can't destroy checkpoints.Testing
cargo check,cargo fmt --check, and clippy on the touched code clean;tscintroduces no new errors🤖 Generated with Claude Code