Browse Source

feat: whiteboard preview

Peng Xiao 3 years ago
parent
commit
4dc96790a4

+ 6 - 5
src/main/frontend/components/whiteboard.cljs

@@ -40,13 +40,14 @@
 (rum/defc dashboard-card
   [page-name]
   (let [tldr (page-name->tldr page-name)]
-    [:a.border.p-4.rounded.text-xl
+    [:div.rounded.text-lg.cursor-pointer.color-level.flex.flex-col.gap-1.overflow-hidden.dashboard-card
      {:on-mouse-down
       (fn [e]
         (util/stop e)
         (route-handler/redirect-to-whiteboard! page-name))}
-     [:span page-name]
-     (tldraw-preview tldr)]))
+     [:div.truncate.bg-white.px-4.py-1.dashboard-card-title page-name]
+     [:div.p-4.h-64.flex.justify-center
+      (tldraw-preview tldr)]]))
 
 (rum/defc whiteboard-dashboard
   []
@@ -57,9 +58,9 @@
                 :on-click (fn [e]
                             (util/stop e)
                             (route-handler/redirect-to-whiteboard! (d/squuid) true)))
-     [:div.flex.flex-col.gap-4.py-2
+     [:div.gap-8.py-4.grid.grid-cols-4.grid-rows-auto
       (for [whiteboard-name whiteboard-names]
-        [:<> {:key whiteboard-name}])]]))
+        [:<> {:key whiteboard-name} (dashboard-card whiteboard-name)])]]))
 
 (rum/defc whiteboard
   [route-match]

+ 8 - 1
src/main/frontend/components/whiteboard.css

@@ -1,2 +1,9 @@
-.logseq-tldraw .tl-container {
+.dashboard-card {
+  @apply hover:shadow;
+  border: 1px solid var(--ls-border-color);
+  background-color: var(--color-level-1);
+}
+
+.dashboard-card-title {
+  border-bottom: 1px solid var(--ls-border-color);
 }

+ 1 - 0
src/main/frontend/handler/route.cljs

@@ -57,6 +57,7 @@
   ([name]
    (redirect-to-whiteboard! name false))
   ([name new?]
+   (recent-handler/add-page-to-recent! (state/get-current-repo) name)
    (redirect! {:to :whiteboard
                :path-params {:name (str name)}
                :query-params (when new? {:new? 1})})))

+ 20 - 11
src/main/frontend/handler/whiteboard.cljs

@@ -59,11 +59,12 @@
     [page-block blocks]))
 
 (defn- whiteboard-clj->tldr [page-block blocks]
-  (let [shapes (map block->shape blocks)
+  (let [id (str (:block/uuid page-block))
+        shapes (map block->shape blocks)
         page-properties (:block/properties page-block)]
-    (clj->js {:currentPageId "page"
+    (clj->js {:currentPageId id
               :pages [(merge page-properties
-                             {:id "page"
+                             {:id id
                               :name "page"
                               :shapes shapes})]})))
 
@@ -71,6 +72,9 @@
   (let [[page-block blocks] (get-whiteboard-clj page-name)]
     (whiteboard-clj->tldr page-block blocks)))
 
+(defn get-whiteboard-entity [page-name]
+  (db-utils/entity [:block/name page-name]))
+
 (defn transact-tldr! [page-name tldr]
   (let [{:keys [pages]} (js->clj tldr :keywordize-keys true)
         tx (tldr-page->blocks-tx page-name (first pages))]
@@ -86,10 +90,11 @@
                               [{:id (.-id fs)
                                 :logseqLink page-or-block-id}])))))))
 
-(defonce default-tldr
-  #js {:currentPageId "page1",
+(defn get-default-tldr
+  [page-id]
+  #js {:currentPageId page-id,
        :selectedIds #js [],
-       :pages #js [#js {:id "page",
+       :pages #js [#js {:id page-id,
                         :name "Page",
                         :shapes #js [],
                         :bindings #js {},
@@ -98,8 +103,12 @@
 
 (defn create-new-whiteboard-page!
   ([name]
-   (transact-tldr! name default-tldr)
-   (let [uuid (or (parse-uuid name) (d/squuid))
-         entity (db-utils/entity [:block/name name])]
-     (outliner-file/sync-to-file entity)
-     (db-utils/transact! [{:db/id (:db/id entity) :block/uuid uuid}]))))
+   (let [uuid (or (parse-uuid name) (d/squuid))]
+     (transact-tldr! name (get-default-tldr (str uuid)))
+     (let [entity (get-whiteboard-entity name)
+           tx (assoc (select-keys entity [:db/id])
+                     :block/uuid uuid)]
+       (db-utils/transact! [tx])
+       (let [page-entity (get-whiteboard-entity name)]
+         (when (and page-entity (nil? (:block/file page-entity)))
+           (outliner-file/sync-to-file page-entity)))))))

+ 11 - 9
tldraw/apps/tldraw-logseq/src/lib/preview-manager.tsx

@@ -2,7 +2,7 @@ import { BoundsUtils, TLDocumentModel, TLShapeConstructor, TLViewport } from '@t
 import ReactDOMServer from 'react-dom/server'
 import { Shape, shapes } from './shapes'
 
-const SVG_EXPORT_PADDING = 0
+const SVG_EXPORT_PADDING = 16
 
 const ShapesMap = new Map(shapes.map(shape => [shape.id, shape]))
 
