mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-20 07:49:59 +02:00
feat: better unlock (#9546)
* change lock label * feat: add unlock logic for single units on pointer up * feat: add unlock popup * fix: linting errors * style: padding tweaks * style: remove redundant line * feat: lock multiple units together * style: tweak color & position * feat: add highlight for locked elements * feat: select groups correctly after unlocking * test: update snapshots * fix: lasso from selecting locked elements * fix: should prevent selecting unlocked elements and setting locked id at the same time * fix: reset hit locked id immediately when appropriate * feat: capture locked units in delta * test: update locking test * feat: show lock highlight when locking (including undo/redo) * feat: make locked highlighting consistent * feat: show correct cursor type when moving over locked elements * fix history * remove `lockedUnits.singleUnits` * tweak button * do not render UnlockPopup if not locked element selected * tweak actions * refactor: simplify type * refactor: rename type * refactor: simplify hit element setting & checking * fix: prefer locked over link * rename to `activeLockedId` * refactor: getElementAtPosition takes an optional hitelments array * fix: avoid setting active locked id after resizing --------- Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
This commit is contained in:
@@ -187,10 +187,12 @@ export class Delta<T> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof deleted[property] === "object" ||
|
||||
typeof inserted[property] === "object"
|
||||
) {
|
||||
const isDeletedObject =
|
||||
deleted[property] !== null && typeof deleted[property] === "object";
|
||||
const isInsertedObject =
|
||||
inserted[property] !== null && typeof inserted[property] === "object";
|
||||
|
||||
if (isDeletedObject || isInsertedObject) {
|
||||
type RecordLike = Record<string, V | undefined>;
|
||||
|
||||
const deletedObject: RecordLike = deleted[property] ?? {};
|
||||
@@ -222,6 +224,9 @@ export class Delta<T> {
|
||||
Reflect.deleteProperty(deleted, property);
|
||||
Reflect.deleteProperty(inserted, property);
|
||||
}
|
||||
} else if (deleted[property] === inserted[property]) {
|
||||
Reflect.deleteProperty(deleted, property);
|
||||
Reflect.deleteProperty(inserted, property);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,6 +663,24 @@ export class AppStateDelta implements DeltaContainer<AppState> {
|
||||
}
|
||||
|
||||
break;
|
||||
case "lockedMultiSelections": {
|
||||
const prevLockedUnits = prevAppState[key] || {};
|
||||
const nextLockedUnits = nextAppState[key] || {};
|
||||
|
||||
if (!isShallowEqual(prevLockedUnits, nextLockedUnits)) {
|
||||
visibleDifferenceFlag.value = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "activeLockedId": {
|
||||
const prevHitLockedId = prevAppState[key] || null;
|
||||
const nextHitLockedId = nextAppState[key] || null;
|
||||
|
||||
if (prevHitLockedId !== nextHitLockedId) {
|
||||
visibleDifferenceFlag.value = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assertNever(
|
||||
key,
|
||||
@@ -753,6 +776,8 @@ export class AppStateDelta implements DeltaContainer<AppState> {
|
||||
editingLinearElementId,
|
||||
selectedLinearElementId,
|
||||
croppingElementId,
|
||||
lockedMultiSelections,
|
||||
activeLockedId,
|
||||
...standaloneProps
|
||||
} = delta as ObservedAppState;
|
||||
|
||||
@@ -797,6 +822,18 @@ export class AppStateDelta implements DeltaContainer<AppState> {
|
||||
"selectedGroupIds",
|
||||
(prevValue) => (prevValue ?? false) as ValueOf<T["selectedGroupIds"]>,
|
||||
);
|
||||
Delta.diffObjects(
|
||||
deleted,
|
||||
inserted,
|
||||
"lockedMultiSelections",
|
||||
(prevValue) => (prevValue ?? {}) as ValueOf<T["lockedMultiSelections"]>,
|
||||
);
|
||||
Delta.diffObjects(
|
||||
deleted,
|
||||
inserted,
|
||||
"activeLockedId",
|
||||
(prevValue) => (prevValue ?? null) as ValueOf<T["activeLockedId"]>,
|
||||
);
|
||||
} catch (e) {
|
||||
// if postprocessing fails it does not make sense to bubble up, but let's make sure we know about it
|
||||
console.error(`Couldn't postprocess appstate change deltas.`);
|
||||
|
Reference in New Issue
Block a user