From 73580b368bca0f7887f8ccdcbcb58dd672764ea3 Mon Sep 17 00:00:00 2001 From: nanoblit Date: Fri, 1 Sep 2023 14:40:23 +0200 Subject: [PATCH] #3005 - Fix undo edgecase --- .../ketcher-react/src/script/editor/Editor.ts | 22 +++++++++++----- .../src/script/ui/state/editor/index.js | 26 ++++++++++++++----- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/packages/ketcher-react/src/script/editor/Editor.ts b/packages/ketcher-react/src/script/editor/Editor.ts index fc292fa382..dd9f8c3fe7 100644 --- a/packages/ketcher-react/src/script/editor/Editor.ts +++ b/packages/ketcher-react/src/script/editor/Editor.ts @@ -512,7 +512,7 @@ class Editor implements KetcherEditor { this.historyStack.shift(); } this.historyPtr = this.historyStack.length; - this.event.change.dispatch(action); // TODO: stoppable here + this.event.change.dispatch({ action }); // TODO: stoppable here } this.render.update(false, null, options); } @@ -525,7 +525,11 @@ class Editor implements KetcherEditor { }; } - undo() { + private async resolveDispatch() { + return new Promise((resolve) => setTimeout(resolve, 0)); + } + + async undo() { if (this.historyPtr === 0) { throw new Error('Undo stack is empty'); } @@ -536,9 +540,11 @@ class Editor implements KetcherEditor { this.selection(null); if (this._tool instanceof toolsMap.paste) { - this.event.change.dispatch(); + this.event.change.dispatch({ isUndoOrRedo: true }); } + await this.resolveDispatch(); + this._tool?.updatePreview?.(); this.historyPtr--; @@ -546,11 +552,11 @@ class Editor implements KetcherEditor { const action = stack.perform(this.render.ctab); this.historyStack[this.historyPtr] = action; - this.event.change.dispatch(action); + this.event.change.dispatch({ action, isUndoOrRedo: true }); this.render.update(); } - redo() { + async redo() { if (this.historyPtr === this.historyStack.length) { throw new Error('Redo stack is empty'); } @@ -562,15 +568,17 @@ class Editor implements KetcherEditor { this.selection(null); if (this._tool instanceof toolsMap.paste) { - this.event.change.dispatch(); + this.event.change.dispatch({ isUndoOrRedo: true }); } + await this.resolveDispatch(); + this._tool?.updatePreview?.(); const action = this.historyStack[this.historyPtr].perform(this.render.ctab); this.historyStack[this.historyPtr] = action; this.historyPtr++; - this.event.change.dispatch(action); + this.event.change.dispatch({ action, isUndoOrRedo: true }); this.render.update(); } diff --git a/packages/ketcher-react/src/script/ui/state/editor/index.js b/packages/ketcher-react/src/script/ui/state/editor/index.js index 0cb42081cc..6b6253d503 100644 --- a/packages/ketcher-react/src/script/ui/state/editor/index.js +++ b/packages/ketcher-react/src/script/ui/state/editor/index.js @@ -46,23 +46,37 @@ export default function initEditor(dispatch, getState) { // eslint-disable-line no-shadow const state = global.currentState; const activeTool = state.actionState.activeTool.tool; - if (activeTool === 'select') return; + + if (activeTool === 'select') { + return; + } + const selectMode = state.toolbar.visibleTools.select; const resetOption = state.options.settings.resetToSelect; - if (resetOption === true || resetOption === activeTool) + + if (resetOption === true || resetOption === activeTool) { // example: 'paste' dispatch({ type: 'ACTION', action: acts[selectMode].action }); - else updateAction(); + } else { + updateAction(); + } } return { onInit: (editor) => { dispatch({ type: 'INIT', editor }); }, - onChange: (action) => { - if (action === undefined) sleep(0).then(() => dispatch(resetToSelect)); + onChange: ({ action, isUndoOrRedo }) => { + if (!action) { + return; + } + + if (isUndoOrRedo) { + return updateAction(); + } + // new tool in reducer - else dispatch(resetToSelect); + dispatch(resetToSelect); }, onSelectionChange: () => { updateAction();