diff --git a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts index cf85bd10b..7d3966fd1 100644 --- a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts +++ b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorState.ts @@ -658,6 +658,12 @@ export function useUiEditorState(initialState: State = EMPTY_UI_EDITOR_STATE) { [], ); + const runWithStateLockedAndHistory = useCallback( + async (operation: (snapshot: State) => Promise): Promise => + runInHistoryTransaction(() => runWithStateLocked(operation)), + [runInHistoryTransaction, runWithStateLocked], + ); + const setImageName = useCallback( (id: UIDesignImageId, name: string): UiEditorOperationResult => { const blocked = guard(); @@ -1544,6 +1550,7 @@ export function useUiEditorState(initialState: State = EMPTY_UI_EDITOR_STATE) { endHistoryTransaction, cancelHistoryTransaction, runInHistoryTransaction, + runWithStateLockedAndHistory, resetHistory, isLocked, diff --git a/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts b/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts index e7a085ec6..29dc33c6a 100644 --- a/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts +++ b/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts @@ -942,7 +942,7 @@ export function useUiEditorSession( setSuggestionStatus(null); setIsSuggesting(true); try { - await editor.runWithStateLocked(async (snapshot) => { + await editor.runWithStateLockedAndHistory(async (snapshot) => { const suggestions = await invoke( 'suggest_ui_design_semantic', { projectPath, state: snapshot }, @@ -965,7 +965,7 @@ export function useUiEditorSession( setRecognitionStatus(null); setIsRecognizing(true); try { - await editor.runWithStateLocked(async (snapshot) => { + await editor.runWithStateLockedAndHistory(async (snapshot) => { const result = await invoke('recognize_ui', { projectPath, state: snapshot, @@ -990,7 +990,7 @@ export function useUiEditorSession( setMergeStatus(null); setIsMerging(true); try { - await editor.runWithStateLocked(async (snapshot) => { + await editor.runWithStateLockedAndHistory(async (snapshot) => { const result = await invoke('merge_ui', { state: snapshot }); editor.replaceState(applyMergeResult(snapshot, result)); setSelectedNodeId(null); @@ -1008,7 +1008,7 @@ export function useUiEditorSession( setBindingStatus(null); setIsBinding(true); try { - await editor.runWithStateLocked(async (snapshot) => { + await editor.runWithStateLockedAndHistory(async (snapshot) => { const allSpriteIds = Object.keys(snapshot.sprite_assets); const batches: string[][] = []; for ( @@ -1228,6 +1228,11 @@ export function useUiEditorSession( deleteNode, openClearDialog: () => setClearOpen(true), }, + history: { + ...editor.historyState, + undo: editor.undo, + redo: editor.redo, + }, inspector: { isLocked: editor.isLocked, projectPath,