chore: Remove editingLinearElement (#9771)

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
Márk Tolmács
2025-07-24 17:02:21 +02:00
committed by GitHub
parent 416da62138
commit d6a934ed19
25 changed files with 348 additions and 398 deletions

View File

@@ -2158,9 +2158,14 @@ class App extends React.Component<AppProps, AppState> {
public dismissLinearEditor = () => {
setTimeout(() => {
this.setState({
editingLinearElement: null,
});
if (this.state.selectedLinearElement?.isEditing) {
this.setState({
selectedLinearElement: {
...this.state.selectedLinearElement,
isEditing: false,
},
});
}
});
};
@@ -2856,15 +2861,15 @@ class App extends React.Component<AppProps, AppState> {
);
if (
this.state.editingLinearElement &&
!this.state.selectedElementIds[this.state.editingLinearElement.elementId]
this.state.selectedLinearElement?.isEditing &&
!this.state.selectedElementIds[this.state.selectedLinearElement.elementId]
) {
// defer so that the scheduleCapture flag isn't reset via current update
setTimeout(() => {
// execute only if the condition still holds when the deferred callback
// executes (it can be scheduled multiple times depending on how
// many times the component renders)
this.state.editingLinearElement &&
this.state.selectedLinearElement?.isEditing &&
this.actionManager.executeAction(actionFinalize);
});
}
@@ -4419,17 +4424,13 @@ class App extends React.Component<AppProps, AppState> {
if (event[KEYS.CTRL_OR_CMD] || isLineElement(selectedElement)) {
if (isLinearElement(selectedElement)) {
if (
!this.state.editingLinearElement ||
this.state.editingLinearElement.elementId !== selectedElement.id
!this.state.selectedLinearElement?.isEditing ||
this.state.selectedLinearElement.elementId !==
selectedElement.id
) {
this.store.scheduleCapture();
if (!isElbowArrow(selectedElement)) {
this.setState({
editingLinearElement: new LinearElementEditor(
selectedElement,
this.scene.getNonDeletedElementsMap(),
),
});
this.actionManager.executeAction(actionToggleLinearEditor);
}
}
}
@@ -5432,15 +5433,12 @@ class App extends React.Component<AppProps, AppState> {
if (
((event[KEYS.CTRL_OR_CMD] && isSimpleArrow(selectedLinearElement)) ||
isLineElement(selectedLinearElement)) &&
this.state.editingLinearElement?.elementId !== selectedLinearElement.id
(!this.state.selectedLinearElement?.isEditing ||
this.state.selectedLinearElement.elementId !==
selectedLinearElement.id)
) {
this.store.scheduleCapture();
this.setState({
editingLinearElement: new LinearElementEditor(
selectedLinearElement,
this.scene.getNonDeletedElementsMap(),
),
});
// Use the proper action to ensure immediate history capture
this.actionManager.executeAction(actionToggleLinearEditor);
return;
} else if (
this.state.selectedLinearElement &&
@@ -5505,8 +5503,8 @@ class App extends React.Component<AppProps, AppState> {
return;
}
} else if (
this.state.editingLinearElement &&
this.state.editingLinearElement.elementId ===
this.state.selectedLinearElement?.isEditing &&
this.state.selectedLinearElement.elementId ===
selectedLinearElement.id &&
isLineElement(selectedLinearElement)
) {
@@ -5561,7 +5559,7 @@ class App extends React.Component<AppProps, AppState> {
// shouldn't edit/create text when inside line editor (often false positive)
if (!this.state.editingLinearElement) {
if (!this.state.selectedLinearElement?.isEditing) {
const container = this.getTextBindableContainerAtPosition(
sceneX,
sceneY,
@@ -5859,8 +5857,8 @@ class App extends React.Component<AppProps, AppState> {
}
if (
this.state.editingLinearElement &&
!this.state.editingLinearElement.isDragging
this.state.selectedLinearElement?.isEditing &&
!this.state.selectedLinearElement.isDragging
) {
const editingLinearElement = LinearElementEditor.handlePointerMove(
event,
@@ -5874,14 +5872,14 @@ class App extends React.Component<AppProps, AppState> {
if (
editingLinearElement &&
editingLinearElement !== this.state.editingLinearElement
editingLinearElement !== this.state.selectedLinearElement
) {
// Since we are reading from previous state which is not possible with
// automatic batching in React 18 hence using flush sync to synchronously
// update the state. Check https://github.com/excalidraw/excalidraw/pull/5508 for more details.
flushSync(() => {
this.setState({
editingLinearElement,
selectedLinearElement: editingLinearElement,
});
});
}
@@ -6041,7 +6039,7 @@ class App extends React.Component<AppProps, AppState> {
if (
selectedElements.length === 1 &&
!isOverScrollBar &&
!this.state.editingLinearElement
!this.state.selectedLinearElement?.isEditing
) {
// for linear elements, we'd like to prioritize point dragging over edge resizing
// therefore, we update and check hovered point index first
@@ -7045,7 +7043,7 @@ class App extends React.Component<AppProps, AppState> {
if (
selectedElements.length === 1 &&
!this.state.editingLinearElement &&
!this.state.selectedLinearElement?.isEditing &&
!isElbowArrow(selectedElements[0]) &&
!(
this.state.selectedLinearElement &&
@@ -7116,8 +7114,7 @@ class App extends React.Component<AppProps, AppState> {
}
} else {
if (this.state.selectedLinearElement) {
const linearElementEditor =
this.state.editingLinearElement || this.state.selectedLinearElement;
const linearElementEditor = this.state.selectedLinearElement;
const ret = LinearElementEditor.handlePointerDown(
event,
this,
@@ -7131,10 +7128,6 @@ class App extends React.Component<AppProps, AppState> {
}
if (ret.linearElementEditor) {
this.setState({ selectedLinearElement: ret.linearElementEditor });
if (this.state.editingLinearElement) {
this.setState({ editingLinearElement: ret.linearElementEditor });
}
}
if (ret.didAddPoint) {
return true;
@@ -7235,11 +7228,11 @@ class App extends React.Component<AppProps, AppState> {
this.clearSelection(hitElement);
}
if (this.state.editingLinearElement) {
if (this.state.selectedLinearElement?.isEditing) {
this.setState({
selectedElementIds: makeNextSelectedElementIds(
{
[this.state.editingLinearElement.elementId]: true,
[this.state.selectedLinearElement.elementId]: true,
},
this.state,
),
@@ -8182,8 +8175,7 @@ class App extends React.Component<AppProps, AppState> {
const elementsMap = this.scene.getNonDeletedElementsMap();
if (this.state.selectedLinearElement) {
const linearElementEditor =
this.state.editingLinearElement || this.state.selectedLinearElement;
const linearElementEditor = this.state.selectedLinearElement;
if (
LinearElementEditor.shouldAddMidpoint(
@@ -8219,16 +8211,6 @@ class App extends React.Component<AppProps, AppState> {
},
});
}
if (this.state.editingLinearElement) {
this.setState({
editingLinearElement: {
...this.state.editingLinearElement,
pointerDownState: ret.pointerDownState,
selectedPointsIndices: ret.selectedPointsIndices,
segmentMidPointHoveredCoords: null,
},
});
}
});
return;
@@ -8262,9 +8244,9 @@ class App extends React.Component<AppProps, AppState> {
);
const isSelectingPointsInLineEditor =
this.state.editingLinearElement &&
this.state.selectedLinearElement?.isEditing &&
event.shiftKey &&
this.state.editingLinearElement.elementId ===
this.state.selectedLinearElement.elementId ===
pointerDownState.hit.element?.id;
if (
(hasHitASelectedElement ||
@@ -8751,7 +8733,7 @@ class App extends React.Component<AppProps, AppState> {
const elements = this.scene.getNonDeletedElements();
// box-select line editor points
if (this.state.editingLinearElement) {
if (this.state.selectedLinearElement?.isEditing) {
LinearElementEditor.handleBoxSelection(
event,
this.state,
@@ -8994,23 +8976,23 @@ class App extends React.Component<AppProps, AppState> {
// Handle end of dragging a point of a linear element, might close a loop
// and sets binding element
if (this.state.editingLinearElement) {
if (this.state.selectedLinearElement?.isEditing) {
if (
!pointerDownState.boxSelection.hasOccurred &&
pointerDownState.hit?.element?.id !==
this.state.editingLinearElement.elementId
this.state.selectedLinearElement.elementId
) {
this.actionManager.executeAction(actionFinalize);
} else {
const editingLinearElement = LinearElementEditor.handlePointerUp(
childEvent,
this.state.editingLinearElement,
this.state.selectedLinearElement,
this.state,
this.scene,
);
if (editingLinearElement !== this.state.editingLinearElement) {
if (editingLinearElement !== this.state.selectedLinearElement) {
this.setState({
editingLinearElement,
selectedLinearElement: editingLinearElement,
suggestedBindings: [],
});
}
@@ -9523,14 +9505,17 @@ class App extends React.Component<AppProps, AppState> {
!pointerDownState.hit.wasAddedToSelection &&
// if we're editing a line, pointerup shouldn't switch selection if
// box selected
(!this.state.editingLinearElement ||
(!this.state.selectedLinearElement?.isEditing ||
!pointerDownState.boxSelection.hasOccurred) &&
// hitElement can be set when alt + ctrl to toggle lasso and we will
// just respect the selected elements from lasso instead
this.state.activeTool.type !== "lasso"
) {
// when inside line editor, shift selects points instead
if (childEvent.shiftKey && !this.state.editingLinearElement) {
if (
childEvent.shiftKey &&
!this.state.selectedLinearElement?.isEditing
) {
if (this.state.selectedElementIds[hitElement.id]) {
if (isSelectedViaGroup(this.state, hitElement)) {
this.setState((_prevState) => {
@@ -9708,8 +9693,9 @@ class App extends React.Component<AppProps, AppState> {
(!hitElement &&
pointerDownState.hit.hasHitCommonBoundingBoxOfSelectedElements))
) {
if (this.state.editingLinearElement) {
this.setState({ editingLinearElement: null });
if (this.state.selectedLinearElement?.isEditing) {
// Exit editing mode but keep the element selected
this.actionManager.executeAction(actionToggleLinearEditor);
} else {
// Deselect selected elements
this.setState({