- CommandHistory class with execute/undo/redo, 50-step max, redo-clear on new action
- PlaceBlockCommand, MoveBlockCommand, ResizeBlockCommand, DeleteBlockCommand
- setCurrentShowId() module-level function for backend sync routing
- syncBlock() fire-and-forget fetch helper for backend sync
- POST/PATCH/DELETE /api/shows/{show_id}/tracks/{device_id}/blocks endpoints
- timeline router registered in main.py with prefix=/api
37 lines
1020 B
JavaScript
37 lines
1020 B
JavaScript
// CommandHistory — undo/redo stack for timeline block mutations
|
|
// Supports min 50 steps. execute() clears redo stack to prevent branching corruption.
|
|
|
|
export class CommandHistory {
|
|
constructor(maxSteps = 50) {
|
|
this.undoStack = [];
|
|
this.redoStack = [];
|
|
this.maxSteps = maxSteps;
|
|
}
|
|
|
|
execute(cmd) {
|
|
cmd.execute();
|
|
this.undoStack.push(cmd);
|
|
if (this.undoStack.length > this.maxSteps) this.undoStack.shift();
|
|
this.redoStack = []; // clear redo on new action (prevents branching corruption)
|
|
}
|
|
|
|
undo() {
|
|
const cmd = this.undoStack.pop();
|
|
if (!cmd) return false;
|
|
cmd.undo();
|
|
this.redoStack.push(cmd);
|
|
return true;
|
|
}
|
|
|
|
redo() {
|
|
const cmd = this.redoStack.pop();
|
|
if (!cmd) return false;
|
|
cmd.execute();
|
|
this.undoStack.push(cmd);
|
|
return true;
|
|
}
|
|
|
|
get canUndo() { return this.undoStack.length > 0; }
|
|
get canRedo() { return this.redoStack.length > 0; }
|
|
}
|