prevent coordinate reset
This commit is contained in:
parent
1b172d7529
commit
0fa1652f72
|
|
@ -134,6 +134,10 @@ export function applyAutomergePatchesToTLStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CRITICAL: Store original x and y before patch application to preserve them
|
||||||
|
const originalX = (record.typeName === 'shape' && typeof record.x === 'number' && !isNaN(record.x)) ? record.x : undefined
|
||||||
|
const originalY = (record.typeName === 'shape' && typeof record.y === 'number' && !isNaN(record.y)) ? record.y : undefined
|
||||||
|
|
||||||
switch (patch.action) {
|
switch (patch.action) {
|
||||||
case "insert": {
|
case "insert": {
|
||||||
updatedObjects[id] = applyInsertToObject(patch, record)
|
updatedObjects[id] = applyInsertToObject(patch, record)
|
||||||
|
|
@ -167,6 +171,23 @@ export function applyAutomergePatchesToTLStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CRITICAL: After patch application, ensure x and y coordinates are preserved for shapes
|
||||||
|
if (updatedObjects[id] && updatedObjects[id].typeName === 'shape') {
|
||||||
|
const patchedRecord = updatedObjects[id]
|
||||||
|
// Preserve original x and y if they were valid, otherwise use defaults
|
||||||
|
if (originalX !== undefined && (typeof patchedRecord.x !== 'number' || patchedRecord.x === null || isNaN(patchedRecord.x))) {
|
||||||
|
updatedObjects[id] = { ...patchedRecord, x: originalX }
|
||||||
|
} else if (typeof patchedRecord.x !== 'number' || patchedRecord.x === null || isNaN(patchedRecord.x)) {
|
||||||
|
updatedObjects[id] = { ...patchedRecord, x: defaultRecord.x || 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (originalY !== undefined && (typeof patchedRecord.y !== 'number' || patchedRecord.y === null || isNaN(patchedRecord.y))) {
|
||||||
|
updatedObjects[id] = { ...patchedRecord, y: originalY }
|
||||||
|
} else if (typeof patchedRecord.y !== 'number' || patchedRecord.y === null || isNaN(patchedRecord.y)) {
|
||||||
|
updatedObjects[id] = { ...patchedRecord, y: defaultRecord.y || 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CRITICAL: Re-check typeName after patch application to ensure it's still correct
|
// CRITICAL: Re-check typeName after patch application to ensure it's still correct
|
||||||
// Note: obsidian_vault records are skipped above, so we don't need to handle them here
|
// Note: obsidian_vault records are skipped above, so we don't need to handle them here
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,23 @@ export function useAutomergeStoreV2({
|
||||||
// CRITICAL: Force editor to see shapes by refreshing them multiple times
|
// CRITICAL: Force editor to see shapes by refreshing them multiple times
|
||||||
// Sometimes the editor needs multiple updates to detect shapes
|
// Sometimes the editor needs multiple updates to detect shapes
|
||||||
const refreshShapes = (attempt: number) => {
|
const refreshShapes = (attempt: number) => {
|
||||||
const shapesToRefresh = existingStoreShapes.map(s => store.get(s.id)).filter((s): s is TLRecord => s !== undefined && s.typeName === 'shape')
|
// CRITICAL: Preserve x and y coordinates when refreshing shapes
|
||||||
|
const shapesToRefresh = existingStoreShapes.map(s => {
|
||||||
|
const shapeFromStore = store.get(s.id)
|
||||||
|
if (shapeFromStore && shapeFromStore.typeName === 'shape') {
|
||||||
|
// Preserve original x and y from the store shape data
|
||||||
|
const originalX = s.x !== undefined && typeof s.x === 'number' && !isNaN(s.x) ? s.x : (shapeFromStore as any).x
|
||||||
|
const originalY = s.y !== undefined && typeof s.y === 'number' && !isNaN(s.y) ? s.y : (shapeFromStore as any).y
|
||||||
|
|
||||||
|
// Ensure x and y are preserved
|
||||||
|
if (typeof originalX === 'number' && !isNaN(originalX) && typeof originalY === 'number' && !isNaN(originalY)) {
|
||||||
|
return { ...shapeFromStore, x: originalX, y: originalY } as TLRecord
|
||||||
|
}
|
||||||
|
return shapeFromStore
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}).filter((s): s is TLRecord => s !== null && s.typeName === 'shape')
|
||||||
|
|
||||||
if (shapesToRefresh.length > 0) {
|
if (shapesToRefresh.length > 0) {
|
||||||
store.mergeRemoteChanges(() => {
|
store.mergeRemoteChanges(() => {
|
||||||
// Re-put shapes to trigger editor update
|
// Re-put shapes to trigger editor update
|
||||||
|
|
@ -419,7 +435,23 @@ export function useAutomergeStoreV2({
|
||||||
// CRITICAL: Force editor to see shapes by refreshing them multiple times
|
// CRITICAL: Force editor to see shapes by refreshing them multiple times
|
||||||
// Sometimes the editor needs multiple updates to detect shapes
|
// Sometimes the editor needs multiple updates to detect shapes
|
||||||
const refreshShapes = (attempt: number) => {
|
const refreshShapes = (attempt: number) => {
|
||||||
const shapesToRefresh = currentShapes.map(s => store.get(s.id)).filter((s): s is TLRecord => s !== undefined && s.typeName === 'shape')
|
// CRITICAL: Preserve x and y coordinates when refreshing shapes
|
||||||
|
const shapesToRefresh = currentShapes.map(s => {
|
||||||
|
const shapeFromStore = store.get(s.id)
|
||||||
|
if (shapeFromStore && shapeFromStore.typeName === 'shape') {
|
||||||
|
// Preserve original x and y from the store shape data
|
||||||
|
const originalX = s.x !== undefined && typeof s.x === 'number' && !isNaN(s.x) ? s.x : (shapeFromStore as any).x
|
||||||
|
const originalY = s.y !== undefined && typeof s.y === 'number' && !isNaN(s.y) ? s.y : (shapeFromStore as any).y
|
||||||
|
|
||||||
|
// Ensure x and y are preserved
|
||||||
|
if (typeof originalX === 'number' && !isNaN(originalX) && typeof originalY === 'number' && !isNaN(originalY)) {
|
||||||
|
return { ...shapeFromStore, x: originalX, y: originalY } as TLRecord
|
||||||
|
}
|
||||||
|
return shapeFromStore
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}).filter((s): s is TLRecord => s !== null && s.typeName === 'shape')
|
||||||
|
|
||||||
if (shapesToRefresh.length > 0) {
|
if (shapesToRefresh.length > 0) {
|
||||||
store.mergeRemoteChanges(() => {
|
store.mergeRemoteChanges(() => {
|
||||||
// Re-put shapes to trigger editor update
|
// Re-put shapes to trigger editor update
|
||||||
|
|
@ -500,7 +532,23 @@ export function useAutomergeStoreV2({
|
||||||
// Sometimes the editor needs multiple updates to detect shapes
|
// Sometimes the editor needs multiple updates to detect shapes
|
||||||
const refreshShapes = (attempt: number) => {
|
const refreshShapes = (attempt: number) => {
|
||||||
const shapes = store.allRecords().filter((r: any) => r.typeName === 'shape')
|
const shapes = store.allRecords().filter((r: any) => r.typeName === 'shape')
|
||||||
const shapesToRefresh = shapes.map(s => store.get(s.id)).filter((s): s is TLRecord => s !== undefined && s.typeName === 'shape')
|
// CRITICAL: Preserve x and y coordinates when refreshing shapes
|
||||||
|
const shapesToRefresh = shapes.map(s => {
|
||||||
|
const shapeFromStore = store.get(s.id)
|
||||||
|
if (shapeFromStore && shapeFromStore.typeName === 'shape') {
|
||||||
|
// Preserve original x and y from the store shape data
|
||||||
|
const originalX = s.x !== undefined && typeof s.x === 'number' && !isNaN(s.x) ? s.x : (shapeFromStore as any).x
|
||||||
|
const originalY = s.y !== undefined && typeof s.y === 'number' && !isNaN(s.y) ? s.y : (shapeFromStore as any).y
|
||||||
|
|
||||||
|
// Ensure x and y are preserved
|
||||||
|
if (typeof originalX === 'number' && !isNaN(originalX) && typeof originalY === 'number' && !isNaN(originalY)) {
|
||||||
|
return { ...shapeFromStore, x: originalX, y: originalY } as TLRecord
|
||||||
|
}
|
||||||
|
return shapeFromStore
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}).filter((s): s is TLRecord => s !== null && s.typeName === 'shape')
|
||||||
|
|
||||||
if (shapesToRefresh.length > 0) {
|
if (shapesToRefresh.length > 0) {
|
||||||
store.mergeRemoteChanges(() => {
|
store.mergeRemoteChanges(() => {
|
||||||
// Re-put shapes to trigger editor update
|
// Re-put shapes to trigger editor update
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,22 @@ export function Board() {
|
||||||
console.warn(`⚠️ Board: ${storeShapes.length} shapes in store (${storeShapesOnCurrentPage.length} on current page) but editor sees 0. Forcing refresh...`)
|
console.warn(`⚠️ Board: ${storeShapes.length} shapes in store (${storeShapesOnCurrentPage.length} on current page) but editor sees 0. Forcing refresh...`)
|
||||||
|
|
||||||
// Force refresh by re-putting shapes with mergeRemoteChanges
|
// Force refresh by re-putting shapes with mergeRemoteChanges
|
||||||
const shapesToRefresh = storeShapesOnCurrentPage.map((s: any) => store.store!.get(s.id)).filter((s): s is TLRecord => s !== undefined && s.typeName === 'shape')
|
// CRITICAL: Preserve x and y coordinates when refreshing shapes
|
||||||
|
const shapesToRefresh = storeShapesOnCurrentPage.map((s: any) => {
|
||||||
|
const shapeFromStore = store.store!.get(s.id)
|
||||||
|
if (shapeFromStore && shapeFromStore.typeName === 'shape') {
|
||||||
|
// Preserve original x and y from the store shape data
|
||||||
|
const originalX = s.x !== undefined && typeof s.x === 'number' && !isNaN(s.x) ? s.x : (shapeFromStore as any).x
|
||||||
|
const originalY = s.y !== undefined && typeof s.y === 'number' && !isNaN(s.y) ? s.y : (shapeFromStore as any).y
|
||||||
|
|
||||||
|
// Ensure x and y are preserved
|
||||||
|
if (typeof originalX === 'number' && !isNaN(originalX) && typeof originalY === 'number' && !isNaN(originalY)) {
|
||||||
|
return { ...shapeFromStore, x: originalX, y: originalY } as TLRecord
|
||||||
|
}
|
||||||
|
return shapeFromStore
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}).filter((s): s is TLRecord => s !== null && s.typeName === 'shape')
|
||||||
if (shapesToRefresh.length > 0) {
|
if (shapesToRefresh.length > 0) {
|
||||||
store.store.mergeRemoteChanges(() => {
|
store.store.mergeRemoteChanges(() => {
|
||||||
store.store!.put(shapesToRefresh)
|
store.store!.put(shapesToRefresh)
|
||||||
|
|
@ -337,9 +352,18 @@ export function Board() {
|
||||||
|
|
||||||
const currentStore = store.store
|
const currentStore = store.store
|
||||||
const shapesToRefresh = missingShapes.slice(0, 10) // Limit to first 10 to avoid performance issues
|
const shapesToRefresh = missingShapes.slice(0, 10) // Limit to first 10 to avoid performance issues
|
||||||
|
// CRITICAL: Preserve x and y coordinates when refreshing shapes
|
||||||
const refreshedShapes = shapesToRefresh.map((s: any) => {
|
const refreshedShapes = shapesToRefresh.map((s: any) => {
|
||||||
const shapeFromStore = currentStore.get(s.id)
|
const shapeFromStore = currentStore.get(s.id)
|
||||||
if (shapeFromStore && shapeFromStore.typeName === 'shape') {
|
if (shapeFromStore && shapeFromStore.typeName === 'shape') {
|
||||||
|
// Preserve original x and y from the store shape data
|
||||||
|
const originalX = s.x !== undefined && typeof s.x === 'number' && !isNaN(s.x) ? s.x : (shapeFromStore as any).x
|
||||||
|
const originalY = s.y !== undefined && typeof s.y === 'number' && !isNaN(s.y) ? s.y : (shapeFromStore as any).y
|
||||||
|
|
||||||
|
// Ensure x and y are preserved
|
||||||
|
if (typeof originalX === 'number' && !isNaN(originalX) && typeof originalY === 'number' && !isNaN(originalY)) {
|
||||||
|
return { ...shapeFromStore, x: originalX, y: originalY } as TLRecord
|
||||||
|
}
|
||||||
return shapeFromStore
|
return shapeFromStore
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|
|
||||||
|
|
@ -202,13 +202,14 @@ export function CustomMainMenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CRITICAL: Preserve existing coordinates - only set defaults if truly missing
|
// CRITICAL: Preserve existing coordinates - only set defaults if truly missing
|
||||||
// x/y can be 0, which is a valid coordinate, so check for undefined/null
|
// x/y can be 0, which is a valid coordinate, so check for undefined/null/NaN
|
||||||
// Note: validateShapeGeometry already ensures x/y are valid numbers
|
// Note: validateShapeGeometry already ensures x/y are valid numbers, but we need to
|
||||||
if (fixedShape.x === undefined || fixedShape.x === null) {
|
// handle the case where they might be NaN or Infinity after validation
|
||||||
fixedShape.x = Math.random() * 400 + 50 // Random position only if missing
|
if (fixedShape.x === undefined || fixedShape.x === null || isNaN(fixedShape.x) || !isFinite(fixedShape.x)) {
|
||||||
|
fixedShape.x = Math.random() * 400 + 50 // Random position only if missing or invalid
|
||||||
}
|
}
|
||||||
if (fixedShape.y === undefined || fixedShape.y === null) {
|
if (fixedShape.y === undefined || fixedShape.y === null || isNaN(fixedShape.y) || !isFinite(fixedShape.y)) {
|
||||||
fixedShape.y = Math.random() * 300 + 50 // Random position only if missing
|
fixedShape.y = Math.random() * 300 + 50 // Random position only if missing or invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve rotation, isLocked, opacity - only set defaults if missing
|
// Preserve rotation, isLocked, opacity - only set defaults if missing
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue