tldraw.cljs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. (ns frontend.extensions.tldraw
  2. "Adapters related to tldraw"
  3. (:require ["/frontend/tldraw-logseq" :as TldrawLogseq]
  4. [frontend.components.block :as block]
  5. [frontend.components.page :as page]
  6. [frontend.db.model :as model]
  7. [frontend.handler.editor :as editor-handler]
  8. [frontend.handler.route :as route-handler]
  9. [frontend.handler.whiteboard :as whiteboard-handler]
  10. [frontend.rum :as r]
  11. [frontend.search :as search]
  12. [frontend.state :as state]
  13. [frontend.util :as util]
  14. [goog.object :as gobj]
  15. [promesa.core :as p]
  16. [rum.core :as rum]
  17. [frontend.ui :as ui]))
  18. (def tldraw (r/adapt-class (gobj/get TldrawLogseq "App")))
  19. (def generate-preview (gobj/get TldrawLogseq "generateJSXFromApp"))
  20. (rum/defc page-cp
  21. [props]
  22. (page/page {:page-name (gobj/get props "pageName") :whiteboard? true}))
  23. (rum/defc block-cp
  24. [props]
  25. ((state/get-component :block/single-block) (uuid (gobj/get props "blockId"))))
  26. (rum/defc breadcrumb
  27. [props]
  28. (block/breadcrumb {:preview? true} (state/get-current-repo) (uuid (gobj/get props "blockId")) {:end-separator? true}))
  29. (rum/defc page-name-link
  30. [props]
  31. (block/page-cp {:preview? true} {:block/name (gobj/get props "pageName")}))
  32. (defn search-handler
  33. [q filters]
  34. (let [{:keys [pages? blocks? files?]} (js->clj filters {:keywordize-keys true})
  35. repo (state/get-current-repo)
  36. limit 100]
  37. (p/let [blocks (when blocks? (search/block-search repo q {:limit limit}))
  38. pages (when pages? (search/page-search q))
  39. files (when files? (search/file-search q limit))]
  40. (clj->js {:pages pages :blocks blocks :files files}))))
  41. (defn save-asset-handler
  42. [file]
  43. (-> (editor-handler/save-assets! nil (state/get-current-repo) [(js->clj file)])
  44. (p/then
  45. (fn [res]
  46. (when-let [[asset-file-name _ full-file-path] (and (seq res) (first res))]
  47. (editor-handler/resolve-relative-path (or full-file-path asset-file-name)))))))
  48. (def tldraw-renderers {:Page page-cp
  49. :Block block-cp
  50. :Breadcrumb breadcrumb
  51. :PageNameLink page-name-link})
  52. (defn get-tldraw-handlers [name]
  53. {:search search-handler
  54. :queryBlockByUUID #(clj->js (model/query-block-by-uuid (parse-uuid %)))
  55. :isWhiteboardPage model/whiteboard-page?
  56. :saveAsset save-asset-handler
  57. :makeAssetUrl editor-handler/make-asset-url
  58. :addNewBlock (fn [content]
  59. (str (whiteboard-handler/add-new-block! name content)))
  60. :sidebarAddBlock (fn [uuid type]
  61. (state/sidebar-add-block! (state/get-current-repo)
  62. (:db/id (model/get-page uuid))
  63. (keyword type)))
  64. :redirectToPage (fn [page-name]
  65. (if (model/whiteboard-page? page-name)
  66. (route-handler/redirect-to-whiteboard! page-name)
  67. (route-handler/redirect-to-page! page-name)))})
  68. (rum/defc tldraw-app
  69. [page-name block-id]
  70. (let [populate-onboarding? (whiteboard-handler/should-populate-onboarding-whiteboard? page-name)
  71. data (whiteboard-handler/page-name->tldr! page-name block-id)
  72. [loaded? set-loaded?] (rum/use-state false)
  73. on-mount (fn [tln]
  74. (when-let [^js api (gobj/get tln "api")]
  75. (p/then (when populate-onboarding?
  76. (whiteboard-handler/populate-onboarding-whiteboard api))
  77. #(do (when (and block-id (parse-uuid block-id))
  78. (. api selectShapes block-id)
  79. (. api zoomToSelection))
  80. (set-loaded? true)))))]
  81. (when data
  82. [:div.draw.tldraw.whiteboard.relative.w-full.h-full
  83. {:style {:overscroll-behavior "none"}
  84. :on-blur (fn [e]
  85. (when (#{"INPUT" "TEXTAREA"} (.-tagName (gobj/get e "target")))
  86. (state/clear-edit!)))
  87. ;; wheel -> overscroll may cause browser navigation
  88. :on-wheel util/stop-propagation}
  89. (when
  90. (and populate-onboarding? (not loaded?))
  91. [:div.absolute.inset-0.flex.items-center.justify-center
  92. {:style {:z-index 200}}
  93. (ui/loading "Loading onboarding whiteboard ...")])
  94. (tldraw {:renderers tldraw-renderers
  95. :handlers (get-tldraw-handlers page-name)
  96. :onMount on-mount
  97. :onPersist (fn [app]
  98. (let [document (gobj/get app "serialized")]
  99. (whiteboard-handler/transact-tldr! page-name document)))
  100. :model data})])))