block.cljs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. (ns frontend.handler.block
  2. (:require [frontend.util :as util]
  3. [clojure.walk :as walk]
  4. [frontend.db :as db]
  5. [frontend.state :as state]
  6. [frontend.format.mldoc :as mldoc]
  7. [frontend.date :as date]
  8. [frontend.config :as config]
  9. [datascript.core :as d]))
  10. (defn blocks->vec-tree [col]
  11. (let [col (map (fn [h] (cond->
  12. h
  13. (not (:block/dummy? h))
  14. (dissoc h :block/meta))) col)
  15. parent? (fn [item children]
  16. (and (seq children)
  17. (every? #(< (:block/level item) (:block/level %)) children)))]
  18. (loop [col (reverse col)
  19. children (list)]
  20. (if (empty? col)
  21. children
  22. (let [[item & others] col
  23. cur-level (:block/level item)
  24. bottom-level (:block/level (first children))
  25. pre-block? (:block/pre-block? item)]
  26. (cond
  27. (empty? children)
  28. (recur others (list item))
  29. (<= bottom-level cur-level)
  30. (recur others (conj children item))
  31. pre-block?
  32. (recur others (cons item children))
  33. (> bottom-level cur-level) ; parent
  34. (let [[children other-children] (split-with (fn [h]
  35. (> (:block/level h) cur-level))
  36. children)
  37. children (cons
  38. (assoc item :block/children children)
  39. other-children)]
  40. (recur others children))))))))
  41. ;; recursively with children content for tree
  42. (defn get-block-content-rec
  43. ([block]
  44. (get-block-content-rec block (fn [block] (:block/content block))))
  45. ([block transform-fn]
  46. (let [contents (atom [])
  47. _ (walk/prewalk
  48. (fn [form]
  49. (when (map? form)
  50. (when-let [content (:block/content form)]
  51. (swap! contents conj (transform-fn form))))
  52. form)
  53. block)]
  54. (apply util/join-newline @contents))))
  55. ;; with children content
  56. (defn get-block-full-content
  57. ([repo block-id]
  58. (get-block-full-content repo block-id (fn [block] (:block/content block))))
  59. ([repo block-id transform-fn]
  60. (let [blocks (db/get-block-and-children-no-cache repo block-id)]
  61. (->> blocks
  62. (map transform-fn)
  63. (apply util/join-newline)))))
  64. (defn get-block-end-pos-rec
  65. [repo block]
  66. (let [children (:block/children block)]
  67. (if (seq children)
  68. (get-block-end-pos-rec repo (last children))
  69. (if-let [end-pos (get-in block [:block/meta :end-pos])]
  70. end-pos
  71. (when-let [block (db/entity repo [:block/uuid (:block/uuid block)])]
  72. (get-in block [:block/meta :end-pos]))))))
  73. (defn get-block-ids
  74. [block]
  75. (let [ids (atom [])
  76. _ (walk/prewalk
  77. (fn [form]
  78. (when (map? form)
  79. (when-let [id (:block/uuid form)]
  80. (swap! ids conj id)))
  81. form)
  82. block)]
  83. @ids))
  84. (defn collapse-block!
  85. [block]
  86. (let [repo (:block/repo block)]
  87. (db/transact! repo
  88. [{:block/uuid (:block/uuid block)
  89. :block/collapsed? true}])))
  90. (defn collapse-blocks!
  91. [block-ids]
  92. (let [repo (state/get-current-repo)]
  93. (db/transact! repo
  94. (map
  95. (fn [id]
  96. {:block/uuid id
  97. :block/collapsed? true})
  98. block-ids))))
  99. (defn expand-block!
  100. [block]
  101. (let [repo (:block/repo block)]
  102. (db/transact! repo
  103. [{:block/uuid (:block/uuid block)
  104. :block/collapsed? false}])))
  105. (defn expand-blocks!
  106. [block-ids]
  107. (let [repo (state/get-current-repo)]
  108. (db/transact! repo
  109. (map
  110. (fn [id]
  111. {:block/uuid id
  112. :block/collapsed? false})
  113. block-ids))))
  114. (defn with-dummy-block
  115. ([blocks format]
  116. (with-dummy-block blocks format {} {}))
  117. ([blocks format default-option {:keys [journal? page-name]
  118. :or {journal? false}}]
  119. (let [format (or format (state/get-preferred-format) :markdown)
  120. blocks (if (and journal?
  121. (seq blocks)
  122. (when-let [title (second (first (:block/title (first blocks))))]
  123. (date/valid-journal-title? title)))
  124. (rest blocks)
  125. blocks)
  126. blocks (vec blocks)]
  127. (cond
  128. (and (seq blocks)
  129. (or (and (> (count blocks) 1)
  130. (:block/pre-block? (first blocks)))
  131. (and (>= (count blocks) 1)
  132. (not (:block/pre-block? (first blocks))))))
  133. blocks
  134. :else
  135. (let [last-block (last blocks)
  136. end-pos (get-in last-block [:block/meta :end-pos] 0)
  137. dummy (merge last-block
  138. (let [uuid (d/squuid)]
  139. {:block/uuid uuid
  140. :block/title ""
  141. :block/content (config/default-empty-block format)
  142. :block/format format
  143. :block/level 2
  144. :block/priority nil
  145. :block/anchor (str uuid)
  146. :block/meta {:start-pos end-pos
  147. :end-pos end-pos}
  148. :block/body nil
  149. :block/dummy? true
  150. :block/marker nil
  151. :block/pre-block? false})
  152. default-option)]
  153. (conj blocks dummy))))))