debounce
This commit is contained in:
@@ -26,6 +26,7 @@ export const applyDomTransform = (
|
||||
height,
|
||||
rotation = 0,
|
||||
scale = 1,
|
||||
zIndex,
|
||||
} = {},
|
||||
) => {
|
||||
if (!node) {
|
||||
@@ -38,6 +39,9 @@ export const applyDomTransform = (
|
||||
const originX = cx - w / 2;
|
||||
const originY = cy - h / 2;
|
||||
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) => {
|
||||
@@ -399,6 +403,11 @@ export class WorkspaceEngine {
|
||||
this.pendingRemovalTag = null;
|
||||
this.dragInProgress = false;
|
||||
this.activeDragDocIds = new Set();
|
||||
this.pendingSnapshotSync = false;
|
||||
this.pendingPersistSync = false;
|
||||
this.persistDebounceId = null;
|
||||
this.pendingSnapshotSync = false;
|
||||
this.pendingPersistSync = false;
|
||||
|
||||
this.items = [];
|
||||
this.documentLookup = new Map();
|
||||
@@ -529,6 +538,16 @@ export class WorkspaceEngine {
|
||||
endDrag() {
|
||||
this.dragInProgress = false;
|
||||
this.activeDragDocIds.clear();
|
||||
this.flushPendingLayoutOps();
|
||||
}
|
||||
|
||||
flushPendingLayoutOps() {
|
||||
if (this.pendingSnapshotSync) {
|
||||
this.syncLayoutSnapshot();
|
||||
}
|
||||
if (this.pendingPersistSync) {
|
||||
this.persistLayoutSnapshot();
|
||||
}
|
||||
}
|
||||
|
||||
setTagDropTargetId(docId) {
|
||||
@@ -583,6 +602,7 @@ export class WorkspaceEngine {
|
||||
}
|
||||
this.markLayoutDirty();
|
||||
this.syncLayoutSnapshot();
|
||||
this.persistLayoutSnapshot();
|
||||
}
|
||||
|
||||
bringToFront(docId) {
|
||||
@@ -598,10 +618,11 @@ export class WorkspaceEngine {
|
||||
this.layout.set(key, { ...entry, z: this.zCounter });
|
||||
this.markLayoutDirty();
|
||||
this.syncLayoutSnapshot();
|
||||
this.persistLayoutSnapshot();
|
||||
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;
|
||||
if (!key) {
|
||||
return;
|
||||
@@ -614,6 +635,7 @@ export class WorkspaceEngine {
|
||||
height,
|
||||
rotation,
|
||||
scale,
|
||||
zIndex,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -635,12 +657,14 @@ export class WorkspaceEngine {
|
||||
const centerY = item.currentCenterY ?? entry.centerY ?? dragState.originCenterY;
|
||||
const rotation = item.displayRotation ?? entry.rotation ?? 0;
|
||||
|
||||
this.layout.set(key, {
|
||||
const nextEntry = {
|
||||
...entry,
|
||||
centerX,
|
||||
centerY,
|
||||
rotation,
|
||||
});
|
||||
};
|
||||
|
||||
this.layout.set(key, nextEntry);
|
||||
|
||||
this.applyTransform(
|
||||
key,
|
||||
@@ -650,10 +674,13 @@ export class WorkspaceEngine {
|
||||
item.height,
|
||||
rotation,
|
||||
key === dragState.docKey ? dragState.dragScale || 1 : 1,
|
||||
nextEntry.z,
|
||||
);
|
||||
});
|
||||
|
||||
this.markLayoutDirty();
|
||||
this.syncLayoutSnapshot();
|
||||
this.persistLayoutSnapshot();
|
||||
}
|
||||
|
||||
cancelInertiaAnimation(docId) {
|
||||
@@ -721,7 +748,8 @@ export class WorkspaceEngine {
|
||||
simulationState.rotation = simulationState.restRotation + dynamicRotation;
|
||||
|
||||
const rotation = simulationState.rotation;
|
||||
this.layout.set(key, { ...entry, rotation });
|
||||
const nextEntry = { ...entry, rotation };
|
||||
this.layout.set(key, nextEntry);
|
||||
this.markLayoutDirty();
|
||||
|
||||
this.applyTransform(
|
||||
@@ -732,6 +760,7 @@ export class WorkspaceEngine {
|
||||
simulationState.height,
|
||||
rotation,
|
||||
simulationState.dragScale || 1,
|
||||
nextEntry.z,
|
||||
);
|
||||
|
||||
const isSettled = Math.abs(angularVelocity) < SETTLE_ANGULAR_VELOCITY;
|
||||
@@ -775,6 +804,7 @@ export class WorkspaceEngine {
|
||||
if (settled) {
|
||||
this.inertiaAnimations.delete(key);
|
||||
this.syncLayoutSnapshot();
|
||||
this.persistLayoutSnapshot();
|
||||
return;
|
||||
}
|
||||
simulationState.frameId = window.requestAnimationFrame(step);
|
||||
@@ -784,27 +814,38 @@ export class WorkspaceEngine {
|
||||
this.inertiaAnimations.set(key, simulationState);
|
||||
}
|
||||
|
||||
syncLayoutSnapshot(force = false) {
|
||||
if (this.dragInProgress && !force) {
|
||||
syncLayoutSnapshot() {
|
||||
if (this.dragInProgress) {
|
||||
this.pendingSnapshotSync = true;
|
||||
return;
|
||||
}
|
||||
this.pendingSnapshotSync = false;
|
||||
this.layoutSnapshot = new Map(this.layout);
|
||||
this.emit();
|
||||
this.persistLayoutSnapshot(force);
|
||||
}
|
||||
|
||||
async persistLayoutSnapshot(force = false) {
|
||||
if (this.dragInProgress && !force) {
|
||||
async persistLayoutSnapshot() {
|
||||
if (this.dragInProgress) {
|
||||
this.pendingPersistSync = true;
|
||||
return;
|
||||
}
|
||||
if (!this.allowLayoutPersistence || !this.tenantId || !this.viewId) {
|
||||
this.pendingPersistSync = false;
|
||||
return;
|
||||
}
|
||||
if (!force && !this.layoutDirty) {
|
||||
if (!this.layoutDirty && !this.pendingPersistSync) {
|
||||
return;
|
||||
}
|
||||
this.pendingPersistSync = 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);
|
||||
snapshot.forEach((entry, docId) => {
|
||||
if (!docId || !entry) {
|
||||
@@ -836,10 +877,21 @@ export class WorkspaceEngine {
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
await upsertLayoutRecords({ tenantId: this.tenantId, viewId: this.viewId, entries: records });
|
||||
} catch (error) {
|
||||
console.warn('[desk] Failed to persist layout snapshot', error);
|
||||
const persistTask = async () => {
|
||||
try {
|
||||
await upsertLayoutRecords({ tenantId: this.tenantId, viewId: this.viewId, entries: records });
|
||||
} 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.zCounter = Math.max(this.zCounter, maxZ);
|
||||
this.syncLayoutSnapshot();
|
||||
this.persistLayoutSnapshot();
|
||||
this.recalcVisibleDocIds();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user