refactor: indent-outdent-nodes wip

This commit is contained in:
Tienson Qin
2021-04-07 00:54:20 +08:00
parent 70a7205832
commit 99721bdb67
3 changed files with 83 additions and 28 deletions

View File

@@ -613,7 +613,11 @@
(defn sort-by-left
[blocks parent]
(assert (= (count blocks) (count (set (map :block/left blocks)))) "Each block should have a different left node")
;; (prn {:blocks blocks
;; :blocks-count (count blocks)
;; :block-left-count (frequencies (map :block/left blocks))
;; :parent parent})
;; (assert (= (count blocks) (count (set (map :block/left blocks)))) "Each block should have a different left node")
(let [left->blocks (reduce (fn [acc b] (assoc acc (:db/id (:block/left b)) b)) {} blocks)]
(loop [block parent
result []]

View File

@@ -227,6 +227,7 @@
(not= current-id (cljs.core/uuid block-id))
(db/entity [:block/uuid (cljs.core/uuid block-id)])))
;; TODO:
(defn- create-file-if-not-exists!
[repo format page value]
(let [format (name format)
@@ -744,20 +745,23 @@
(recur parent blocks)
end-block))
(defn- get-top-level-end-node
[blocks]
(let [end-block (last blocks)
end-block-parent (get-end-block-parent end-block blocks)]
(outliner-core/block end-block-parent)))
(defn delete-blocks!
[repo block-uuids]
(when (seq block-uuids)
(let [lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
blocks (db/pull-many repo '[*] lookup-refs)]
(let [start-node (outliner-core/block (first blocks))
end-block (last blocks)
end-block-parent (get-end-block-parent end-block blocks)
end-node (outliner-core/block end-block-parent)]
end-node (get-top-level-end-node blocks)]
(outliner-core/delete-nodes start-node end-node lookup-refs)
(let [opts {:key :block/change
:data blocks}]
(db/refresh repo opts))
(repo-handler/push-if-auto-enabled! repo)))))
(db/refresh repo opts))))))
(defn remove-block-property!
[block-id key]
@@ -1544,25 +1548,26 @@
(expand/cycle!)))
(defn on-tab
"direction = :left|:right, only indent when blocks are siblings"
"direction = :left|:right, only indent or outdent when blocks are siblings"
[direction]
(fn [e]
(when-let [repo (state/get-current-repo)]
(let [blocks (seq (state/get-selection-blocks))]
(cond
(seq blocks)
(let [ids (map (fn [block] (when-let [id (dom/attr block "blockid")]
(medley/uuid id))) blocks)]
;; (repo-handler/transact-react-and-alter-file!
;; repo
;; (concat
;; blocks
;; after-blocks)
;; {:key :block/change
;; :data (map (fn [block] (assoc block :block/page page)) blocks)}
;; [[file-path new-content]])
)
(let [lookup-refs (->> (map (fn [block] (when-let [id (dom/attr block "blockid")]
[:block/uuid (medley/uuid id)])) blocks)
(remove nil?))
blocks (db/pull-many repo '[*] lookup-refs)
end-node (get-top-level-end-node blocks)
end-node-parent (tree/-get-parent end-node)
top-level-nodes (->> (filter #(= (get-in end-node-parent [:data :db/id])
(get-in % [:block/parent :db/id])) blocks)
(map outliner-core/block))]
(outliner-core/indent-outdent-nodes top-level-nodes (= direction :right))
(let [opts {:key :block/change
:data blocks}]
(db/refresh repo opts)))
(gdom/getElement "date-time-picker")
nil
@@ -1932,6 +1937,7 @@
:else
nil))))
;; TODO: merge indent-on-tab, outdent-on-shift-tab, on-tab
(defn indent-on-tab
([state]
(indent-on-tab state 100))
@@ -1944,9 +1950,7 @@
(state/set-editor-op! :indent-outdent)
(let [{:keys [block block-parent-id value config]} (get-state state)
current-node (outliner-core/block block)
first-child? (=
(tree/-get-left-id current-node)
(tree/-get-parent-id current-node)) ]
first-child? (outliner-core/first-child? current-node)]
(when-not first-child?
(let [left (tree/-get-left current-node)
children-of-left (tree/-get-children left)]

View File

@@ -1,5 +1,6 @@
(ns frontend.modules.outliner.core
(:require [frontend.modules.outliner.tree :as tree]
[frontend.db :as db]
[frontend.db.outliner :as db-outliner]
[frontend.db.conn :as conn]
[frontend.modules.outliner.utils :as outliner-u]
@@ -270,23 +271,69 @@
(db-outliner/del-blocks conn block-ids)
(outliner-file/sync-to-file start-node))))
(defn first-child?
[node]
(=
(tree/-get-left-id node)
(tree/-get-parent-id node)))
(defn first-level?
"Can't be outdented."
[node]
(nil? (tree/-get-parent (tree/-get-parent node))))
(defn indent-outdent-nodes
[nodes indent?]
(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)]
;; (prn {:parent-or-last-child-id parent-or-last-child-id
;; :parent-content (:block/content (db/pull [:block/uuid parent-or-last-child-id]))
;; :last-node-right last-node-right
;; :content (:block/content (db/pull (get-in last-node-right [:data :db/id])))})
(-> (tree/-set-left-id first-node parent-or-last-child-id)
(tree/-save))
(doseq [node nodes]
(-> (tree/-set-parent-id node first-node-left-id)
(tree/-save)))
(some-> last-node-right
(tree/-set-left-id first-node-left-id)
(tree/-save))
(outliner-file/sync-to-file first-node)))
(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)]
(doseq [node nodes]
(-> (tree/-set-parent-id node parent-parent-id)
(tree/-save)))
(some-> parent-right
(tree/-set-left-id (tree/-get-id last-node))
(tree/-save)))))))
(defn move-subtree*
"Move subtree to a destination position in the relation tree.
Args:
root: root of subtree
target-node: the destination
sibling: as sibling of the target-node or child"
[root target-node sibling]
sibling?: as sibling of the target-node or child"
[root target-node sibling?]
{:pre [(every? tree/satisfied-inode? [root target-node])
(boolean? sibling)]}
(boolean? sibling?)]}
(let [left-node-id (tree/-get-left-id root)
right-node (tree/-get-right root)]
(when (tree/satisfied-inode? right-node)
(let [new-right-node (tree/-set-left-id right-node left-node-id)]
(tree/-save new-right-node)))
(if sibling
(insert-node-as-sibling root target-node)
(insert-node-as-first-child root target-node))))
(insert-node root target-node sibling?)))
(defn move-subtree
"Move subtree to a destination position in the relation tree.