Browse Source

fix: undo should bring refs back

Tienson Qin 2 years ago
parent
commit
753d452b50

+ 16 - 4
src/main/frontend/handler/editor.cljs

@@ -1968,6 +1968,15 @@
   (let [ids (set (map :db/id blocks))]
     (some? (some #(ids (:db/id (:block/parent %))) blocks))))
 
+(defn- get-revert-cut-tx
+  [blocks]
+  (let [{:keys [retracted-block-ids revert-tx]} (get-in @state/state [:editor/last-replace-ref-content-tx (state/get-current-repo)])
+        recent-cut-block-ids (->> retracted-block-ids (map second) (set))]
+    ;; (state/set-state! [:editor/last-replace-ref-content-tx (state/get-current-repo)] nil)
+    (when (and (= (set (map :block/uuid blocks)) recent-cut-block-ids)
+               (seq revert-tx))
+      revert-tx)))
+
 (defn paste-blocks
   "Given a vec of blocks, insert them into the target page.
    keep-uuid?: if true, keep the uuid provided in the block structure."
@@ -1990,8 +1999,9 @@
         empty-target? (string/blank? (:block/content target-block))
         paste-nested-blocks? (nested-blocks blocks)
         target-block-has-children? (db/has-children? (:block/uuid target-block))
-        replace-empty-target? (if (and paste-nested-blocks? empty-target?
-                                       target-block-has-children?)
+        revert-cut-txs (get-revert-cut-tx blocks)
+        keep-uuid? (if (seq revert-cut-txs) true keep-uuid?)
+        replace-empty-target? (if (and paste-nested-blocks? empty-target? target-block-has-children?)
                                 false
                                 true)
         target-block' (if replace-empty-target? target-block
@@ -2009,7 +2019,8 @@
                    false
 
                    :else
-                   true)]
+                   true)
+]
 
     (when has-unsaved-edits
       (outliner-tx/transact!
@@ -2017,7 +2028,8 @@
         (outliner-core/save-block! editing-block)))
 
     (outliner-tx/transact!
-      {:outliner-op :insert-blocks}
+      {:outliner-op :insert-blocks
+       :additional-tx revert-cut-txs}
       (when target-block'
         (let [format (or (:block/format target-block') (state/get-preferred-format))
               blocks' (map (fn [block]

+ 4 - 4
src/main/frontend/modules/editor/undo_redo.cljs

@@ -159,10 +159,10 @@
   "Prevent block auto-save during undo/redo."
   []
   (when-let [block (state/get-edit-block)]
-    (let [content (:block/content (db/entity (:db/id block)))
-          content' (-> (property/remove-built-in-properties (:block/format block) content)
-                       (drawer/remove-logbook))]
-      (state/set-edit-content! (state/get-edit-input-id) content'))))
+    (when-let [content (:block/content (db/entity (:db/id block)))]
+      (let [content' (-> (property/remove-built-in-properties (:block/format block) content)
+                         (drawer/remove-logbook))]
+        (state/set-edit-content! (state/get-edit-input-id) content')))))
 
 (defn- get-next-tx-editor-cursor
   [tx-id]

+ 25 - 17
src/main/frontend/modules/outliner/datascript.cljc

@@ -86,25 +86,33 @@
      [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))
+       (let [retracted-block-ids (->> (keep (fn [tx]
+                                              (when (and (vector? tx)
+                                                         (= :db.fn/retractEntity (first tx)))
+                                                (second tx))) txs))
+             retracted-blocks (map db/entity retracted-block-ids)
              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))
+                                   (map (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))]
+                                            {:tx [[:db/retract (:db/id ref) :block/refs (:db/id block)]
+                                                  [:db/add id :block/content new-content]]
+                                             :revert-tx [[:db/add (:db/id ref) :block/refs (:db/id block)]
+                                                         [:db/add id :block/content (:block/content ref)]]})) refs)))
+                               (apply concat))
+             retracted-tx' (mapcat :tx retracted-tx)
+             revert-tx (mapcat :revert-tx retracted-tx)]
+         (when (seq retracted-tx')
+           (state/set-state! [:editor/last-replace-ref-content-tx (state/get-current-repo)]
+                             {:retracted-block-ids retracted-block-ids
+                              :revert-tx revert-tx}))
+         (concat txs retracted-tx'))
        txs)))
 
 #?(:cljs

+ 3 - 0
src/main/frontend/state.cljs

@@ -122,6 +122,9 @@
      :editor/on-paste?                      false
      :editor/last-key-code                  nil
 
+     ;; delete refed blocks
+     :editor/last-replace-ref-content-tx    nil
+
      ;; for audio record
      :editor/record-status                  "NONE"