diff --git a/src/main/frontend/handler/block.cljs b/src/main/frontend/handler/block.cljs index ee9823dc2..d3dcd85e5 100644 --- a/src/main/frontend/handler/block.cljs +++ b/src/main/frontend/handler/block.cljs @@ -7,7 +7,7 @@ [frontend.db.model :as db-model] [frontend.mobile.haptics :as haptics] [frontend.modules.outliner.core :as outliner-core] - [frontend.modules.outliner.transaction :as outliner-tx] + [frontend.modules.outliner.ui :as ui-outliner-tx] [frontend.state :as state] [frontend.util :as util] [goog.dom :as gdom] @@ -59,7 +59,7 @@ (defn indent-outdent-block! [block direction] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :move-blocks} (outliner-core/indent-outdent-blocks! [block] (= direction :right)))) diff --git a/src/main/frontend/handler/db_based/editor.cljs b/src/main/frontend/handler/db_based/editor.cljs index dcbb5ec4d..82cc8d922 100644 --- a/src/main/frontend/handler/db_based/editor.cljs +++ b/src/main/frontend/handler/db_based/editor.cljs @@ -15,7 +15,7 @@ [frontend.handler.property.util :as pu] [frontend.handler.repo-config :as repo-config-handler] [frontend.modules.outliner.core :as outliner-core] - [frontend.modules.outliner.transaction :as outliner-tx] + [frontend.modules.outliner.ui :as ui-outliner-tx] [frontend.schema.handler.repo-config :as repo-config-schema] [promesa.core :as p] [logseq.db.frontend.content :as db-content])) @@ -150,7 +150,7 @@ (defn batch-set-heading! [repo block-ids heading] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :save-block} (doseq [block-tx (keep #(set-heading-aux! % heading) block-ids)] (outliner-core/save-block! block-tx)) diff --git a/src/main/frontend/handler/dnd.cljs b/src/main/frontend/handler/dnd.cljs index 885180756..74508ce09 100644 --- a/src/main/frontend/handler/dnd.cljs +++ b/src/main/frontend/handler/dnd.cljs @@ -4,7 +4,7 @@ [frontend.handler.property :as property-handler] [frontend.modules.outliner.core :as outliner-core] [logseq.outliner.tree :as otree] - [frontend.modules.outliner.transaction :as outliner-tx] + [frontend.modules.outliner.ui :as ui-outliner-tx] [logseq.graph-parser.util.block-ref :as block-ref] [frontend.state :as state] [frontend.db :as db])) @@ -40,7 +40,7 @@ (every? map? (conj blocks' target-block)) (let [target-node (outliner-core/block target-block)] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :move-blocks} (editor-handler/save-current-block!) (if top? diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 8ba1635f9..d813a02bd 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -32,7 +32,7 @@ [frontend.handler.file-based.editor :as file-editor-handler] [frontend.mobile.util :as mobile-util] [frontend.modules.outliner.core :as outliner-core] - [frontend.modules.outliner.transaction :as outliner-tx] + [frontend.modules.outliner.ui :as ui-outliner-tx] [frontend.modules.outliner.tree :as tree] [logseq.outliner.tree :as otree] [frontend.search :as search] @@ -266,7 +266,7 @@ (let [original-block (db/entity (:db/id block)) original-props (:block/properties original-block) {:keys [tx-data]} - (outliner-tx/transact! + (ui-outliner-tx/transact! opts' (outliner-core/save-block! block') ;; page properties changed @@ -362,7 +362,7 @@ :else (not has-children?))] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :insert-blocks} (save-current-block! {:current-block current-block :insert-block? true}) @@ -665,7 +665,7 @@ (let [ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")] (uuid id)) blocks)) (remove nil?))] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :cycle-todos} (doseq [id ids] (let [block (db/pull [:block/uuid id])] @@ -702,7 +702,7 @@ (let [repo (or repo (state/get-current-repo)) block (db/pull repo '[*] [:block/uuid uuid])] (when block - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :delete-blocks} (outliner-core/delete-blocks! [block] (merge delete-opts @@ -794,7 +794,7 @@ (assoc :concat-data {:last-edit-block (:block/uuid block)})) db-based? (config/db-based-graph? repo)] - (outliner-tx/transact! + (ui-outliner-tx/transact! transact-opts (cond (and prev-block (:block/name prev-block) @@ -863,7 +863,7 @@ block (first blocks) block-parent (get uuid->dom-block (:block/uuid block)) sibling-block (when block-parent (util/get-prev-block-non-collapsed-non-embed block-parent))] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :delete-blocks} (outliner-core/delete-blocks! blocks {})) (when sibling-block @@ -1269,7 +1269,7 @@ (map #(block/page-name->map % true) tags) (map :db/id existing-tags)) opts {:outliner-op :save-block}] - (outliner-tx/transact! + (ui-outliner-tx/transact! opts (outliner-core/save-block! {:db/id (:db/id block) :block/tags tag-pages}))))) @@ -1294,7 +1294,7 @@ (defn save-blocks! [blocks] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :save-block} (doseq [[block value] blocks] (save-block-if-changed! block value)))) @@ -1749,7 +1749,7 @@ (save-current-block!) (let [edit-block-id (:block/uuid (state/get-edit-block)) move-nodes (fn [blocks] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :move-blocks} (outliner-core/move-blocks-up-down! blocks up?)) (when-let [block-node (util/get-first-block-by-id (:block/uuid (first blocks)))] @@ -1786,7 +1786,7 @@ [direction] (let [blocks (get-selected-ordered-blocks)] (when (seq blocks) - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :move-blocks :real-outliner-op :indent-outdent} (outliner-core/indent-outdent-blocks! blocks (= direction :right)))))) @@ -2076,11 +2076,11 @@ true)] (when has-unsaved-edits - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :save-block} (outliner-core/save-block! editing-block))) - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :insert-blocks :additional-tx revert-cut-txs} (when target-block' @@ -2194,7 +2194,7 @@ :else true)] (try - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :insert-blocks :created-from-journal-template? journal?} (save-current-block!) @@ -2262,7 +2262,7 @@ block (:data node)] (save-current-block!) (when target - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :move-blocks :real-outliner-op :indent-outdent} (outliner-core/move-blocks! [block] target true)) @@ -2538,7 +2538,7 @@ false)) (profile "Insert block" - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :insert-blocks} (insert-new-block! state)))))))))) @@ -2715,7 +2715,7 @@ repo (state/get-current-repo) delete-block (if next-block-has-refs? edit-block next-block) keep-block (if next-block-has-refs? next-block edit-block)] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :delete-blocks :concat-data {:last-edit-block (:block/uuid edit-block) :end? true}} @@ -2860,7 +2860,7 @@ {:keys [block]} (get-state)] (when block (state/set-editor-last-pos! pos) - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :move-blocks :real-outliner-op :indent-outdent} (outliner-core/indent-outdent-blocks! [block] indent?))) @@ -3527,7 +3527,7 @@ value (boolean value)] (when repo (save-current-block!) ;; Save the input contents before collapsing - (outliner-tx/transact! ;; Save the new collapsed state as an undo transaction (if it changed) + (ui-outliner-tx/transact! ;; Save the new collapsed state as an undo transaction (if it changed) {:outliner-op :collapse-expand-blocks} (doseq [block-id block-ids] (when-let [block (db/entity [:block/uuid block-id])] diff --git a/src/main/frontend/handler/file_based/page_property.cljs b/src/main/frontend/handler/file_based/page_property.cljs index da4523699..669d24c53 100644 --- a/src/main/frontend/handler/file_based/page_property.cljs +++ b/src/main/frontend/handler/file_based/page_property.cljs @@ -3,7 +3,7 @@ (:require [clojure.string :as string] [frontend.db :as db] [frontend.modules.outliner.core :as outliner-core] - [frontend.modules.outliner.transaction :as outliner-tx] + [frontend.modules.outliner.ui :as ui-outliner-tx] [frontend.state :as state] [frontend.util :as util])) @@ -83,7 +83,7 @@ :block/properties {key value} :block/pre-block? true} page-properties-tx [(assoc page-id :block/properties {key value})]] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :insert-blocks :additional-tx page-properties-tx} (outliner-core/insert-blocks! block page {:sibling? false})))))))) diff --git a/src/main/frontend/handler/file_based/property.cljs b/src/main/frontend/handler/file_based/property.cljs index bde2e766c..d7b75f4bd 100644 --- a/src/main/frontend/handler/file_based/property.cljs +++ b/src/main/frontend/handler/file_based/property.cljs @@ -4,7 +4,7 @@ [frontend.handler.block :as block-handler] [frontend.handler.file-based.property.util :as property-util] [frontend.modules.outliner.core :as outliner-core] - [frontend.modules.outliner.transaction :as outliner-tx] + [frontend.modules.outliner.ui :as ui-outliner-tx] [frontend.state :as state] [logseq.graph-parser.util :as gp-util])) @@ -23,7 +23,7 @@ "col: a collection of [block-id property-key property-value]." [col] (let [col' (group-by first col)] - (outliner-tx/transact! + (ui-outliner-tx/transact! {:outliner-op :save-block} (doseq [[block-id items] col'] (let [block-id (if (string? block-id) (uuid block-id) block-id) diff --git a/src/main/frontend/modules/outliner/datascript.cljs b/src/main/frontend/modules/outliner/datascript.cljs index 79de295b6..ab6a2916b 100644 --- a/src/main/frontend/modules/outliner/datascript.cljs +++ b/src/main/frontend/modules/outliner/datascript.cljs @@ -1,15 +1,11 @@ (ns frontend.modules.outliner.datascript (:require [logseq.graph-parser.util :as gp-util] [logseq.graph-parser.util.block-ref :as block-ref] - [lambdaisland.glogi :as log] - [clojure.string :as string] [frontend.worker.util :as worker-util] [logseq.db.sqlite.util :as sqlite-util] [frontend.worker.file.property-util :as wpu] [datascript.core :as d] - [frontend.state :as state] - [frontend.config :as config] - [frontend.db :as db])) + [clojure.string :as string])) (defn new-outliner-txs-state [] (atom [])) @@ -36,7 +32,7 @@ (defn update-refs-and-macros "When a block is deleted, refs are updated and macros associated with the block are deleted" - [txs db repo opts] + [txs db repo opts set-state-fn] (if (= :delete-blocks (:outliner-op opts)) (let [retracted-block-ids (->> (keep (fn [tx] (when (and (vector? tx) @@ -75,18 +71,16 @@ (vector :db.fn/retractEntity (:db/id %))) (:block/macros b))) retracted-blocks)] - (when (seq retracted-tx') - (state/set-state! [:editor/last-replace-ref-content-tx repo] - {:retracted-block-ids retracted-block-ids + (when (and (seq retracted-tx') (fn? set-state-fn)) + (set-state-fn [:editor/last-replace-ref-content-tx repo] + {:retracted-block-ids retracted-block-ids :revert-tx revert-tx})) (concat txs retracted-tx' macros-tx)) txs)) (defn transact! - [txs opts before-editor-cursor] - (let [repo (state/get-current-repo) - conn (db/get-db repo false) - db-based? (sqlite-util/db-based-graph? repo) + [txs tx-meta {:keys [repo conn unlinked-graph? after-transact-fn set-state-fn] :as opts}] + (let [db-based? (sqlite-util/db-based-graph? repo) txs (map (fn [m] (if (map? m) (dissoc m :block/children :block/meta :block/top? :block/bottom? :block/anchor @@ -95,27 +89,17 @@ m)) txs) txs (remove-nil-from-transaction txs) txs (cond-> txs - (= :delete-blocks (:outliner-op opts)) - (update-refs-and-macros @conn repo opts) + (= :delete-blocks (:outliner-op tx-meta)) + (update-refs-and-macros @conn repo tx-meta set-state-fn) true (distinct))] (when (and (seq txs) - (or db-based? - (not (contains? (:file/unlinked-dirs @state/state) - (config/get-repo-dir repo))))) + (or db-based? (not unlinked-graph?))) (try - (let [rs (d/transact! conn txs (assoc opts :outliner/transact? true)) - tx-id (get-tx-id rs)] - - (state/update-state! :history/tx->editor-cursor - (fn [m] (assoc m tx-id before-editor-cursor))) - - ;; update the current edit block to include full information - (when-let [block (state/get-edit-block)] - (when (and (:block/uuid block) (not (:db/id block))) - (state/set-state! :editor/block (d/pull @conn '[*] [:block/uuid (:block/uuid block)])))) - rs) + (let [tx-report (d/transact! conn txs (assoc tx-meta :outliner/transact? true))] + (when (fn? after-transact-fn) (after-transact-fn tx-report opts)) + tx-report) (catch :default e - (log/error :exception e) + (js/console.error e) (throw e)))))) diff --git a/src/main/frontend/modules/outliner/transaction.cljc b/src/main/frontend/modules/outliner/transaction.cljc index 5fdd965d2..80ea96423 100644 --- a/src/main/frontend/modules/outliner/transaction.cljc +++ b/src/main/frontend/modules/outliner/transaction.cljc @@ -31,14 +31,13 @@ _# (assert (or (map? opts*#) (symbol? opts*#)) (str "opts is not a map or symbol, type: " (type opts*#))) opts# (if transact-data# (assoc opts*# :nested-transaction? true) - opts*#) - before-editor-cursor# (frontend.state/get-current-edit-block-and-position)] + opts*#)] (if transact-data# (do (when transaction-opts# (conj! transaction-opts# opts#)) ~@body) - (let [repo# (frontend.state/get-current-repo) + (let [repo# (get-in opts# [:transact-opts :repo]) transaction-args# (cond-> {:repo repo#} (and (frontend.config/db-based-graph? repo#) (get opts*# :persist-op? true)) @@ -59,7 +58,7 @@ (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#)] + (let [result# (frontend.modules.outliner.datascript/transact! all-tx# (dissoc opts## :transact-opts) (:transact-opts opts##))] {:tx-report result# :tx-data all-tx# :tx-meta tx-meta#}))))))))) diff --git a/src/main/frontend/modules/outliner/ui.cljc b/src/main/frontend/modules/outliner/ui.cljc new file mode 100644 index 000000000..1ee5d3502 --- /dev/null +++ b/src/main/frontend/modules/outliner/ui.cljc @@ -0,0 +1,42 @@ +(ns frontend.modules.outliner.ui + #?(:cljs (:require-macros [frontend.modules.outliner.transaction])) + #?(:cljs (:require-macros [frontend.modules.outliner.ui])) + #?(:cljs (:require [frontend.state :as state] + [frontend.config :as config] + [frontend.db :as db]))) + +#?(:cljs + (do + (defn unlinked-graph? + [] + (let [repo (state/get-current-repo)] + (contains? (:file/unlinked-dirs @state/state) + (config/get-repo-dir repo)))) + + (def set-state-fn state/set-state!) + + (defn get-tx-id + [tx-report] + (get-in tx-report [:tempids :db/current-tx])) + + (defn after-transact-fn + [tx-report opts] + (let [tx-id (get-tx-id tx-report)] + (state/update-state! :history/tx->editor-cursor + (fn [m] (assoc m tx-id (:before-editor-cursor opts))))) + + ;; update the current edit block to include full information + (when-let [block (state/get-edit-block)] + (when (and (:block/uuid block) (not (:db/id block))) + (state/set-state! :editor/block (db/pull [:block/uuid (:block/uuid block)]))))))) + +(defmacro transact! + [opts & body] + `(let [transact-opts# {:repo (state/get-current-repo) + :conn (db/get-db false) + :before-editor-cursor (state/get-current-edit-block-and-position) + :unlinked-graph? frontend.modules.outliner.ui/unlinked-graph? + :set-state-fn frontend.modules.outliner.ui/set-state-fn + :after-transact-fn frontend.modules.outliner.ui/after-transact-fn}] + (frontend.modules.outliner.transaction/transact! (assoc ~opts :transact-opts transact-opts#) + ~@body)))