Просмотр исходного кода

Merge pull request #9480 from logseq/fix/whiteboards-issues

Fix (Whiteboards): Various issues
Gabriel Horner 2 лет назад
Родитель
Сommit
cb0d52fb1c

+ 31 - 0
e2e-tests/whiteboards.spec.ts

@@ -126,6 +126,37 @@ test('clone the rectangle', async ({ page }) => {
   await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
 })
 
+test('group the rectangles', async ({ page }) => {
+  await page.keyboard.press(modKey + '+a')
+  await page.keyboard.press(modKey + '+g')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(1)
+})
+
+test('delete the group', async ({ page }) => {
+  await page.keyboard.press(modKey + '+a')
+
+  await page.keyboard.press('Delete')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(0)
+    // should also delete the grouped shapes
+  await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(0)
+})
+
+test('undo the group deletion', async ({ page }) => {
+  await page.keyboard.press(modKey + '+z')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(1)
+  await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
+})
+
+test('undo the group action', async ({ page }) => {
+  await page.keyboard.press(modKey + '+z')
+
+  await expect(page.locator('.logseq-tldraw .tl-group-container')).toHaveCount(0)
+  await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
+})
+
 test('connect rectangles with an arrow', async ({ page }) => {
   const canvas = await page.waitForSelector('.logseq-tldraw')
   const bounds = (await canvas.boundingBox())!

+ 2 - 1
src/main/frontend/extensions/tldraw.cljs

@@ -138,7 +138,8 @@
                      (when-let [^js api (gobj/get tln "api")]
                       (p/then (when populate-onboarding?
                                 (whiteboard-handler/populate-onboarding-whiteboard api))
-                              #(do (state/focus-whiteboard-shape tln block-id)
+                              #(do (whiteboard-handler/cleanup! (.-currentPage tln))
+                                   (state/focus-whiteboard-shape tln block-id)
                                    (set-loaded-app tln))))))]
     (rum/use-effect! (fn []
                        (when (and loaded-app block-id)

+ 7 - 1
src/main/frontend/handler/whiteboard.cljs

@@ -153,13 +153,14 @@
         (compute-tx app tl-page new-id-nonces db-id-nonces page-name replace?)
         tx-data (concat delete-blocks [page-block] upserted-blocks)
         new-shapes (get-in metadata [:data :new-shapes])
+        deleted-shapes (get-in metadata [:data :deleted-shapes])
         metadata' (cond
                     ;; group
                     (some #(= "group" (:type %)) new-shapes)
                     (assoc metadata :whiteboard/op :group)
 
                     ;; ungroup
-                    (some #(= "group" (:type %)) (get-in metadata [:data :deleted-shapes]))
+                    (and (not-empty deleted-shapes) (every? #(= "group" (:type %)) deleted-shapes))
                     (assoc metadata :whiteboard/op :un-group)
 
                     ;; arrow
@@ -361,6 +362,11 @@
   [^js api ids]
   (apply (.-selectShapes api) ids))
 
+(defn cleanup!
+  [^js tl-page]
+  (let [shapes (.-shapes tl-page)]
+    (.cleanup tl-page (map #(.-id %) shapes))))
+
 (defn update-bindings!
   [^js tl-page page-name]
   (when-let [page (db/entity [:block/name page-name])]

+ 1 - 1
tldraw/apps/tldraw-logseq/src/components/QuickLinks/QuickLinks.tsx

@@ -25,7 +25,7 @@ export const QuickLinks: TLQuickLinksComponent<Shape> = observer(({ shape }) =>
         link[0].toLowerCase() !== app.currentPage.name &&
         handlers.getBlockPageName(link[0]) !== app.currentPage.name
     )
-  }, [shape.props.type, shape.props.parentId, shape.props.refs])
+  }, [shape.props.id, shape.props.type, shape.props.parentId, shape.props.refs])
 
   if (links.length === 0) return null
 

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

@@ -29,7 +29,7 @@ export class GroupShape extends TLGroupShape<GroupShapeProps> {
     const Indicator = this.ReactIndicator
 
     return (
-      <SVGContainer {...events}>
+      <SVGContainer {...events} className="tl-group-container">
         <rect
           className={'tl-hitarea-fill'}
           x={strokeWidth / 2}

+ 2 - 1
tldraw/packages/core/src/lib/TLPage/TLPage.ts

@@ -1,4 +1,5 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
+import { deepEqual } from '@tldraw/core'
 import { intersectRayBounds, TLBounds } from '@tldraw/intersect'
 import Vec from '@tldraw/vec'
 import { action, autorun, computed, makeObservable, observable, toJS, transaction } from 'mobx'
@@ -264,7 +265,7 @@ export class TLPage<S extends TLShape = TLShape, E extends TLEventMap = TLEventM
           ...fromDelta,
         }
         shapeChanged = true
-        this.getShapeById(nextShape.id)?.update(nextShape, false, true)
+        this.getShapeById(nextShape.id)?.update(nextShape, false, deepEqual(fromDelta?.handles, fromShape?.props.handles))
       }
     })
 

+ 16 - 0
tldraw/packages/core/src/lib/shapes/TLGroupShape/TLGroupShape.tsx

@@ -3,6 +3,7 @@ import { computed, makeObservable } from 'mobx'
 import { BoundsUtils } from '../../../utils'
 import { TLBoxShape, TLBoxShapeProps } from '../TLBoxShape'
 import type { TLShape } from '../TLShape'
+import { useApp } from '@tldraw/react'
 
 export interface TLGroupShapeProps extends TLBoxShapeProps {
   children: string[] // shape ids
@@ -41,6 +42,21 @@ export class TLGroupShape<
   }
 
   getBounds = (): TLBounds => {
+    // A group without children needs to be removed
+    if (this.shapes.length === 0) {
+      const app = useApp<Shape>()
+      app.deleteShapes([this.id])
+
+      return {
+        minX: 0,
+        minY: 0,
+        maxX: 0,
+        maxY: 0,
+        width: 0,
+        height: 0,
+      }
+    }
+
     return BoundsUtils.getCommonBounds(this.shapes.map(s => s.getBounds()))
   }
 }