mirror of https://github.com/logseq/logseq
fix: broken block ref when backspace/delete a block
parent
8a0a41ccb8
commit
ea019bcad5
|
@ -353,8 +353,16 @@
|
|||
block (apply dissoc block db-schema/retract-attributes)]
|
||||
(profile
|
||||
"Save block: "
|
||||
(let [block' (wrap-parse-block block)
|
||||
opts' (merge opts {:outliner-op :save-block})]
|
||||
(let [original-uuid (:block/uuid (db/entity (:db/id block)))
|
||||
uuid-changed? (not= (:block/uuid block) original-uuid)
|
||||
block' (-> (wrap-parse-block block)
|
||||
;; :block/uuid might be changed when backspace/delete
|
||||
;; a block that has been refed
|
||||
(assoc :block/uuid (:block/uuid block)))
|
||||
opts' (merge opts (cond-> {:outliner-op :save-block}
|
||||
uuid-changed?
|
||||
(assoc :uuid-changed {:from (:block/uuid block)
|
||||
:to original-uuid})))]
|
||||
(outliner-tx/transact!
|
||||
opts'
|
||||
(outliner-core/save-block! block'))
|
||||
|
@ -760,6 +768,9 @@
|
|||
(let [original-content (util/trim-safe (:block/content block))
|
||||
value' (-> (property/remove-built-in-properties format original-content)
|
||||
(drawer/remove-logbook))
|
||||
value (->> value
|
||||
(property/remove-properties format)
|
||||
(drawer/remove-logbook))
|
||||
new-value (str value' value)
|
||||
tail-len (count value)
|
||||
pos (max
|
||||
|
@ -788,9 +799,9 @@
|
|||
(let [page-id (:db/id (:block/page (db/entity [:block/uuid block-id])))
|
||||
page-blocks-count (and page-id (db/get-page-blocks-count repo page-id))]
|
||||
(when (> page-blocks-count 1)
|
||||
(let [block (db/entity [:block/uuid block-id])
|
||||
has-children? (seq (:block/_parent block))
|
||||
block (db/pull (:db/id block))
|
||||
(let [block-e (db/entity [:block/uuid block-id])
|
||||
has-children? (seq (:block/_parent block-e))
|
||||
block (db/pull (:db/id block-e))
|
||||
left (tree/-get-left (outliner-core/block block))
|
||||
left-has-children? (and left
|
||||
(when-let [block-id (:block/uuid (:data left))]
|
||||
|
@ -808,9 +819,15 @@
|
|||
(assoc :concat-data
|
||||
{:last-edit-block (:block/uuid block)}))]
|
||||
(outliner-tx/transact! transact-opts
|
||||
(when concat-prev-block?
|
||||
(save-block! repo prev-block new-content))
|
||||
(delete-block-aux! block delete-children?))
|
||||
(if concat-prev-block?
|
||||
(let [prev-block' (if (seq (:block/_refs block-e))
|
||||
(assoc prev-block
|
||||
:block/uuid (:block/uuid block)
|
||||
:block/additional-properties (:block/properties block))
|
||||
prev-block)]
|
||||
(delete-block-aux! block delete-children?)
|
||||
(save-block! repo prev-block' new-content))
|
||||
(delete-block-aux! block delete-children?)))
|
||||
(move-fn)))))))))
|
||||
(state/set-editor-op! nil)))
|
||||
|
||||
|
@ -1224,10 +1241,7 @@
|
|||
(let [value (string/trim value)]
|
||||
;; FIXME: somehow frontend.components.editor's will-unmount event will loop forever
|
||||
;; maybe we shouldn't save the block/file in "will-unmount" event?
|
||||
(save-block-if-changed! block value
|
||||
(merge
|
||||
{:init-properties (:block/properties block)}
|
||||
opts))))
|
||||
(save-block-if-changed! block value opts)))
|
||||
|
||||
(defn save-block!
|
||||
([repo block-or-uuid content]
|
||||
|
@ -2611,11 +2625,22 @@
|
|||
transact-opts {:outliner-op :delete-block
|
||||
:concat-data {:last-edit-block (:block/uuid edit-block)
|
||||
:end? true}}
|
||||
new-content (str value "" (:block/content next-block))
|
||||
repo (state/get-current-repo)]
|
||||
next-block-has-refs? (some? (:block/_refs (db/entity (:db/id next-block))))
|
||||
new-content (if next-block-has-refs?
|
||||
(str value ""
|
||||
(->> (:block/content next-block)
|
||||
(property/remove-properties (:block/format next-block))
|
||||
(drawer/remove-logbook)))
|
||||
(str value "" (:block/content next-block)))
|
||||
repo (state/get-current-repo)
|
||||
edit-block' (if next-block-has-refs?
|
||||
(assoc edit-block
|
||||
:block/uuid (:block/uuid next-block)
|
||||
:block/additional-properties (dissoc (:block/properties next-block) :block/uuid))
|
||||
edit-block)]
|
||||
(outliner-tx/transact! transact-opts
|
||||
(save-block! repo edit-block new-content)
|
||||
(delete-block-aux! next-block false))
|
||||
(delete-block-aux! next-block false)
|
||||
(save-block! repo edit-block' new-content))
|
||||
|
||||
(state/set-edit-content! input-id new-content)
|
||||
(cursor/move-cursor-to input current-pos)))))
|
||||
|
|
|
@ -32,8 +32,10 @@
|
|||
content))
|
||||
|
||||
(defn transform-content
|
||||
[{:block/keys [collapsed? format pre-block? unordered content left page parent properties]} level {:keys [heading-to-list?]}]
|
||||
(let [heading (:heading properties)
|
||||
[{:block/keys [collapsed? format pre-block? unordered content left page parent properties] :as b} level {:keys [heading-to-list?]}]
|
||||
(let [block-ref-not-saved? (and (seq (:block/_refs (db/entity (:db/id b))))
|
||||
(not (string/includes? content (str (:block/uuid b)))))
|
||||
heading (:heading properties)
|
||||
markdown? (= :markdown format)
|
||||
content (or content "")
|
||||
pre-block? (or pre-block?
|
||||
|
@ -80,7 +82,10 @@
|
|||
(string/blank? new-content))
|
||||
""
|
||||
" ")]
|
||||
(str prefix sep new-content)))]
|
||||
(str prefix sep new-content)))
|
||||
content (if block-ref-not-saved?
|
||||
(property/insert-property format content :id (str (:block/uuid b)))
|
||||
content)]
|
||||
content))
|
||||
|
||||
|
||||
|
|
|
@ -859,6 +859,11 @@
|
|||
see also `frontend.modules.outliner.transaction/transact!`"
|
||||
nil)
|
||||
|
||||
(def ^:private ^:dynamic *transaction-opts*
|
||||
"Stores transaction opts that are generated by one or more write-operations,
|
||||
see also `frontend.modules.outliner.transaction/transact!`"
|
||||
nil)
|
||||
|
||||
(defn- op-transact!
|
||||
[fn-var & args]
|
||||
{:pre [(var? fn-var)]}
|
||||
|
|
|
@ -51,6 +51,28 @@
|
|||
[tx-report]
|
||||
(get-in tx-report [:tempids :db/current-tx])))
|
||||
|
||||
#?(:cljs
|
||||
(defn update-block-refs
|
||||
[txs opts]
|
||||
(if-let [changed (:uuid-changed opts)]
|
||||
(let [{:keys [from to]} changed
|
||||
from-e (db/entity [:block/uuid from])
|
||||
to-e (db/entity [:block/uuid to])
|
||||
from-id (:db/id from-e)
|
||||
to-id (:db/id to-e)
|
||||
refs (:block/_refs from-e)
|
||||
path-refs (:block/_path-refs from-e)
|
||||
refs-txs (mapcat (fn [ref refs]
|
||||
(let [id (:db/id ref)]
|
||||
[[:db/retract id :block/refs from-id]
|
||||
[:db/add id :block/refs to-id]])) refs)
|
||||
path-refs-txs (mapcat (fn [ref refs]
|
||||
(let [id (:db/id ref)]
|
||||
[[:db/retract id :block/path-refs from-id]
|
||||
[:db/add id :block/path-refs to-id]])) path-refs)]
|
||||
(concat txs refs-txs path-refs-txs))
|
||||
txs)))
|
||||
|
||||
#?(:cljs
|
||||
(defn transact!
|
||||
[txs opts before-editor-cursor]
|
||||
|
@ -58,8 +80,10 @@
|
|||
txs (map (fn [m] (if (map? m)
|
||||
(dissoc m
|
||||
:block/children :block/meta :block/top? :block/bottom? :block/anchor
|
||||
:block/title :block/body :block/level :block/container :db/other-tx)
|
||||
m)) txs)]
|
||||
:block/title :block/body :block/level :block/container :db/other-tx
|
||||
:block/additional-properties)
|
||||
m)) txs)
|
||||
txs (update-block-refs txs opts)]
|
||||
(when (and (seq txs)
|
||||
(not (:skip-transact? opts))
|
||||
(not (contains? (:file/unlinked-dirs @state/state)
|
||||
|
|
|
@ -25,22 +25,27 @@
|
|||
[opts & body]
|
||||
(assert (or (map? opts) (symbol? opts)) (str "opts is not a map or symbol, type: " (type opts) ))
|
||||
`(let [transact-data# frontend.modules.outliner.core/*transaction-data*
|
||||
transaction-opts# frontend.modules.outliner.core/*transaction-opts*
|
||||
opts# (if transact-data#
|
||||
(assoc ~opts :nested-transaction? true)
|
||||
~opts)
|
||||
before-editor-cursor# (frontend.state/get-current-edit-block-and-position)]
|
||||
(when transaction-opts# (conj! transaction-opts# opts#))
|
||||
(if transact-data#
|
||||
(do ~@body)
|
||||
(binding [frontend.modules.outliner.core/*transaction-data* (transient [])]
|
||||
(binding [frontend.modules.outliner.core/*transaction-data* (transient [])
|
||||
frontend.modules.outliner.core/*transaction-opts* (transient [])]
|
||||
~@body
|
||||
(let [r# (persistent! frontend.modules.outliner.core/*transaction-data*)
|
||||
tx# (mapcat :tx-data r#)
|
||||
;; FIXME: should we merge all the tx-meta?
|
||||
tx-meta# (first (map :tx-meta r#))
|
||||
all-tx# (concat tx# (:additional-tx opts#))
|
||||
opts## (merge (dissoc opts# :additional-tx) tx-meta#)]
|
||||
o# (persistent! frontend.modules.outliner.core/*transaction-opts*)
|
||||
full-opts# (apply merge (reverse o#))
|
||||
opts## (merge (dissoc full-opts# :additional-tx :current-block :nested-transaction?) tx-meta#)]
|
||||
(when (seq all-tx#) ;; If it's empty, do nothing
|
||||
(when-not (:nested-transaction? opts#) ; transact only for the whole transaction
|
||||
(when-not (:nested-transaction? opts##) ; transact only for the whole transaction
|
||||
(let [result# (frontend.modules.outliner.datascript/transact! all-tx# opts## before-editor-cursor#)]
|
||||
{:tx-report result#
|
||||
:tx-data all-tx#
|
||||
|
|
Loading…
Reference in New Issue