Преглед изворни кода

undo/redo indent-outdent-nodes

rcmerci пре 4 година
родитељ
комит
44e96e95de
2 измењених фајлова са 89 додато и 62 уклоњено
  1. 55 51
      src/main/frontend/modules/outliner/core.cljs
  2. 34 11
      src/main/frontend/modules/outliner/yjs.cljs

+ 55 - 51
src/main/frontend/modules/outliner/core.cljs

@@ -606,57 +606,61 @@
           (tree/-save txs-state)))
 
 (defn indent-outdent-nodes
-  [nodes indent?]
-  {:pre [(> (count nodes) 0)]}
-  (let [page-name (get-page-name (first nodes))
-        ids (mapv #(get-in % [:data :block/uuid]) nodes)]
-    (ds/auto-transact!
-     [txs-state (ds/new-outliner-txs-state)] {:outliner-op :indent-outdent-nodes
-                                              :other-meta {:page-name page-name
-                                                           :indent? indent?
-                                                           :node-ids ids}}
-     (let [first-node (first nodes)
-           last-node (last nodes)]
-       (if indent?
-         (when-not (first-child? first-node)
-           (let [first-node-left-id (tree/-get-left-id first-node)
-                 last-node-right (tree/-get-right last-node)
-                 parent-or-last-child-id (or (-> (db/get-block-immediate-children (state/get-current-repo)
-                                                                                  first-node-left-id)
-                                                 last
-                                                 :block/uuid)
-                                             first-node-left-id)
-                 first-node (tree/-set-left-id first-node parent-or-last-child-id)]
-             (doseq [node (cons first-node (rest nodes))]
-               (-> (tree/-set-parent-id node first-node-left-id)
-                   (tree/-save txs-state)))
-             (some-> last-node-right
-                     (tree/-set-left-id first-node-left-id)
-                     (tree/-save txs-state))))
-         (when-not (first-level? first-node)
-           (let [parent (tree/-get-parent first-node)
-                 parent-parent-id (tree/-get-parent-id parent)
-                 parent-right (tree/-get-right parent)
-                 last-node-right (tree/-get-right last-node)
-                 last-node-id (tree/-get-id last-node)]
-             (logical-outdenting txs-state parent nodes first-node last-node last-node-right parent-parent-id parent-right)
-             (when-not (state/logical-outdenting?)
-               ;; direct outdenting (the old behavior)
-               (let [right-siblings (get-right-siblings last-node)
-                     right-siblings (doall
-                                     (map (fn [sibling right-siblings]
-                                            (some->
-                                             (tree/-set-parent-id sibling last-node-id)
-                                             (tree/-save txs-state)))
-                                          right-siblings))]
-                 (when-let [last-node-right (first right-siblings)]
-                   (let [last-node-children (tree/-get-children last-node)
-                         left-id (if (seq last-node-children)
-                                   (tree/-get-id (last last-node-children))
-                                   last-node-id)]
-                     (when left-id
-                       (some-> (tree/-set-left-id last-node-right left-id)
-                               (tree/-save txs-state))))))))))))))
+  ([nodes indent?]
+   (indent-outdent-nodes nodes indent? nil))
+  ([nodes indent? {:keys [skip-undo?]
+                   :or {skip-undo? false}}]
+   {:pre [(> (count nodes) 0)]}
+   (let [page-name (get-page-name (first nodes))
+         ids (mapv #(get-in % [:data :block/uuid]) nodes)]
+     (ds/auto-transact!
+      [txs-state (ds/new-outliner-txs-state)] {:outliner-op :indent-outdent-nodes
+                                               :skip-undo? skip-undo?
+                                               :other-meta {:page-name page-name
+                                                            :indent? indent?
+                                                            :node-ids ids}}
+      (let [first-node (first nodes)
+            last-node (last nodes)]
+        (if indent?
+          (when-not (first-child? first-node)
+            (let [first-node-left-id (tree/-get-left-id first-node)
+                  last-node-right (tree/-get-right last-node)
+                  parent-or-last-child-id (or (-> (db/get-block-immediate-children (state/get-current-repo)
+                                                                                   first-node-left-id)
+                                                  last
+                                                  :block/uuid)
+                                              first-node-left-id)
+                  first-node (tree/-set-left-id first-node parent-or-last-child-id)]
+              (doseq [node (cons first-node (rest nodes))]
+                (-> (tree/-set-parent-id node first-node-left-id)
+                    (tree/-save txs-state)))
+              (some-> last-node-right
+                      (tree/-set-left-id first-node-left-id)
+                      (tree/-save txs-state))))
+          (when-not (first-level? first-node)
+            (let [parent (tree/-get-parent first-node)
+                  parent-parent-id (tree/-get-parent-id parent)
+                  parent-right (tree/-get-right parent)
+                  last-node-right (tree/-get-right last-node)
+                  last-node-id (tree/-get-id last-node)]
+              (logical-outdenting txs-state parent nodes first-node last-node last-node-right parent-parent-id parent-right)
+              (when-not (state/logical-outdenting?)
+                ;; direct outdenting (the old behavior)
+                (let [right-siblings (get-right-siblings last-node)
+                      right-siblings (doall
+                                      (map (fn [sibling right-siblings]
+                                             (some->
+                                              (tree/-set-parent-id sibling last-node-id)
+                                              (tree/-save txs-state)))
+                                           right-siblings))]
+                  (when-let [last-node-right (first right-siblings)]
+                    (let [last-node-children (tree/-get-children last-node)
+                          left-id (if (seq last-node-children)
+                                    (tree/-get-id (last last-node-children))
+                                    last-node-id)]
+                      (when left-id
+                        (some-> (tree/-set-left-id last-node-right left-id)
+                                (tree/-save txs-state)))))))))))))))
 
 (defn- set-nodes-page&file-aux
   [node page file txs-state]

+ 34 - 11
src/main/frontend/modules/outliner/yjs.cljs

@@ -902,17 +902,20 @@ return [2 3]
        (outdent-item struct id)))
    ids))
 
