From affa57e78d36cfbd50ebfe0adfcd3237d1daa884 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 15 May 2023 20:19:23 +0800 Subject: [PATCH] fix: replace with source block's content when deleting refed blocks --- src/main/frontend/handler/editor.cljs | 4 +- .../frontend/modules/outliner/datascript.cljc | 45 +++++++++++++++---- .../modules/outliner/transaction.cljc | 10 +++-- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index d699543a6a..4cc0aba146 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -808,7 +808,7 @@ {:keys [prev-block new-content move-fn]} (move-to-prev-block repo sibling-block format id value false) concat-prev-block? (boolean (and prev-block new-content)) transact-opts (cond-> - {:outliner-op :delete-block} + {:outliner-op :delete-blocks} concat-prev-block? (assoc :concat-data {:last-edit-block (:block/uuid block)}))] @@ -2615,7 +2615,7 @@ :else (let [edit-block (state/get-edit-block) - transact-opts {:outliner-op :delete-block + transact-opts {:outliner-op :delete-blocks :concat-data {:last-edit-block (:block/uuid edit-block) :end? true}} next-block-has-refs? (some? (:block/_refs (db/entity (:db/id next-block)))) diff --git a/src/main/frontend/modules/outliner/datascript.cljc b/src/main/frontend/modules/outliner/datascript.cljc index dbce843495..9aa42996be 100644 --- a/src/main/frontend/modules/outliner/datascript.cljc +++ b/src/main/frontend/modules/outliner/datascript.cljc @@ -12,7 +12,9 @@ [logseq.graph-parser.util :as gp-util] [lambdaisland.glogi :as log] [frontend.search :as search] - [clojure.string :as string]))) + [clojure.string :as string] + [frontend.util :as util] + [frontend.util.property :as property]))) #?(:cljs (defn new-outliner-txs-state [] (atom []))) @@ -65,21 +67,47 @@ kept-refs (:block/_refs kept-e) kept-path-refs (:block/_path-refs kept-e) deleted-refs (:block/_refs deleted-e) - kept-refs-txs (mapcat (fn [ref refs] + kept-refs-txs (mapcat (fn [ref] (let [id (:db/id ref)] [[:db/retract id :block/refs kept-id] [:db/add id :block/refs deleted-id]])) kept-refs) - kept-path-refs-txs (mapcat (fn [ref refs] + kept-path-refs-txs (mapcat (fn [ref] (let [id (:db/id ref)] [[:db/retract id :block/path-refs kept-id] [:db/add id :block/path-refs deleted-id]])) kept-path-refs) - deleted-refs-txs (mapcat (fn [ref refs] - (let [id (:db/id ref)] - (let [new-content (string/replace (:block/content ref) (str deleted) (str kept))] - [[:db/add id :block/content new-content]]))) deleted-refs)] + deleted-refs-txs (mapcat (fn [ref] + (let [id (:db/id ref) + new-content (string/replace (:block/content ref) (str deleted) (str kept))] + [[:db/add id :block/content new-content]])) deleted-refs)] (concat txs kept-refs-txs kept-path-refs-txs deleted-refs-txs)) txs))) +#?(:cljs + (defn replace-ref-with-content + [txs opts] + (if (and (= :delete-blocks (:outliner-op opts)) + (not (:uuid-changed opts))) + (let [retracted-blocks (->> (keep (fn [tx] + (when (and (vector? tx) + (= :db.fn/retractEntity (first tx))) + (second tx))) txs) + (map db/entity)) + retracted-tx (->> (for [block retracted-blocks] + (let [refs (:block/_refs block)] + (mapcat (fn [ref] + (let [id (:db/id ref) + block-content (property/remove-properties (:block/format block) (:block/content block)) + new-content (-> (:block/content ref) + (string/replace (re-pattern (util/format "{{embed \\(\\(%s\\)\\)\\s?}}" (str (:block/uuid block)))) + block-content) + (string/replace (util/format "((%s))" (str (:block/uuid block))) + block-content))] + [[:db/retract (:db/id ref) :block/refs (:db/id block)] + [:db/add id :block/content new-content]])) refs))) + (apply concat))] + (concat txs retracted-tx)) + txs))) + #?(:cljs (defn transact! [txs opts before-editor-cursor] @@ -92,6 +120,7 @@ :block/additional-properties) m)) txs) txs (-> (update-block-refs txs opts) + (replace-ref-with-content opts) (distinct))] (when (and (seq txs) (not (:skip-transact? opts)) @@ -101,7 +130,7 @@ (config/get-repo-dir repo))))) (prn "[DEBUG] Outliner transact:") - (frontend.util/pprint txs) + (frontend.util/pprint {:txs txs :opts opts}) (try (let [repo (get opts :repo (state/get-current-repo)) diff --git a/src/main/frontend/modules/outliner/transaction.cljc b/src/main/frontend/modules/outliner/transaction.cljc index b2f7e3d393..7adf7bc5c8 100644 --- a/src/main/frontend/modules/outliner/transaction.cljc +++ b/src/main/frontend/modules/outliner/transaction.cljc @@ -23,18 +23,21 @@ (move-blocks! ...) (delete-blocks! ...))" [opts & body] - (assert (or (map? opts) (symbol? opts)) (str "opts is not a map or symbol, type: " (type opts) )) + (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) + (do + (when transaction-opts# + (conj! transaction-opts# opts#)) + ~@body) (binding [frontend.modules.outliner.core/*transaction-data* (transient []) frontend.modules.outliner.core/*transaction-opts* (transient [])] + (conj! frontend.modules.outliner.core/*transaction-opts* transaction-opts# opts#) ~@body (let [r# (persistent! frontend.modules.outliner.core/*transaction-data*) tx# (mapcat :tx-data r#) @@ -44,6 +47,7 @@ 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 (let [result# (frontend.modules.outliner.datascript/transact! all-tx# opts## before-editor-cursor#)]