Peng Xiao vor 3 Jahren
Ursprung
Commit
2f5680bd49

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
templates/onboarding-whiteboard.json


+ 7 - 1
tldraw/apps/tldraw-logseq/src/components/ContextMenu/ContextMenu.tsx

@@ -236,7 +236,13 @@ export const ContextMenu = observer(function ContextMenu({
               {developerMode && (
                 <ReactContextMenu.Item
                   className="tl-menu-item"
-                  onClick={() => console.log(app.selectedShapesArray.map(s => toJS(s.serialized)))}
+                  onClick={() => {
+                    if (app.selectedShapesArray.length === 1) {
+                      console.log(toJS(app.selectedShapesArray[0].serialized))
+                    } else {
+                      console.log(app.selectedShapesArray.map(s => toJS(s.serialized)))
+                    }
+                  }}
                 >
                   (Dev) Print shape props
                 </ReactContextMenu.Item>

+ 9 - 7
tldraw/apps/tldraw-logseq/src/hooks/usePaste.ts

@@ -56,7 +56,7 @@ function getFileType(filename: string) {
   return 'unknown'
 }
 
-type MaybeShapes = Shape['props'][] | null | undefined
+type MaybeShapes = TLShapeModel[] | null | undefined
 
 type CreateShapeFN<Args extends any[]> = (...args: Args) => Promise<MaybeShapes> | MaybeShapes
 
@@ -350,7 +350,7 @@ export function usePaste() {
 
       app.cursors.setCursor(TLCursor.Progress)
 
-      let newShapes: Shape['props'][] = []
+      let newShapes: TLShapeModel[] = []
       try {
         if (dataTransfer) {
           newShapes.push(...((await tryCreateShapesFromDataTransfer(dataTransfer)) ?? []))
@@ -372,11 +372,13 @@ export function usePaste() {
       })
 
       app.wrapUpdate(() => {
-        app.api.addClonedShapes(
-          allShapesToAdd,
-          [...imageAssetsToCreate, ...assetsToClone],
-          bindingsToCreate
-        )
+        if (assetsToClone.length > 0) {
+          app.createAssets(assetsToClone)
+        }
+        if (newShapes.length > 0) {
+          app.createShapes(newShapes)
+        }
+        app.currentPage.updateBindings(Object.fromEntries(bindingsToCreate.map(b => [b.id, b])))
 
         if (app.selectedShapesArray.length === 1 && allShapesToAdd.length === 1 && !fromDrop) {
           const source = app.selectedShapesArray[0]

+ 1 - 1
tldraw/apps/tldraw-logseq/src/lib/shapes/TextShape.tsx

@@ -53,7 +53,7 @@ export class TextShape extends TLTextShape<TextShapeProps> {
     fontWeight: 400,
     italic: false,
     padding: 4,
-    fontFamily: "var(--ls-font-family), 'Helvetica Neue', Helvetica, Arial, sans-serif",
+    fontFamily: 'var(--ls-font-family)',
     borderRadius: 0,
     stroke: '',
     fill: '',

+ 95 - 74
tldraw/packages/core/src/lib/TLApi/TLApi.ts

@@ -196,6 +196,84 @@ export class TLApi<S extends TLShape = TLShape, K extends TLEventMap = TLEventMa
     return this.app.createNewLineBinding(source, target)
   }
 
+  /** Clone shapes with given context */
+  cloneShapes = ({
+    shapes,
+    assets,
+    bindings,
+    point,
+  }: {
+    shapes: TLShapeModel[]
+    point: number[]
+    // assets & bindings are the context for creating shapes
+    assets: TLAsset[]
+    bindings: Record<string, TLBinding>
+  }) => {
+    const commonBounds = BoundsUtils.getCommonBounds(
+      shapes.map(shape => ({
+        minX: shape.point?.[0] ?? point[0],
+        minY: shape.point?.[1] ?? point[1],
+        width: shape.size?.[0] ?? 4,
+        height: shape.size?.[1] ?? 4,
+        maxX: (shape.point?.[0] ?? point[0]) + (shape.size?.[0] ?? 4),
+        maxY: (shape.point?.[1] ?? point[1]) + (shape.size?.[1] ?? 4),
+      }))
+    )
+
+    const clonedShapes = shapes.map(shape => {
+      return {
+        ...shape,
+        id: uniqueId(),
+        point: [
+          point[0] + shape.point![0] - commonBounds.minX,
+          point[1] + shape.point![1] - commonBounds.minY,
+        ],
+      }
+    })
+
+    const clonedBindings: TLBinding[] = []
+
+    // Try to rebinding the shapes with the given bindings
+    clonedShapes
+      .flatMap(s => Object.values(s.handles ?? {}))
+      .forEach(handle => {
+        if (!handle.bindingId) {
+          return
+        }
+        // try to bind the new shape
+        const binding = bindings[handle.bindingId]
+        if (binding) {
+          // 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: clonedShapes[oldFromIdx].id,
+              toId: clonedShapes[oldToIdx].id,
+            }
+            clonedBindings.push(newBinding)
+            handle.bindingId = newBinding.id
+          } else {
+            handle.bindingId = undefined
+          }
+        } else {
+          console.warn('binding not found', handle.bindingId)
+        }
+      })
+
+    const clonedAssets = assets.filter(asset => {
+      // do we need to create new asset id?
+      return clonedShapes.some(shape => shape.assetId === asset.id)
+    })
+    return {
+      shapes: clonedShapes,
+      assets: clonedAssets,
+      bindings: clonedBindings,
+    }
+  }
+
   getClonedShapesFromTldrString = (text: string, point: number[]) => {
     const safeParseJson = (json: string) => {
       try {
@@ -213,91 +291,34 @@ export class TLApi<S extends TLShape = TLShape, K extends TLEventMap = TLEventMa
     }
 
     try {
-      let assetsToClone: TLAsset[] = []
-      const bindingsToCreate: TLBinding[] = []
       const data = getWhiteboardsTldrFromText(text)
-
-      const shapes = data.shapes as TLShapeModel[]
-      assetsToClone = data.assets as TLAsset[]
-      const commonBounds = BoundsUtils.getCommonBounds(
-        shapes.map(shape => ({
-          minX: shape.point?.[0] ?? point[0],
-          minY: shape.point?.[1] ?? point[1],
-          width: shape.size?.[0] ?? 4,
-          height: shape.size?.[1] ?? 4,
-          maxX: (shape.point?.[0] ?? point[0]) + (shape.size?.[0] ?? 4),
-          maxY: (shape.point?.[1] ?? point[1]) + (shape.size?.[1] ?? 4),
-        }))
-      )
-
-      const bindings = data.bindings as Record<string, TLBinding>
-      const shapesToCreate = shapes.map(shape => {
-        return {
-          ...shape,
-          id: uniqueId(),
-          point: [
-            point[0] + shape.point![0] - commonBounds.minX,
-            point[1] + shape.point![1] - commonBounds.minY,
-          ],
-        }
+      if (!data) return null
+      const { shapes, bindings, assets } = data
+
+      return this.cloneShapes({
+        shapes,
+        bindings,
+        assets,
+        point,
       })
-
-      // Try to rebinding the shapes to the new assets
-      shapesToCreate
-        .flatMap(s => Object.values(s.handles ?? {}))
-        .forEach(h => {
-          if (!h.bindingId) {
-            return
-          }
-          // try to bind the new shape
-          const binding = bindings[h.bindingId]
-          if (binding) {
-            // 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
-            }
-          } else {
-            console.warn('binding not found', h.bindingId)
-          }
-        })
-
-      return {
-        shapes: shapesToCreate as S['props'][],
-        assets: assetsToClone,
-        bindings: bindingsToCreate,
-      }
     } catch (err) {
       console.log(err)
     }
     return null
   }
 
-  addClonedShapes = (shapes: S[] | TLShapeModel[], assets: TLAsset[], bindings: TLBinding[]) => {
-    if (assets.length > 0) {
-      this.app.createAssets(assets)
-    }
-    if (shapes.length > 0) {
-      this.app.createShapes(shapes)
-    }
-    this.app.currentPage.updateBindings(Object.fromEntries(bindings.map(b => [b.id, b])))
-    this.app.selectedTool.transition('idle') // clears possible editing states
-  }
-
   addClonedShapesFromTldrString = (text: string, point: number[]) => {
     const data = this.getClonedShapesFromTldrString(text, point)
     if (data) {
-      this.addClonedShapes(data.shapes, data.assets, data.bindings)
+      const { shapes, bindings, assets } = data
+      if (assets.length > 0) {
+        this.app.createAssets(assets)
+      }
+      if (shapes.length > 0) {
+        this.app.createShapes(shapes)
+      }
+      this.app.currentPage.updateBindings(Object.fromEntries(bindings.map(b => [b.id, b])))
+      this.app.selectedTool.transition('idle') // clears possible editing states
     }
   }
 }

+ 12 - 2
tldraw/packages/core/src/lib/TLApp/TLApp.ts

@@ -70,7 +70,7 @@ export class TLApp<
 
   keybindingRegistered = false
   uuid = uniqueId()
-  
+
   static id = 'app'
   static initial = 'select'
 
@@ -451,8 +451,18 @@ export class TLApp<
     return this
   }
 
+  @action removeUnusedAssets = (): this => {
+    const usedAssets = this.getCleanUpAssets()
+    Object.keys(this.assets).forEach(assetId => {
+      if (!usedAssets.some(asset => asset.id === assetId)) {
+        delete this.assets[assetId]
+      }
+    })
+    this.persist()
+    return this
+  }
+
   getCleanUpAssets<T extends TLAsset>(): T[] {
-    let deleted = false
     const usedAssets = new Set<T>()
 
     this.pages.forEach(p =>

+ 2 - 1
tldraw/packages/core/src/utils/getTextSize.ts

@@ -32,6 +32,7 @@ function getMeasurementDiv() {
     zIndex: '9999',
     userSelect: 'none',
     pointerEvents: 'none',
+    font: 'var(--ls-font-family)',
   })
 
   pre.tabIndex = -1
@@ -94,7 +95,7 @@ export function getTextLabelSize(
     melm.style.font = font
     melm.style.padding = padding + 'px'
 
-    const rect = melm.getBoundingClientRect();
+    const rect = melm.getBoundingClientRect()
 
     // In tests, offsetWidth and offsetHeight will be 0
     const width = Math.ceil(rect.width || 1)

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.