diff --git a/deps/graph-parser/src/logseq/graph_parser/extract.cljc b/deps/graph-parser/src/logseq/graph_parser/extract.cljc index 0a8d919ef8..26c06afe4c 100644 --- a/deps/graph-parser/src/logseq/graph_parser/extract.cljc +++ b/deps/graph-parser/src/logseq/graph_parser/extract.cljc @@ -250,11 +250,7 @@ page-block (first pages) page-name (or (:block/name page-block) (filepath->page-name file)) - page-original-name (-> (:block/original-name page-block) - (#(cond (some? %) % - (= (gp-util/page-name-sanity-lc %) - (gp-util/page-name-sanity-lc page-name)) page-name - :else page-name))) + page-original-name (:block/original-name page-block) page-name (gp-util/page-name-sanity-lc page-name) page {:block/name page-name :block/type "whiteboard" diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 56653b4a9a..308fec5e24 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -5,6 +5,7 @@ [cljs-bean.core :as bean] [cljs.core.match :refer [match]] [cljs.reader :as reader] + [clojure.set :as set] [clojure.string :as string] [clojure.walk :as walk] [datascript.core :as d] @@ -39,11 +40,13 @@ [frontend.handler.common :as common-handler] [frontend.handler.dnd :as dnd] [frontend.handler.editor :as editor-handler] + [frontend.handler.file-sync :as file-sync] [frontend.handler.plugin :as plugin-handler] [frontend.handler.query :as query-handler] [frontend.handler.repeated :as repeated] [frontend.handler.route :as route-handler] [frontend.handler.ui :as ui-handler] + [frontend.handler.whiteboard :as whiteboard-handler] [frontend.mobile.util :as mobile-util] [frontend.modules.outliner.tree :as tree] [frontend.search :as search] @@ -62,8 +65,8 @@ [logseq.graph-parser.block :as gp-block] [logseq.graph-parser.config :as gp-config] [logseq.graph-parser.mldoc :as gp-mldoc] - [logseq.graph-parser.text :as text] [logseq.graph-parser.property :as gp-property] + [logseq.graph-parser.text :as text] [logseq.graph-parser.util :as gp-util] [logseq.graph-parser.util.block-ref :as block-ref] [logseq.graph-parser.util.page-ref :as page-ref] @@ -71,8 +74,6 @@ [promesa.core :as p] [reitit.frontend.easy :as rfe] [rum.core :as rum] - [frontend.handler.file-sync :as file-sync] - [clojure.set :as set] [shadow.loader :as loader])) (defn safe-read-string @@ -535,6 +536,11 @@ (:db/id page-entity) :page)) + (whiteboard-handler/inside-whiteboard-portal-container (.-target e)) + (whiteboard-handler/add-new-block-portal-shape! + page-name + (whiteboard-handler/closest-whiteboard-shape-id (.-target e))) + whiteboard-page? (route-handler/redirect-to-whiteboard! page-name) @@ -885,12 +891,19 @@ (not (util/right-click? e))) (util/stop e) - (if (gobj/get e "shiftKey") + (cond + (gobj/get e "shiftKey") (state/sidebar-add-block! (state/get-current-repo) (:db/id block) :block-ref) + (whiteboard-handler/inside-whiteboard-portal-container (.-target e)) + (whiteboard-handler/add-new-block-portal-shape! + (:block/uuid block) + (whiteboard-handler/closest-whiteboard-shape-id (.-target e))) + + :else (match [block-type (util/electron?)] ;; pdf annotation [:annotation true] (pdf-assets/open-block-ref! block) diff --git a/src/main/frontend/handler/whiteboard.cljs b/src/main/frontend/handler/whiteboard.cljs index 211b33a95b..3a6af1893d 100644 --- a/src/main/frontend/handler/whiteboard.cljs +++ b/src/main/frontend/handler/whiteboard.cljs @@ -1,6 +1,7 @@ (ns frontend.handler.whiteboard "Whiteboard related handlers" (:require [datascript.core :as d] + [dommy.core :as dom] [frontend.db.model :as model] [frontend.db.utils :as db-utils] [frontend.handler.route :as route-handler] @@ -127,6 +128,32 @@ (create-new-whiteboard-page! name) (route-handler/redirect-to-whiteboard! name))) +(defn ->logseq-portal-shape + [block-id point] + {:blockType (if (parse-uuid (str block-id)) "B" "P") + :id (str (d/squuid)) + :compact false + :pageId (str block-id) + :point point + :size [400, 0] + :type "logseq-portal"}) + +(defn add-new-block-portal-shape! + "Given the block uuid, add a new shape to the referenced block. + By default it will be placed next to the given shape id" + [block-uuid source-shape & {:keys [link? bottom?]}] + (let [app (state/active-tldraw-app) + api (.-api app) + point (-> (.getShapeById app source-shape) + (.-bounds) + ((fn [bounds] (if bottom? + [(.-minX bounds) (+ 64 (.-maxY bounds))] + [(+ 64 (.-maxX bounds)) (.-minY bounds)])))) + shape (->logseq-portal-shape block-uuid point)] + (.createShapes api (clj->js shape)) + (when link? + (.createNewLineBinding api source-shape (:id shape))))) + (defn page-name->tldr! ([page-name] (page-name->tldr! page-name nil)) @@ -169,3 +196,12 @@ :block/parent {:block/name page-name}}] (db-utils/transact! [tx]) uuid)) + +(defn inside-whiteboard-portal-container + [target] + (dom/closest target ".tl-logseq-cp-container")) + +(defn closest-whiteboard-shape-id + [target] + (when-let [shape-el (dom/closest target "[data-shape-id]")] + (.getAttribute shape-el "data-shape-id"))) \ No newline at end of file diff --git a/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx b/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx index 8cca46a4b2..89cdf0b942 100644 --- a/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx +++ b/tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx @@ -835,6 +835,7 @@ export class LogseqPortalShape extends TLBoxShape { data-collapsed={this.collapsed} data-page-id={pageId} data-portal-selected={portalSelected} + data-editing={isEditing} style={{ background: this.props.compact ? 'transparent' : fill, color: stroke, diff --git a/tldraw/apps/tldraw-logseq/src/styles.css b/tldraw/apps/tldraw-logseq/src/styles.css index aace791dcf..da4f2b8420 100644 --- a/tldraw/apps/tldraw-logseq/src/styles.css +++ b/tldraw/apps/tldraw-logseq/src/styles.css @@ -625,6 +625,10 @@ button.tl-select-input-trigger { user-select: text; transform-origin: top left; + &[data-collapsed='true'][data-editing='false'] { + @apply overflow-hidden; + } + &[data-portal-selected='true'] { filter: brightness(0.9) contrast(0.5); } diff --git a/tldraw/packages/core/src/lib/TLApi/TLApi.ts b/tldraw/packages/core/src/lib/TLApi/TLApi.ts index eaa2a7aff7..57f45c84a8 100644 --- a/tldraw/packages/core/src/lib/TLApi/TLApi.ts +++ b/tldraw/packages/core/src/lib/TLApi/TLApi.ts @@ -192,7 +192,7 @@ export class TLApi { + createNewLineBinding = (source: S | string, target: S | string) => { return this.app.createNewLineBinding(source, target) } } diff --git a/tldraw/packages/core/src/lib/TLApp/TLApp.ts b/tldraw/packages/core/src/lib/TLApp/TLApp.ts index 7d17d8d74a..c1ab9379ce 100644 --- a/tldraw/packages/core/src/lib/TLApp/TLApp.ts +++ b/tldraw/packages/core/src/lib/TLApp/TLApp.ts @@ -425,7 +425,9 @@ export class TLApp< distribute = (type: DistributeType, shapes: S[] = this.selectedShapesArray): this => { if (shapes.length < 2) return this - const deltaMap = Object.fromEntries(BoundsUtils.getDistributions(shapes, type).map(d => [d.id, d])) + const deltaMap = Object.fromEntries( + BoundsUtils.getDistributions(shapes, type).map(d => [d.id, d]) + ) shapes.forEach(shape => { if (deltaMap[shape.id]) shape.update({ point: deltaMap[shape.id].next }) @@ -662,9 +664,11 @@ export class TLApp< return this.setBindingShapes() } - @action createNewLineBinding = (source: TLShape, target: TLShape) => { - if (source.canBind && target.canBind) { - const result = createNewLineBinding(source, target) + @action createNewLineBinding = (source: S | string, target: S | string) => { + const src = typeof source === 'string' ? this.getShapeById(source) : source + const tgt = typeof target === 'string' ? this.getShapeById(target) : target + if (src?.canBind && tgt?.canBind) { + const result = createNewLineBinding(src, tgt) if (result) { const [newLine, newBindings] = result this.createShapes([newLine]) diff --git a/tldraw/packages/react/src/components/Shape/Shape.tsx b/tldraw/packages/react/src/components/Shape/Shape.tsx index 8fa33c959e..acc12807d1 100644 --- a/tldraw/packages/react/src/components/Shape/Shape.tsx +++ b/tldraw/packages/react/src/components/Shape/Shape.tsx @@ -37,7 +37,14 @@ export const Shape = observer(function Shape({ } = shape const events = useShapeEvents(shape) return ( - +