debounce
This commit is contained in:
@@ -242,10 +242,6 @@ const DesktopWorkspace = ({
|
|||||||
engine.recalcVisibleDocIds();
|
engine.recalcVisibleDocIds();
|
||||||
}, [engine]);
|
}, [engine]);
|
||||||
|
|
||||||
const syncLayoutSnapshot = useCallback((force = false) => {
|
|
||||||
engine.syncLayoutSnapshot(force);
|
|
||||||
}, [engine]);
|
|
||||||
|
|
||||||
const setDraggingId = useCallback((value) => {
|
const setDraggingId = useCallback((value) => {
|
||||||
engine.setDraggingId(value);
|
engine.setDraggingId(value);
|
||||||
}, [engine]);
|
}, [engine]);
|
||||||
@@ -666,7 +662,6 @@ const DesktopWorkspace = ({
|
|||||||
resolveBaseMetrics,
|
resolveBaseMetrics,
|
||||||
bringToFront,
|
bringToFront,
|
||||||
setDraggingId,
|
setDraggingId,
|
||||||
syncLayoutSnapshot,
|
|
||||||
canvasSize,
|
canvasSize,
|
||||||
openOverlayForDoc,
|
openOverlayForDoc,
|
||||||
recalcVisibleDocIds,
|
recalcVisibleDocIds,
|
||||||
@@ -725,7 +720,6 @@ const DesktopWorkspace = ({
|
|||||||
markLayoutDirty,
|
markLayoutDirty,
|
||||||
tagDropTargetId,
|
tagDropTargetId,
|
||||||
visibleDocIds,
|
visibleDocIds,
|
||||||
syncLayoutSnapshot,
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
@@ -778,10 +772,9 @@ const DesktopWorkspaceView = ({
|
|||||||
onCloseDetailPanel,
|
onCloseDetailPanel,
|
||||||
documentLookup,
|
documentLookup,
|
||||||
resolveBaseMetrics,
|
resolveBaseMetrics,
|
||||||
bringToFront,
|
bringToFront,
|
||||||
setDraggingId,
|
setDraggingId,
|
||||||
syncLayoutSnapshot,
|
canvasSize,
|
||||||
canvasSize,
|
|
||||||
openOverlayForDoc,
|
openOverlayForDoc,
|
||||||
recalcVisibleDocIds,
|
recalcVisibleDocIds,
|
||||||
dragSettings,
|
dragSettings,
|
||||||
@@ -800,7 +793,6 @@ const DesktopWorkspaceView = ({
|
|||||||
resolveBaseMetrics,
|
resolveBaseMetrics,
|
||||||
bringToFront,
|
bringToFront,
|
||||||
setDraggingId,
|
setDraggingId,
|
||||||
syncLayoutSnapshot,
|
|
||||||
canvasSize,
|
canvasSize,
|
||||||
openOverlayForDoc,
|
openOverlayForDoc,
|
||||||
recalcVisibleDocIds,
|
recalcVisibleDocIds,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
resolveBaseMetrics,
|
resolveBaseMetrics,
|
||||||
bringToFront,
|
bringToFront,
|
||||||
setDraggingId,
|
setDraggingId,
|
||||||
syncLayoutSnapshot,
|
|
||||||
canvasSize,
|
canvasSize,
|
||||||
openOverlayForDoc,
|
openOverlayForDoc,
|
||||||
recalcVisibleDocIds,
|
recalcVisibleDocIds,
|
||||||
@@ -114,7 +113,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
}, [dragTransformsRef, layoutRef, markLayoutDirty]);
|
}, [dragTransformsRef, layoutRef, markLayoutDirty]);
|
||||||
|
|
||||||
const finishDrag = useCallback(
|
const finishDrag = useCallback(
|
||||||
(pointerId, { shouldSync = false, clearTransforms = true } = {}) => {
|
(pointerId, { clearTransforms = true } = {}) => {
|
||||||
const state = dragStateRef.current;
|
const state = dragStateRef.current;
|
||||||
if (state && state.pointerId === pointerId) {
|
if (state && state.pointerId === pointerId) {
|
||||||
const capturedTarget = state.capturedTarget;
|
const capturedTarget = state.capturedTarget;
|
||||||
@@ -134,11 +133,8 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
if (clearTransforms) {
|
if (clearTransforms) {
|
||||||
clearDragTransforms();
|
clearDragTransforms();
|
||||||
}
|
}
|
||||||
if (shouldSync) {
|
|
||||||
syncLayoutSnapshot(true);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[clearDragTransforms, debugDrag, engine, setDraggingId, syncLayoutSnapshot],
|
[clearDragTransforms, debugDrag, engine, setDraggingId],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePointerDown = useCallback(
|
const handlePointerDown = useCallback(
|
||||||
@@ -176,7 +172,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
: [];
|
: [];
|
||||||
|
|
||||||
if (!stackDocIdsOption && !pointerModifierActive && !wasSelectedAtPointerDown) {
|
if (!stackDocIdsOption && !pointerModifierActive && !wasSelectedAtPointerDown) {
|
||||||
selectionIds = [];
|
selectionIds = [docKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stackDocIdsOption && stackDocIdsOption.length) {
|
if (stackDocIdsOption && stackDocIdsOption.length) {
|
||||||
@@ -193,20 +189,23 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
if (!stackDocIdsOption && metaOrCtrl && !selectionIds.includes(docKey)) {
|
if (!stackDocIdsOption && metaOrCtrl && !selectionIds.includes(docKey)) {
|
||||||
selectionIds = [...selectionIds, docKey];
|
selectionIds = [...selectionIds, docKey];
|
||||||
}
|
}
|
||||||
let groupDocIds = selectionIds
|
|
||||||
|
selectionIds = selectionIds
|
||||||
.map((id) => String(id))
|
.map((id) => String(id))
|
||||||
.filter((id, index, array) => array.indexOf(id) === index && documentLookup.has(id));
|
.filter((id, index, array) => array.indexOf(id) === index && documentLookup.has(id));
|
||||||
if (!groupDocIds.includes(docKey)) {
|
|
||||||
groupDocIds.unshift(docKey);
|
if (!selectionIds.includes(docKey)) {
|
||||||
|
selectionIds.unshift(docKey);
|
||||||
}
|
}
|
||||||
groupDocIds = groupDocIds.filter((id, index, array) => array.indexOf(id) === index);
|
|
||||||
if (!groupDocIds.length) {
|
if (!selectionIds.length) {
|
||||||
groupDocIds = [docKey];
|
selectionIds = [docKey];
|
||||||
}
|
}
|
||||||
const isGroupDrag = groupDocIds.length > 1;
|
|
||||||
|
const isGroupDrag = selectionIds.length > 1;
|
||||||
|
|
||||||
if (isGroupDrag) {
|
if (isGroupDrag) {
|
||||||
groupDocIds.forEach((id) => {
|
selectionIds.forEach((id) => {
|
||||||
if (id !== docKey) {
|
if (id !== docKey) {
|
||||||
engine?.cancelInertiaAnimation?.(id);
|
engine?.cancelInertiaAnimation?.(id);
|
||||||
}
|
}
|
||||||
@@ -230,7 +229,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
if (!modifierPressed) {
|
if (!modifierPressed) {
|
||||||
if (isGroupDrag) {
|
if (isGroupDrag) {
|
||||||
const layout = layoutRef.current;
|
const layout = layoutRef.current;
|
||||||
const ordered = [...groupDocIds]
|
const ordered = [...selectionIds]
|
||||||
.filter((id, index, array) => array.indexOf(id) === index)
|
.filter((id, index, array) => array.indexOf(id) === index)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aZ = layout.get(a)?.z ?? 0;
|
const aZ = layout.get(a)?.z ?? 0;
|
||||||
@@ -275,7 +274,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
const localPointerOffsetX = pointerOffsetX * cosInitial - pointerOffsetY * sinInitial;
|
const localPointerOffsetX = pointerOffsetX * cosInitial - pointerOffsetY * sinInitial;
|
||||||
const localPointerOffsetY = pointerOffsetX * sinInitial + pointerOffsetY * cosInitial;
|
const localPointerOffsetY = pointerOffsetX * sinInitial + pointerOffsetY * cosInitial;
|
||||||
|
|
||||||
const groupItems = groupDocIds.map((id) => {
|
const groupItems = selectionIds.map((id) => {
|
||||||
const itemDoc = documentLookup.get(id);
|
const itemDoc = documentLookup.get(id);
|
||||||
const itemSize = ensureDocumentSize(itemDoc) || sizeInfo;
|
const itemSize = ensureDocumentSize(itemDoc) || sizeInfo;
|
||||||
const itemWidth = itemSize.width || docWidth;
|
const itemWidth = itemSize.width || docWidth;
|
||||||
@@ -343,7 +342,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
containerRectLeft: containerLeft,
|
containerRectLeft: containerLeft,
|
||||||
containerRectTop: containerTop,
|
containerRectTop: containerTop,
|
||||||
isGroup: isGroupDrag,
|
isGroup: isGroupDrag,
|
||||||
groupDocIds,
|
activeDocIds: selectionIds,
|
||||||
groupItems,
|
groupItems,
|
||||||
groupElevated: !isGroupDrag,
|
groupElevated: !isGroupDrag,
|
||||||
stackDocIds: hasStackSource ? stackDocIdsOption : null,
|
stackDocIds: hasStackSource ? stackDocIdsOption : null,
|
||||||
@@ -368,7 +367,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
engine?.beginDrag?.(state.groupDocIds);
|
engine?.beginDrag?.(state.activeDocIds);
|
||||||
|
|
||||||
setDraggingId(docKey);
|
setDraggingId(docKey);
|
||||||
|
|
||||||
@@ -380,6 +379,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
const node = itemRefs.current.get(item.docId);
|
const node = itemRefs.current.get(item.docId);
|
||||||
if (node) {
|
if (node) {
|
||||||
item.displayRotation = item.initialRotation;
|
item.displayRotation = item.initialRotation;
|
||||||
|
const itemEntry = layoutRef.current.get(item.docId) || null;
|
||||||
applyDomTransform(node, {
|
applyDomTransform(node, {
|
||||||
centerX: item.currentCenterX,
|
centerX: item.currentCenterX,
|
||||||
centerY: item.currentCenterY,
|
centerY: item.currentCenterY,
|
||||||
@@ -387,6 +387,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
height: item.height,
|
height: item.height,
|
||||||
rotation: item.displayRotation ?? 0,
|
rotation: item.displayRotation ?? 0,
|
||||||
scale: 1,
|
scale: 1,
|
||||||
|
zIndex: itemEntry?.z,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -447,7 +448,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
}
|
}
|
||||||
if (!state.groupElevated) {
|
if (!state.groupElevated) {
|
||||||
const layout = layoutRef.current;
|
const layout = layoutRef.current;
|
||||||
const sortedGroup = state.groupDocIds
|
const sortedGroup = state.activeDocIds
|
||||||
.filter((id) => id !== state.docKey)
|
.filter((id) => id !== state.docKey)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aZ = layout.get(a)?.z ?? 0;
|
const aZ = layout.get(a)?.z ?? 0;
|
||||||
@@ -515,6 +516,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
item.displayRotation += (item.targetRotation - item.displayRotation) * rotationBlend;
|
item.displayRotation += (item.targetRotation - item.displayRotation) * rotationBlend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const entry = layoutRef.current.get(item.docId) || null;
|
||||||
const payload = {
|
const payload = {
|
||||||
centerX: item.currentCenterX,
|
centerX: item.currentCenterX,
|
||||||
centerY: item.currentCenterY,
|
centerY: item.currentCenterY,
|
||||||
@@ -522,6 +524,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
width: item.width,
|
width: item.width,
|
||||||
height: item.height,
|
height: item.height,
|
||||||
scale: isPrimary ? state.dragScale || 1 : 1,
|
scale: isPrimary ? state.dragScale || 1 : 1,
|
||||||
|
zIndex: entry?.z,
|
||||||
};
|
};
|
||||||
|
|
||||||
setDragTransform(item.docId, payload);
|
setDragTransform(item.docId, payload);
|
||||||
@@ -630,6 +633,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
state.currentCenterX = currentCenterX;
|
state.currentCenterX = currentCenterX;
|
||||||
state.currentCenterY = currentCenterY;
|
state.currentCenterY = currentCenterY;
|
||||||
|
|
||||||
|
const layoutEntry = layoutRef.current.get(state.docKey) || null;
|
||||||
const transformPayload = {
|
const transformPayload = {
|
||||||
centerX: currentCenterX,
|
centerX: currentCenterX,
|
||||||
centerY: currentCenterY,
|
centerY: currentCenterY,
|
||||||
@@ -637,6 +641,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
width: state.width,
|
width: state.width,
|
||||||
height: state.height,
|
height: state.height,
|
||||||
scale: state.dragScale || 1,
|
scale: state.dragScale || 1,
|
||||||
|
zIndex: layoutEntry?.z,
|
||||||
};
|
};
|
||||||
|
|
||||||
setDragTransform(state.docKey, transformPayload);
|
setDragTransform(state.docKey, transformPayload);
|
||||||
@@ -710,8 +715,8 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
|
|
||||||
if (state.isGroup) {
|
if (state.isGroup) {
|
||||||
engine?.finalizeGroupDrag?.(state);
|
engine?.finalizeGroupDrag?.(state);
|
||||||
commitActiveDragTransforms(state.groupDocIds);
|
commitActiveDragTransforms(state.activeDocIds);
|
||||||
finishDrag(event.pointerId, { shouldSync: true });
|
finishDrag(event.pointerId);
|
||||||
recalcVisibleDocIds();
|
recalcVisibleDocIds();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -728,7 +733,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
dragScale: state.dragScale || 1,
|
dragScale: state.dragScale || 1,
|
||||||
};
|
};
|
||||||
const docId = state.docKey;
|
const docId = state.docKey;
|
||||||
finishDrag(event.pointerId, { shouldSync: true });
|
finishDrag(event.pointerId);
|
||||||
engine?.startInertiaAnimation?.(docId, inertiaState);
|
engine?.startInertiaAnimation?.(docId, inertiaState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -770,8 +775,8 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
if (state && state.pointerId === event.pointerId && state.moved) {
|
if (state && state.pointerId === event.pointerId && state.moved) {
|
||||||
if (state.isGroup) {
|
if (state.isGroup) {
|
||||||
engine?.finalizeGroupDrag?.(state);
|
engine?.finalizeGroupDrag?.(state);
|
||||||
commitActiveDragTransforms(state.groupDocIds);
|
commitActiveDragTransforms(state.activeDocIds);
|
||||||
finishDrag(event.pointerId, { shouldSync: true });
|
finishDrag(event.pointerId);
|
||||||
recalcVisibleDocIds();
|
recalcVisibleDocIds();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -787,7 +792,7 @@ const useDocumentDrag = (options = {}) => {
|
|||||||
dragScale: state.dragScale || 1,
|
dragScale: state.dragScale || 1,
|
||||||
};
|
};
|
||||||
const docId = state.docKey;
|
const docId = state.docKey;
|
||||||
finishDrag(event.pointerId, { shouldSync: true });
|
finishDrag(event.pointerId);
|
||||||
engine?.startInertiaAnimation?.(docId, inertiaState);
|
engine?.startInertiaAnimation?.(docId, inertiaState);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export const applyDomTransform = (
|
|||||||
height,
|
height,
|
||||||
rotation = 0,
|
rotation = 0,
|
||||||
scale = 1,
|
scale = 1,
|
||||||
|
zIndex,
|
||||||
} = {},
|
} = {},
|
||||||
) => {
|
) => {
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@@ -38,6 +39,9 @@ export const applyDomTransform = (
|
|||||||
const originX = cx - w / 2;
|
const originX = cx - w / 2;
|
||||||
const originY = cy - h / 2;
|
const originY = cy - h / 2;
|
||||||
node.style.transform = formatTransform(originX, originY, rotation || 0, scale || 1);
|
node.style.transform = formatTransform(originX, originY, rotation || 0, scale || 1);
|
||||||
|
if (zIndex != null && node.style.zIndex !== String(zIndex)) {
|
||||||
|
node.style.zIndex = String(zIndex);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const clampCardDimensions = (width, height) => {
|
export const clampCardDimensions = (width, height) => {
|
||||||
@@ -399,6 +403,11 @@ export class WorkspaceEngine {
|
|||||||
this.pendingRemovalTag = null;
|
this.pendingRemovalTag = null;
|
||||||
this.dragInProgress = false;
|
this.dragInProgress = false;
|
||||||
this.activeDragDocIds = new Set();
|
this.activeDragDocIds = new Set();
|
||||||
|
this.pendingSnapshotSync = false;
|
||||||
|
this.pendingPersistSync = false;
|
||||||
|
this.persistDebounceId = null;
|
||||||
|
this.pendingSnapshotSync = false;
|
||||||
|
this.pendingPersistSync = false;
|
||||||
|
|
||||||
this.items = [];
|
this.items = [];
|
||||||
this.documentLookup = new Map();
|
this.documentLookup = new Map();
|
||||||
@@ -529,6 +538,16 @@ export class WorkspaceEngine {
|
|||||||
endDrag() {
|
endDrag() {
|
||||||
this.dragInProgress = false;
|
this.dragInProgress = false;
|
||||||
this.activeDragDocIds.clear();
|
this.activeDragDocIds.clear();
|
||||||
|
this.flushPendingLayoutOps();
|
||||||
|
}
|
||||||
|
|
||||||
|
flushPendingLayoutOps() {
|
||||||
|
if (this.pendingSnapshotSync) {
|
||||||
|
this.syncLayoutSnapshot();
|
||||||
|
}
|
||||||
|
if (this.pendingPersistSync) {
|
||||||
|
this.persistLayoutSnapshot();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTagDropTargetId(docId) {
|
setTagDropTargetId(docId) {
|
||||||
@@ -583,6 +602,7 @@ export class WorkspaceEngine {
|
|||||||
}
|
}
|
||||||
this.markLayoutDirty();
|
this.markLayoutDirty();
|
||||||
this.syncLayoutSnapshot();
|
this.syncLayoutSnapshot();
|
||||||
|
this.persistLayoutSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
bringToFront(docId) {
|
bringToFront(docId) {
|
||||||
@@ -598,10 +618,11 @@ export class WorkspaceEngine {
|
|||||||
this.layout.set(key, { ...entry, z: this.zCounter });
|
this.layout.set(key, { ...entry, z: this.zCounter });
|
||||||
this.markLayoutDirty();
|
this.markLayoutDirty();
|
||||||
this.syncLayoutSnapshot();
|
this.syncLayoutSnapshot();
|
||||||
|
this.persistLayoutSnapshot();
|
||||||
this.recalcVisibleDocIds();
|
this.recalcVisibleDocIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyTransform(docId, centerX, centerY, width, height, rotation, scale = 1) {
|
applyTransform(docId, centerX, centerY, width, height, rotation, scale = 1, zIndex = null) {
|
||||||
const key = docId != null ? String(docId) : null;
|
const key = docId != null ? String(docId) : null;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
return;
|
return;
|
||||||
@@ -614,6 +635,7 @@ export class WorkspaceEngine {
|
|||||||
height,
|
height,
|
||||||
rotation,
|
rotation,
|
||||||
scale,
|
scale,
|
||||||
|
zIndex,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,12 +657,14 @@ export class WorkspaceEngine {
|
|||||||
const centerY = item.currentCenterY ?? entry.centerY ?? dragState.originCenterY;
|
const centerY = item.currentCenterY ?? entry.centerY ?? dragState.originCenterY;
|
||||||
const rotation = item.displayRotation ?? entry.rotation ?? 0;
|
const rotation = item.displayRotation ?? entry.rotation ?? 0;
|
||||||
|
|
||||||
this.layout.set(key, {
|
const nextEntry = {
|
||||||
...entry,
|
...entry,
|
||||||
centerX,
|
centerX,
|
||||||
centerY,
|
centerY,
|
||||||
rotation,
|
rotation,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
this.layout.set(key, nextEntry);
|
||||||
|
|
||||||
this.applyTransform(
|
this.applyTransform(
|
||||||
key,
|
key,
|
||||||
@@ -650,10 +674,13 @@ export class WorkspaceEngine {
|
|||||||
item.height,
|
item.height,
|
||||||
rotation,
|
rotation,
|
||||||
key === dragState.docKey ? dragState.dragScale || 1 : 1,
|
key === dragState.docKey ? dragState.dragScale || 1 : 1,
|
||||||
|
nextEntry.z,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.markLayoutDirty();
|
this.markLayoutDirty();
|
||||||
|
this.syncLayoutSnapshot();
|
||||||
|
this.persistLayoutSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelInertiaAnimation(docId) {
|
cancelInertiaAnimation(docId) {
|
||||||
@@ -721,7 +748,8 @@ export class WorkspaceEngine {
|
|||||||
simulationState.rotation = simulationState.restRotation + dynamicRotation;
|
simulationState.rotation = simulationState.restRotation + dynamicRotation;
|
||||||
|
|
||||||
const rotation = simulationState.rotation;
|
const rotation = simulationState.rotation;
|
||||||
this.layout.set(key, { ...entry, rotation });
|
const nextEntry = { ...entry, rotation };
|
||||||
|
this.layout.set(key, nextEntry);
|
||||||
this.markLayoutDirty();
|
this.markLayoutDirty();
|
||||||
|
|
||||||
this.applyTransform(
|
this.applyTransform(
|
||||||
@@ -732,6 +760,7 @@ export class WorkspaceEngine {
|
|||||||
simulationState.height,
|
simulationState.height,
|
||||||
rotation,
|
rotation,
|
||||||
simulationState.dragScale || 1,
|
simulationState.dragScale || 1,
|
||||||
|
nextEntry.z,
|
||||||
);
|
);
|
||||||
|
|
||||||
const isSettled = Math.abs(angularVelocity) < SETTLE_ANGULAR_VELOCITY;
|
const isSettled = Math.abs(angularVelocity) < SETTLE_ANGULAR_VELOCITY;
|
||||||
@@ -775,6 +804,7 @@ export class WorkspaceEngine {
|
|||||||
if (settled) {
|
if (settled) {
|
||||||
this.inertiaAnimations.delete(key);
|
this.inertiaAnimations.delete(key);
|
||||||
this.syncLayoutSnapshot();
|
this.syncLayoutSnapshot();
|
||||||
|
this.persistLayoutSnapshot();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
simulationState.frameId = window.requestAnimationFrame(step);
|
simulationState.frameId = window.requestAnimationFrame(step);
|
||||||
@@ -784,27 +814,38 @@ export class WorkspaceEngine {
|
|||||||
this.inertiaAnimations.set(key, simulationState);
|
this.inertiaAnimations.set(key, simulationState);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncLayoutSnapshot(force = false) {
|
syncLayoutSnapshot() {
|
||||||
if (this.dragInProgress && !force) {
|
if (this.dragInProgress) {
|
||||||
|
this.pendingSnapshotSync = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.pendingSnapshotSync = false;
|
||||||
this.layoutSnapshot = new Map(this.layout);
|
this.layoutSnapshot = new Map(this.layout);
|
||||||
this.emit();
|
this.emit();
|
||||||
this.persistLayoutSnapshot(force);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async persistLayoutSnapshot(force = false) {
|
async persistLayoutSnapshot() {
|
||||||
if (this.dragInProgress && !force) {
|
if (this.dragInProgress) {
|
||||||
|
this.pendingPersistSync = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.allowLayoutPersistence || !this.tenantId || !this.viewId) {
|
if (!this.allowLayoutPersistence || !this.tenantId || !this.viewId) {
|
||||||
|
this.pendingPersistSync = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!force && !this.layoutDirty) {
|
if (!this.layoutDirty && !this.pendingPersistSync) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.pendingPersistSync = false;
|
||||||
this.layoutDirty = false;
|
this.layoutDirty = false;
|
||||||
const snapshot = new Map(this.layoutSnapshot);
|
if (this.persistDebounceId) {
|
||||||
|
clearTimeout(this.persistDebounceId);
|
||||||
|
this.persistDebounceId = null;
|
||||||
|
}
|
||||||
|
const snapshotSource = this.layoutSnapshot && this.layoutSnapshot.size
|
||||||
|
? this.layoutSnapshot
|
||||||
|
: this.layout;
|
||||||
|
const snapshot = new Map(snapshotSource);
|
||||||
const merged = new Map(this.persistedLayout);
|
const merged = new Map(this.persistedLayout);
|
||||||
snapshot.forEach((entry, docId) => {
|
snapshot.forEach((entry, docId) => {
|
||||||
if (!docId || !entry) {
|
if (!docId || !entry) {
|
||||||
@@ -836,10 +877,21 @@ export class WorkspaceEngine {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
const persistTask = async () => {
|
||||||
await upsertLayoutRecords({ tenantId: this.tenantId, viewId: this.viewId, entries: records });
|
try {
|
||||||
} catch (error) {
|
await upsertLayoutRecords({ tenantId: this.tenantId, viewId: this.viewId, entries: records });
|
||||||
console.warn('[desk] Failed to persist layout snapshot', error);
|
} catch (error) {
|
||||||
|
console.warn('[desk] Failed to persist layout snapshot', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined' && typeof window.setTimeout === 'function') {
|
||||||
|
this.persistDebounceId = window.setTimeout(() => {
|
||||||
|
this.persistDebounceId = null;
|
||||||
|
void persistTask();
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
await persistTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -940,6 +992,7 @@ export class WorkspaceEngine {
|
|||||||
this.layout = next;
|
this.layout = next;
|
||||||
this.zCounter = Math.max(this.zCounter, maxZ);
|
this.zCounter = Math.max(this.zCounter, maxZ);
|
||||||
this.syncLayoutSnapshot();
|
this.syncLayoutSnapshot();
|
||||||
|
this.persistLayoutSnapshot();
|
||||||
this.recalcVisibleDocIds();
|
this.recalcVisibleDocIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user