fix: can't backspace in some situations

pull/10639/head^2
Tienson Qin 2023-12-13 20:31:26 +08:00
parent 083618a427
commit 8c3794f5aa
6 changed files with 124 additions and 69 deletions

View File

@ -568,10 +568,10 @@ independent of format as format specific heading characters are stripped"
'[:db/id :block/collapsed? :block/properties {:block/parent ...}]
[:block/uuid block-id]))
(defn get-block-last-direct-child
(defn get-block-last-direct-child-id
"Notice: if `not-collapsed?` is true, will skip searching for any collapsed block."
([db db-id]
(get-block-last-direct-child db db-id false))
(get-block-last-direct-child-id db db-id false))
([db db-id not-collapsed?]
(when-let [block (db-utils/entity db db-id)]
(when (if not-collapsed?
@ -582,6 +582,16 @@ independent of format as format specific heading characters are stripped"
all-ids (set (map :db/id children))]
(first (set/difference all-ids all-left)))))))
(defn get-block-deep-last-open-child-id
[db db-id]
(loop [node (db-utils/entity db db-id)]
(if-let [last-child-id (get-block-last-direct-child-id db (:db/id node) true)]
(let [e (db-utils/entity db last-child-id)]
(if (or (:block/collapsed? e) (empty? (:block/_parent e)))
last-child-id
(recur e)))
nil)))
(defn get-prev-sibling
[db id]
(when-let [e (db-utils/entity db id)]
@ -597,7 +607,7 @@ independent of format as format specific heading characters are stripped"
db-id)))
(defn get-next
"Get next block, either right sibling, or loop to find its next block."
"Get next block, either its right sibling, or loop to find its next block."
[db db-id & {:keys [skip-collapsed? init?]
:or {skip-collapsed? true
init? true}
@ -608,6 +618,21 @@ independent of format as format specific heading characters are stripped"
(let [parent-id (:db/id (:block/parent (db-utils/entity db db-id)))]
(get-next db parent-id (assoc opts :init? false))))))
(defn get-prev
"Get prev block, either its left sibling if the sibling is collapsed or no children,
or get sibling's last deep displayable child (collaspsed parent or non-collapsed child)."
[db db-id]
(when-let [entity (db-utils/entity db db-id)]
(or
(when-let [prev-sibling (get-prev-sibling db db-id)]
(if (or (:block/collapsed? prev-sibling)
(empty? (:block/_parent prev-sibling)))
prev-sibling
(some->> (get-block-deep-last-open-child-id db (:db/id prev-sibling))
(db-utils/entity db))))
(let [parent (:block/parent entity)]
(when-not (:block/name parent)
parent)))))
(defn last-child-block?
"The child block could be collapsed."

View File

@ -73,7 +73,7 @@
(outliner-core/block)
(outliner-tree/-get-down)
(outliner-core/get-data))
to-last-direct-child-id (model/get-block-last-direct-child (db/get-db) to-id)
to-last-direct-child-id (model/get-block-last-direct-child-id (db/get-db) to-id)
repo (state/get-current-repo)
conn (conn/get-db repo false)
datoms (d/datoms @conn :avet :block/page from-id)

View File