-(defn indent-outdent-nodes-op [nodes indent?]
-  (when-some [page-name
-              (:block/name (db/entity (:db/id (:block/page (:data (first nodes))))))]
-    (let [ids (mapv (fn [node] (str (:block/uuid (:data node)))) nodes)
-          struct (structarray page-name)]
-      (indent-outdent-nodes-yjs struct ids indent?)
-      (merge-doc @doc-remote @doc-local)
-      (when *debug*
-        (validate-struct struct)
-        (validate-no-left-conflict page-name))
-      (outliner-core/indent-outdent-nodes nodes indent?))))
+(defn indent-outdent-nodes-op
+  ([nodes indent?]
+   (indent-outdent-nodes-op nodes indent? {:skip-undo? false}))
+  ([nodes indent? {:keys [skip-undo?]}]
+   (when-some [page-name
+               (:block/name (db/entity (:db/id (:block/page (:data (first nodes))))))]
+     (let [ids (mapv (fn [node] (str (:block/uuid (:data node)))) nodes)
+           struct (structarray page-name)]
+       (indent-outdent-nodes-yjs struct ids indent?)
+       (merge-doc @doc-remote @doc-local)
+       (when *debug*
+         (validate-struct struct)
+         (validate-no-left-conflict page-name))
+       (outliner-core/indent-outdent-nodes nodes indent? {:skip-undo? skip-undo?})))))
 
 (defn move-subtree-same-page-yjs [struct root-id target-id sibling?]
   (when (find-pos struct target-id)
@@ -1174,6 +1177,22 @@ return [2 3]
         end-node (outliner-core/block (db/pull [:block/uuid end-id]))]
     (delete-nodes-op start-node end-node block-ids {:skip-undo? true})))
 
+(defn- undo-indent-outdent-nodes [page-name txn-meta]
+  {:pre [(= :indent-outdent-nodes (:outliner-op txn-meta))
+         (= page-name (get-in txn-meta [:other-meta :page-name]))]}
+  (let [indent? (get-in txn-meta [:other-meta :indent?])
+        node-ids (get-in txn-meta [:other-meta :node-ids])
+        nodes (mapv (fn [id] (outliner-core/block (db/pull [:block/uuid id]))) node-ids)]
+    (indent-outdent-nodes-op nodes (not indent?) {:skip-undo? true})))
+
+(defn- redo-indent-outdent-nodes [page-name txn-meta]
+  {:pre [(= :indent-outdent-nodes (:outliner-op txn-meta))
+         (= page-name (get-in txn-meta [:other-meta :page-name]))]}
+  (let [indent? (get-in txn-meta [:other-meta :indent?])
+        node-ids (get-in txn-meta [:other-meta :node-ids])
+        nodes (mapv (fn [id] (outliner-core/block (db/pull [:block/uuid id]))) node-ids)]
+    (indent-outdent-nodes-op nodes indent? {:skip-undo? true})))
+
 
 (defn undo-op [page-name txn-meta]
   (def bbb [page-name txn-meta])
@@ -1189,6 +1208,8 @@ return [2 3]
     (undo-insert-nodes page-name txn-meta)
     :delete-nodes
     (undo-delete-nodes page-name txn-meta)
+    :indent-outdent-nodes
+    (undo-indent-outdent-nodes page-name txn-meta)
     (println "unsupport" (:outliner-op txn-meta))))
 
 (defn redo-op [page-name txn-meta]
@@ -1204,6 +1225,8 @@ return [2 3]
     (redo-insert-nodes page-name txn-meta)
     :delete-nodes
     (redo-delete-nodes page-name txn-meta)
+    :indent-outdent-nodes
+    (redo-indent-outdent-nodes page-name txn-meta)
     (println "unsupport" (:outliner-op txn-meta))))
 
 (defn undo []