simple undo/redo of application state

This commit is contained in:
Joeri Exelmans 2025-05-12 16:45:17 +02:00
parent 8744bad0b8
commit 1f831b0517
2 changed files with 48 additions and 9 deletions

View file

@ -82,25 +82,64 @@ const tripleFunctionCallEditorState: EditorState = {
}
export function App() {
// const [state, setState] = useState<EditorState>(initialEditorState);
// const [state, setState] = useState<EditorState>(nonEmptyEditorState);
const [state, setState] = useState<EditorState>(tripleFunctionCallEditorState);
const [history, setHistory] = useState([initialEditorState]);
// const [history, setHistory] = useState([nonEmptyEditorState]);
// const [history, setHistory] = useState([tripleFunctionCallEditorState]);
const [future, setFuture] = useState<EditorState[]>([]);
const pushHistory = (s: EditorState) => {
console.log('pushHistory');
setHistory(history.concat([s]));
setFuture([]);
};
const onUndo = () => {
setFuture(future.concat(history.at(-1)!)); // add
setHistory(history.slice(0,-1)); // remove
};
const onRedo = () => {
setHistory(history.concat(future.at(-1)!)); // add
setFuture(future.slice(0,-1)); // remove
};
const onKeyDown = (e) => {
if (e.key === "Z" && e.ctrlKey) {
if (e.shiftKey) {
if (future.length > 0) {
onRedo();
}
}
else {
if (history.length > 1) {
onUndo();
}
}
e.preventDefault();
}
};
useEffect(() => {
window['APP_STATE'] = state;
window['APP_STATE'] = history;
// console.log("EDITOR STATE:", state);
}, [state]);
}, [history]);
useEffect(() => {
window.onkeydown = onKeyDown;
}, []);
return (
<>
<header>
{/* Header content */}
<button disabled={history.length===1} onClick={onUndo}>Undo ({history.length-1}) [Ctrl+Z]</button>
<button disabled={future.length===0} onClick={onRedo}>Redo ({future.length}) [Ctrl+Shift+Z]</button>
</header>
<main>
<Editor
state={state}
setState={setState}
state={history.at(-1)!}
setState={pushHistory}
onResolve={() => {console.log("toplevel resolved")}}
onCancel={() => {console.log("toplevel canceled")}}
/>

View file

@ -3,7 +3,7 @@
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,