@ -577,7 +577,7 @@
:block/content ""
:block/page page-id
:block/parent page-id
:block/left (or (when page-entity (model/get-block-last-direct-child (db/get-db) (:db/id page-entity)))
:block/left (or (when page-entity (model/get-block-last-direct-child-id (db/get-db) (:db/id page-entity)))
page-id)
:block/metadata metadata}
sqlite-util/block-with-timestamps)
@ -631,7 +631,7 @@
:block/page page-id
:block/metadata metadata
:block/parent page-id
:block/left (or (when page-entity (model/get-block-last-direct-child (db/get-db) (:db/id page-entity)))
:block/left (or (when page-entity (model/get-block-last-direct-child-id (db/get-db) (:db/id page-entity)))
page-id)}
sqlite-util/block-with-timestamps)]
{:page page-tx

View File

@ -762,6 +762,12 @@
(let [{:keys [id block-id block-parent-id value format config]} (get-state)]
(when block-id
(when-let [block-e (db/entity [:block/uuid block-id])]
(let [prev-block (db-model/get-prev (db/get-db) (:db/id block-e))]
(cond
(nil? prev-block)
nil
:else
(let [has-children? (seq (:block/_parent block-e))
block (db/pull (:db/id block-e))
left (tree/-get-left (outliner-core/block block))
@ -799,13 +805,36 @@
(let [new-properties (merge (:block/properties (db/entity (:db/id prev-block)))
(:block/properties (db/entity (:db/id block))))]
(if (seq (:block/_refs (db/entity (:db/id block))))
(do
(let [block-right (outliner-core/get-right-sibling (:db/id block))]
(delete-block-fn prev-block)
(save-block! repo block new-content {:editor/op :delete})
(outliner-core/save-block! {:db/id (:db/id block)
:block/parent (:db/id (:block/parent prev-block))
:block/left (or (:db/id (:block/left prev-block))
(:db/id (:block/parent prev-block)))})
;; block->right needs to point its `left` to block->left
(when (and block-right (not= (:db/id (:block/parent prev-block))
(:db/id (:block/parent block))))
(outliner-core/save-block! {:db/id (:db/id block-right)
:block/left (:db/id (:block/left block))}))
;; update prev-block's children to point to the refed block
(when (or (:block/collapsed? prev-block)
(= (:db/id prev-block) (:db/id (:block/parent block))))
(let [children (:block/_parent prev-block)]
(doseq [child children]
(when-not (= (:db/id child) (:db/id block))
(outliner-core/save-block! {:db/id (:db/id child)
:block/parent (:db/id block)
:block/left (:db/id block)})))))
;; parent will be removed
(when (= (:db/id prev-block) (:db/id (:block/parent block)))
(when-let [parent-right (outliner-core/get-right-sibling (:db/id prev-block))]
(outliner-core/save-block! {:db/id (:db/id parent-right)
:block/left (:db/id block)})))
(when db-based?
(outliner-core/save-block! {:db/id (:db/id block)
:block/properties new-properties}))
@ -823,7 +852,7 @@
:block/properties new-properties})))))
:else
(delete-block-fn block))))))))))
(delete-block-fn block))))))))))))
(state/set-editor-op! nil))
(defn delete-blocks!
@ -2668,6 +2697,7 @@
(nil? next-block)
nil
;; TODO: merge children from both the current block and the next block
(and collapsed? next-block (db/has-children? (:block/uuid next-block)))
nil

View File

@ -322,7 +322,7 @@
(outliner-core/block)
(outliner-tree/-get-down)
(outliner-core/get-data))
to-last-direct-child-id (model/get-block-last-direct-child (db/get-db) to-id)
to-last-direct-child-id (model/get-block-last-direct-child-id (db/get-db) to-id)
repo (state/get-current-repo)
conn (conn/get-db repo false)
datoms (d/datoms @conn :avet :block/page from-id)

View File

@ -133,7 +133,7 @@
(defn- get-last-child-or-self
[block]
(let [last-child (some-> (db-model/get-block-last-direct-child (conn/get-db) (:db/id block) true)
(let [last-child (some-> (db-model/get-block-last-direct-child-id (conn/get-db) (:db/id block) true)
db/entity)
target (or last-child block)]
[target (some? last-child)]))
@ -1093,7 +1093,7 @@
opts {:outliner-op :indent-outdent-blocks}]
(if indent?
(when (and left (not (page-first-child? first-block)))
(let [last-direct-child-id (db-model/get-block-last-direct-child db (:db/id left))
(let [last-direct-child-id (db-model/get-block-last-direct-child-id db (:db/id left))
blocks' (drop-while (fn [b]
(= (:db/id (:block/parent b))
(:db/id left)))
@ -1132,7 +1132,7 @@
right-siblings (->> (get-right-siblings (block last-top-block))
(map :data))]
(if (seq right-siblings)
(let [result2 (if-let [last-direct-child-id (db-model/get-block-last-direct-child db (:db/id last-top-block))]
(let [result2 (if-let [last-direct-child-id (db-model/get-block-last-direct-child-id db (:db/id last-top-block))]
(move-blocks right-siblings (db/entity last-direct-child-id) (merge opts {:sibling? true}))
(move-blocks right-siblings last-top-block (merge opts {:sibling? false})))]
(concat-tx-fn result result2))