fix: drag && drop for non-consecutive selected blocks

pull/10050/head
Tienson Qin 2023-08-17 15:33:24 +08:00
parent 0f1f8873f3
commit f26d45d31c
4 changed files with 42 additions and 38 deletions

View File

@ -17,7 +17,9 @@
nested? (= move-to :nested)
alt-key? (and event (.-altKey event))
current-format (:block/format first-block)
target-format (:block/format target-block)]
target-format (:block/format target-block)
target-block (if nested? target-block
(or (first (:block/_link (db/entity (:db/id target-block)))) target-block))]
(cond
;; alt pressed, make a block-ref
(and alt-key? (= (count blocks) 1))
@ -46,9 +48,9 @@
(= (tree/-get-parent-id target-node)
(tree/-get-left-id target-node))]
(if first-child?
(let [parent (tree/-get-parent target-node)]
(when-let [parent (tree/-get-parent target-node)]
(outliner-core/move-blocks! blocks' (:data parent) false))
(let [before-node (tree/-get-left target-node)]
(when-let [before-node (tree/-get-left target-node)]
(outliner-core/move-blocks! blocks' (:data before-node) true))))
(outliner-core/move-blocks! blocks' target-block (not nested?)))))

View File

@ -215,10 +215,6 @@
(-> (get-in this [:data :block/parent])
(outliner-u/->block-id)))
(-set-parent-id [this parent-id]
(outliner-u/check-block-id parent-id)
(update this :data assoc :block/parent [:block/uuid parent-id]))
(-get-left-id [this]
(-> (get-in this [:data :block/left])
(outliner-u/->block-id)))
@ -640,7 +636,7 @@
(and up-down? linked)
[linked false]
(contains? #{:insert-blocks} outliner-op)
(contains? #{:insert-blocks :move-blocks} outliner-op)
[block sibling?]
linked
@ -724,50 +720,50 @@
:blocks tx}))))
(defn- build-move-blocks-next-tx
[blocks non-consecutive-blocks?]
(let [id->blocks (zipmap (map :db/id blocks) blocks)
top-level-blocks (get-top-level-blocks blocks)
[target-block blocks {:keys [sibling? _non-consecutive-blocks?]}]
(let [top-level-blocks (get-top-level-blocks blocks)
top-level-blocks-ids (set (map :db/id top-level-blocks))
right-block (get-right-sibling (:db/id (last top-level-blocks)))]
(when (and right-block
(not (contains? top-level-blocks-ids (:db/id right-block)))
(or (and
non-consecutive-blocks?
(not= (:db/id (last top-level-blocks))
(:db/id (:block/left right-block))))
true))
{:db/id (:db/id right-block)
:block/left (loop [block (:block/left right-block)]
(not (contains? top-level-blocks-ids (:db/id right-block))))
(when-let [left (loop [block (:block/left right-block)]
(if (contains? top-level-blocks-ids (:db/id block))
(recur (:block/left (get id->blocks (:db/id block))))
(:db/id block)))})))
(recur (:block/left (db/entity (:db/id block))))
(:db/id block)))]
(when-not (and (= left (:db/id target-block)) sibling?)
{:db/id (:db/id right-block)
:block/left left})))))
(defn- find-new-left
[block moved-ids target-block current-block sibling?]
[block moved-ids target-block current-block sibling? near-by?]
(if (= (:db/id target-block) (:db/id (:block/left current-block)))
(if sibling?
(db/entity (last moved-ids))
target-block)
(let [left (db/entity (:db/id (:block/left block)))]
(if (contains? (set moved-ids) (:db/id left))
(find-new-left left moved-ids target-block current-block sibling?)
(find-new-left left moved-ids target-block current-block sibling? near-by?)
left))))
(defn- fix-non-consecutive-blocks
[blocks target-block sibling?]
(when (> (count blocks) 1)
(let [page-blocks (group-by :block/page blocks)]
(let [page-blocks (group-by :block/page blocks)
near-by? (= (:db/id target-block) (:db/id (:block/left (first blocks))))]
(->>
(mapcat (fn [[_page blocks]]
(let [blocks (db-model/sort-page-random-blocks blocks)
non-consecutive-blocks (->> (conj (db-model/get-non-consecutive-blocks blocks) (last blocks))
(util/distinct-by :db/id))]
(when (seq non-consecutive-blocks)
(mapv (fn [block]
(map-indexed (fn [idx block]
(when-let [right (get-right-sibling (:db/id block))]
(when-let [new-left (find-new-left right (distinct (map :db/id blocks)) target-block block sibling?)]
(if (and (zero? idx) near-by? sibling?)
{:db/id (:db/id right)
:block/left (:db/id new-left)})))
:block/left (:db/id (last blocks))}
(when-let [new-left (find-new-left right (distinct (map :db/id blocks)) target-block block sibling? near-by?)]
{:db/id (:db/id right)
:block/left (:db/id new-left)}))))
non-consecutive-blocks)))) page-blocks)
(remove nil?)))))
@ -845,6 +841,10 @@
(:db/id target-block))
sibling?)))
(defn get-original-block
[linked-block]
(first (:block/_link (db/entity (:db/id linked-block)))))
(defn move-blocks
"Move `blocks` to `target-block` as siblings or children."
[blocks target-block {:keys [_sibling? _up? outliner-op _indent?]
@ -861,7 +861,11 @@
(set))
move-parents-to-child? (some parents (map :db/id blocks))]
(when-not move-parents-to-child?
(let [blocks (get-top-level-blocks blocks)
(let [blocks (->> (get-top-level-blocks blocks)
(map (fn [b]
(let [original (get-original-block b)
original' (when original (db/pull (:db/id original)))]
(or original' b)))))
first-block (first blocks)
{:keys [tx-data]} (insert-blocks blocks target-block {:sibling? sibling?
:outliner-op (or outliner-op :move-blocks)})]
@ -870,7 +874,8 @@
target-page (or (:db/id (:block/page target-block))
(:db/id target-block))
not-same-page? (not= first-block-page target-page)
move-blocks-next-tx [(build-move-blocks-next-tx blocks non-consecutive-blocks?)]
move-blocks-next-tx [(build-move-blocks-next-tx target-block blocks {:sibling? sibling?
:non-consecutive-blocks? non-consecutive-blocks?})]
children-page-tx (when not-same-page?
(let [children-ids (mapcat #(db/get-block-children-ids (state/get-current-repo) (:block/uuid %)) blocks)]
(map (fn [id] {:block/uuid id

View File

@ -171,8 +171,8 @@
(not (contains? (:file/unlinked-dirs @state/state)
(config/get-repo-dir repo)))))
(prn :debug "Outliner transact:")
(frontend.util/pprint {:txs txs :opts opts})
;; (prn :debug "Outliner transact:")
;; (frontend.util/pprint {:txs txs :opts opts})
(try
(let [repo (get opts :repo (state/get-current-repo))

View File

@ -8,15 +8,12 @@
(defprotocol INode
(-get-id [this])
(-get-parent-id [this])
(-set-parent-id [this parent-id])
(-get-left-id [this])
(-set-left-id [this left-id])
(-get-parent [this])
(-get-left [this])
(-get-right [this])
(-get-down [this])
(-save [this db])
(-del [this db children?])
(-get-children [this]))