feat(ui): add canvas snapshot save/restore functionality#8978
feat(ui): add canvas snapshot save/restore functionality#8978GGSSKK wants to merge 13 commits intoinvoke-ai:mainfrom
Conversation
Add ability to save and restore canvas state snapshots, allowing users to preserve their canvas layout at any point and restore it later. This is useful when the canvas freezes or resets unexpectedly. Backend: - Add get_keys_by_prefix and delete_by_key to client_state persistence - Add corresponding API endpoints Frontend: - Add canvasSnapshotRestored reducer to canvasSlice - Add useCanvasSnapshots hook for snapshot CRUD operations - Add CanvasToolbarSnapshotMenuButton with save/restore UI - Add i18n keys for snapshot feature - Regenerate API schema types Tests: - Add tests for new client_state endpoints (prefix search, key deletion) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
A very welcome feature. Also useful if you want temporarily switch to something else. |
|
Here's some finding done with LLM regarding this PR as a heads up for reviewer. Review Pass 1: Broader Review
Open questions:
Review Pass 2: Issues Actually Introduced By This PR
Open questions:
As an addition:
Open question:
|
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Preserve current modelBase on snapshot restore to prevent bbox desync with the active model (mirrors resetState pattern) - Exclude snapshot restore from undo history so it cannot be accidentally undone - Migrate manual fetch calls to RTKQ endpoints (clientState.ts) so snapshots go through the shared API transport layer with proper auth, session-expiry handling and sliding-window token refresh - Validate referenced images on restore and warn when some are missing - Detect incompatible (schema-changed) snapshots and show a specific error message instead of a generic failure toast - Disable snapshot restore while the canvas is staging to prevent entity ID conflicts with in-progress generations - Sort snapshot list by updated_at instead of rowid so re-saved snapshots appear at the top - Add pre-flight backend reachability check before image validation to avoid false "missing images" warnings when offline Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Thanks for the thorough review! Addressed each point in 368fe74. Issues fixed in this PR
Additional fixes
Issues not in this PR's scopeThe three auth/user-management findings (PATCH last-admin guard, edit-user stale state, 400 vs 404) are real bugs, but they were introduced by #8937 — this PR's only auth change is the Open questions answered
Notes from main merge
|
…save-restore # Conflicts: # invokeai/frontend/web/src/features/controlLayers/store/canvasSlice.ts
…le utility Remove the local collectImageNames from useCanvasSnapshots and reuse the shared, more comprehensive version from canvasProjectFile.ts that was introduced by the canvas project save/load feature (invoke-ai#8917). Snapshots don't include global ref images, so an empty array is passed for that parameter. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…m/GGSSKK/InvokeAI into feat/canvas-snapshot-save-restore
|
Merged with latest main and resolved a conflict in Also consolidated One thing to note: the |
…default name chars - Escape %, _, \ in client_state prefix query to prevent accidental wildcard matching - Confirm before overwriting an existing snapshot instead of silently replacing it - Use - instead of / and : in the default snapshot name to avoid key separator clashes
Pfannkuchensack
left a comment
There was a problem hiding this comment.
Works good.
Added:
- Escape %, _, \ in client_state prefix query to prevent accidental wildcard matching
- Confirm before overwriting an existing snapshot instead of silently replacing it
- Use - instead of / and : in the default snapshot name to avoid key separator clashes
Preserve modelBase, call syncScaledSize, and exclude from undo history to avoid bbox/model desync on project load — same pattern already used by canvasSnapshotRestored.
|
I fixed the found in canvasProjectRecalled. |
Summary
Adds a canvas snapshot save/restore button to the toolbar (camera icon). Users can save the current canvas state at any time and restore it later — useful when the canvas resets unexpectedly due to freezes or reloads.
Reuses the existing
client_stateAPI with acanvas_snapshot:key prefix, keeping changes minimal.snapshot.mp4
Related Issues / Discussions
Related to #6554 (canvas state not persisting). This provides a manual workaround by letting users explicitly save/restore canvas state.
Changes
Snapshot save/restore (original)
CanvasToolbarSnapshotMenuButtoncomponent with save input, restore list, and per-snapshot deleteuseCanvasSnapshotshook backed byclient_statepersistence APIcanvasSnapshotRestoredreducer incanvasSliceReview feedback (368fe74)
modelBaseinstead of blindly overwriting it from the snapshot. Prevents bbox grid/dimension desync when the user switches models after saving. Follows the same pattern asresetState.canvasSnapshotRestoredis filtered out of redux-undo history so Undo cannot accidentally discard a just-restored snapshot.fetch+getAuthHeaders()with a newclientState.tsRTKQ endpoint file. Snapshots now go throughdynamicBaseQuery, gaining automatic auth token injection, 401 session-expiry handling, and sliding-window token refresh.image_namereferences (including regional guidance reference images) and checks their existence viagetImageDTOSafebefore restoring. Shows a warning toast with the count of missing images.ZodErrorfromzCanvasState.parse()and shows a specific "incompatible version" error instead of a generic failure toast.ORDER BY rowid DESC→ORDER BY updated_at DESCinget_keys_by_prefixso re-saved snapshots move to the top of the list.getAppVersion) before image validation to avoid false "missing images" warnings when offline.FetchOnReconnecttag to the snapshot list query so it auto-refreshes after websocket reconnect.QA Instructions
Merge Plan
Simple merge. No DB schema changes — uses existing
client_statetable. New RTKQ endpoint file (clientState.ts) added.Checklist
What's Newcopy (if doing a release after this PR)