@@ -15,6 +15,7 @@ const getShapeClass = (type: string): TLShapeConstructor<Shape> => {
 
 export class PreviewManager {
   shapes: Shape[] | undefined
+  pageId: string | undefined;
   constructor(serializedApp?: TLDocumentModel<Shape>) {
     if (serializedApp) {
       this.load(serializedApp)
@@ -23,6 +24,7 @@ export class PreviewManager {
 
   load(snapshot: TLDocumentModel) {
     const page = snapshot.pages.find(p => snapshot.currentPageId === p.id)
+    this.pageId = page?.id
     this.shapes = page?.shapes.map(s => {
       const ShapeClass = getShapeClass(s.type)
       return new ShapeClass(s)
@@ -64,18 +66,18 @@ export class PreviewManager {
           {vBounds && (
             <>
               <rect
-                id="camera-rect"
+                id={this.pageId + "-camera-rect"}
                 transform={`translate(${vx}, ${vy})`}
                 width={vBounds.width}
                 height={vBounds.height}
               />
-              <mask id="camera-mask">
+              <mask id={this.pageId + "-camera-mask"}>
                 <rect width={commonBounds.width} height={commonBounds.height} fill="white" />
-                <use href="#camera-rect" fill="black" />
+                <use href={`#${this.pageId}-camera-rect`} fill="black" />
               </mask>
             </>
           )}
-          <g id="preview-shapes">
+          <g id={this.pageId + "-preview-shapes"}>
             {this.shapes?.map(s => {
               const {
                 bounds,
@@ -93,12 +95,12 @@ export class PreviewManager {
             })}
           </g>
         </defs>
-        <use href="#preview-shapes" />
+        <use href={`#${this.pageId}-preview-shapes`} />
         <rect
-          mask={vBounds ? 'url(#camera-mask)' : ''}
+          mask={vBounds ? `url(#${this.pageId}-camera-mask)` : ''}
           width={commonBounds.width}
           height={commonBounds.height}
-          fill="rgba(0, 0, 0, 0.2)"
+          fill="rgba(0, 0, 0, 0.02)"
         />
         {vBounds && (
           <use
@@ -107,7 +109,7 @@ export class PreviewManager {
             data-y={vy}
             data-width={vBounds.width}
             data-height={vBounds.height}
-            href="#camera-rect"
+            href={`#${this.pageId}-camera-rect`}
             fill="transparent"
             stroke="red"
             strokeWidth={4 / viewport.camera.zoom}

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

@@ -30,7 +30,7 @@ export class LineShape extends TLLineShape<LineShapeProps> {
       start: { id: 'start', canBind: true, point: [0, 0] },
       end: { id: 'end', canBind: true, point: [1, 1] },
     },
-    stroke: 'var(--tl-foreground)',
+    stroke: 'var(--tl-foreground, #000)',
     fill: '#ffffff',
     strokeWidth: 1,
     opacity: 1,

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

@@ -25,7 +25,7 @@ export class PencilShape extends TLDrawShape<PencilShapeProps> {
     point: [0, 0],
     points: [],
     isComplete: false,
-    stroke: 'var(--tl-foreground)',
+    stroke: 'var(--tl-foreground, #000)',
     fill: '#ffffff',
     strokeWidth: 2,
     opacity: 1,

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

@@ -32,7 +32,7 @@ export class TextShape extends TLTextShape<TextShapeProps> {
     padding: 4,
     fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif",
     borderRadius: 0,
-    stroke: 'var(--tl-foreground)',
+    stroke: 'var(--tl-foreground, #000)',
     fill: '#ffffff',
     strokeWidth: 2,
     opacity: 1,

+ 1 - 1
tldraw/packages/core/package.json

@@ -47,7 +47,7 @@
     "mobx": "^6.6.0",
     "mobx-react-lite": "^3.4.0",
     "mousetrap": "^1.6.5",
-    "nanoid": "^3.1.30",
+    "uuid": "^8.0.0",
     "rbush": "^3.0.1"
   },
   "devDependencies": {

+ 1 - 1
tldraw/packages/core/src/lib/shapes/TLShape/TLShape.tsx

@@ -357,7 +357,7 @@ export abstract class TLShape<P extends TLShapeProps = TLShapeProps, M = any> {
     const bounds = this.getBounds()
     return (
       <rect
-        fill="var(--tl-foreground)"
+        fill="var(--tl-foreground, #000)"
         fillOpacity={0.2}
         width={bounds.width}
         height={bounds.height}

+ 3 - 2
tldraw/packages/core/src/utils/index.ts

@@ -1,4 +1,5 @@
-import { nanoid } from 'nanoid'
+// @ts-expect-error no types for uuid
+import * as uuid from 'uuid'
 export * from './BoundsUtils'
 export * from './PointUtils'
 export * from './KeyUtils'
@@ -9,7 +10,7 @@ export * from './DataUtils'
 export * from './TextUtils'
 
 export function uniqueId() {
-  return nanoid()
+  return uuid.v1()
 }
 
 // via https://github.com/bameyrick/throttle-typescript

+ 1 - 1
tldraw/packages/react/package.json

@@ -46,7 +46,7 @@
     "mobx": "^6.6.0",
     "mobx-react-lite": "^3.4.0",
     "mousetrap": "^1.6.5",
-    "nanoid": "^3.1.30",
+    "uuid": "^8.0.0",
     "rbush": "^3.0.1"
   },
   "peerDependencies": {

+ 2 - 2
tldraw/yarn.lock

@@ -6797,7 +6797,7 @@ mz@^2.7.0:
     object-assign "^4.0.1"
     thenify-all "^1.0.0"
 
-nanoid@^3.1.30, nanoid@^3.3.4:
+nanoid@^3.3.4:
   version "3.3.4"
   resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
   integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
@@ -9037,7 +9037,7 @@ util@^0.11.0:
   dependencies:
     inherits "2.0.3"
 
-uuid@^8.3.2:
+uuid@^8.0.0, uuid@^8.3.2:
   version "8.3.2"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
   integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==