fix: paste shapes with bindings

pull/5742/head
Peng Xiao 2022-06-20 03:13:23 +08:00
parent ac9cc48fe8
commit e39fe772bb
2 changed files with 40 additions and 6 deletions

View File

@ -3,6 +3,7 @@ import {
fileToBase64, fileToBase64,
getSizeFromSrc, getSizeFromSrc,
TLAsset, TLAsset,
TLBinding,
TLShapeModel, TLShapeModel,
uniqueId, uniqueId,
} from '@tldraw/core' } from '@tldraw/core'
@ -19,6 +20,7 @@ export function usePaste() {
const assetsToCreate: ImageAsset[] = [] const assetsToCreate: ImageAsset[] = []
const shapesToCreate: TLShapeModel[] = [] const shapesToCreate: TLShapeModel[] = []
const bindingsToCreate: TLBinding[] = []
async function handleImage(item: ClipboardItem) { async function handleImage(item: ClipboardItem) {
const firstImageType = item.types.find(type => type.startsWith('image')) const firstImageType = item.types.find(type => type.startsWith('image'))
@ -62,10 +64,9 @@ export function usePaste() {
maxY: (shape.point?.[1] ?? point[1]) + (shape.size?.[1] ?? 4), maxY: (shape.point?.[1] ?? point[1]) + (shape.size?.[1] ?? 4),
})) }))
) )
const clonedShape = data.shapes.map((shape: TLShapeModel) => { const clonedShapes = shapes.map((shape: TLShapeModel) => {
return { return {
...shape, ...shape,
handles: {}, // TODO: may add this later?
id: uniqueId(), id: uniqueId(),
parentId: app.currentPageId, parentId: app.currentPageId,
point: [ point: [
@ -74,7 +75,34 @@ export function usePaste() {
], ],
} }
}) })
shapesToCreate.push(...clonedShape) shapesToCreate.push(...clonedShapes)
// Try to rebinding the shapes to the new assets
shapesToCreate.forEach((s, idx) => {
if (s.handles) {
Object.values(s.handles).forEach(h => {
if (h.bindingId) {
// try to bind the new shape
const binding = app.currentPage.bindings[h.bindingId]
// if the copied binding from/to is in the source
const oldFromIdx = shapes.findIndex(s => s.id === binding.fromId)
const oldToIdx = shapes.findIndex(s => s.id === binding.toId)
if (binding && oldFromIdx !== -1 && oldToIdx !== -1) {
const newBinding: TLBinding = {
...binding,
id: uniqueId(),
fromId: shapesToCreate[oldFromIdx].id,
toId: shapesToCreate[oldToIdx].id,
}
bindingsToCreate.push(newBinding)
h.bindingId = newBinding.id
} else {
h.bindingId = undefined
}
}
})
}
})
} }
} }
} }
@ -91,7 +119,7 @@ export function usePaste() {
} }
} }
const allShapesToAdd = [ const allShapesToAdd: TLShapeModel[] = [
...assetsToCreate.map((asset, i) => ({ ...assetsToCreate.map((asset, i) => ({
id: uniqueId(), id: uniqueId(),
type: 'image', type: 'image',
@ -103,9 +131,9 @@ export function usePaste() {
})), })),
...shapesToCreate, ...shapesToCreate,
] ]
app.createAssets(assetsToCreate) app.createAssets(assetsToCreate)
app.createShapes(allShapesToAdd) app.createShapes(allShapesToAdd)
app.currentPage.updateBindings(Object.fromEntries(bindingsToCreate.map(b => [b.id, b])))
app.setSelectedShapes(allShapesToAdd.map(s => s.id)) app.setSelectedShapes(allShapesToAdd.map(s => s.id))
}, []) }, [])

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import { Vec } from '@tldraw/vec' import { Vec } from '@tldraw/vec'
import { action, computed, makeObservable, observable } from 'mobx' import { action, computed, makeObservable, observable, toJS } from 'mobx'
import { BoundsUtils, KeyUtils } from '~utils' import { BoundsUtils, KeyUtils } from '~utils'
import { import {
TLSelectTool, TLSelectTool,
@ -470,6 +470,12 @@ export class TLApp<
} else { } else {
this.selectionRotation = 0 this.selectionRotation = 0
} }
if (process.env.NODE_ENV === 'development') {
console.log(
'setSelectedShapes',
newSelectedShapes.map(s => toJS(s.serialized))
)
}
return this return this
} }