From aae14bb007ba679d4ffb4110d6c90d7a672bbb79 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Fri, 22 May 2026 23:14:26 +0800 Subject: [PATCH] fix: allow moving comments block as sibling --- deps/outliner/src/logseq/outliner/core.cljs | 18 ++++++++--- .../test/logseq/outliner/core_test.cljs | 32 ++++++++++++++----- src/main/frontend/components/block.cljs | 7 ++-- .../components/block/comments_model.cljs | 19 ++++++++--- .../components/block/comments_model_test.cljs | 24 ++++++++++++++ .../frontend/modules/outliner/core_test.cljs | 18 +++++++++-- 6 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 src/test/frontend/components/block/comments_model_test.cljs diff --git a/deps/outliner/src/logseq/outliner/core.cljs b/deps/outliner/src/logseq/outliner/core.cljs index 742267629b..63bf3dd732 100644 --- a/deps/outliner/src/logseq/outliner/core.cljs +++ b/deps/outliner/src/logseq/outliner/core.cljs @@ -863,10 +863,17 @@ (or (comments-area? block) (comment-block? block))) +(defn- move-source-allowed-for-comments? + [block sibling?] + (and (not (comment-block? block)) + (or sibling? + (not (comments-area? block))))) + (defn- move-target-allowed-for-comments? - [target-block] - (and (not (comments-area? target-block)) - (not (comment-block? target-block)))) + [target-block sibling?] + (and (not (comment-block? target-block)) + (or sibling? + (not (comments-area? target-block))))) (defn- block-subtree-ids [db block] @@ -1044,7 +1051,7 @@ current-blocks (map (fn [block] (d/entity db (:db/id block))) blocks) - top-level-blocks (remove protected-comment-block? + top-level-blocks (remove comment-block? (filter-top-level-blocks db current-blocks))] (when (seq top-level-blocks) (let [[target-block sibling?] (get-target-block db top-level-blocks target-block opts) @@ -1058,7 +1065,8 @@ block (d/entity db (:db/id block)))))) original-position? (move-to-original-position? blocks target-block sibling? non-consecutive?)] - (when (and (move-target-allowed-for-comments? target-block) + (when (and (every? #(move-source-allowed-for-comments? % sibling?) blocks) + (move-target-allowed-for-comments? target-block sibling?) (not (contains? (set (map :db/id blocks)) (:db/id target-block))) (not original-position?)) (let [parents' (->> (ldb/get-block-parents db (:block/uuid target-block) {}) diff --git a/deps/outliner/test/logseq/outliner/core_test.cljs b/deps/outliner/test/logseq/outliner/core_test.cljs index 474db2cfd1..7a704de03d 100644 --- a/deps/outliner/test/logseq/outliner/core_test.cljs +++ b/deps/outliner/test/logseq/outliner/core_test.cljs @@ -184,8 +184,7 @@ tagged-comment (db-test/find-block-by-content @conn "tagged comment") ordinary (db-test/find-block-by-content @conn "ordinary") comments-area (db-test/find-block-by-content @conn "Comments") - original-comment-parent-id (:db/id (:block/parent tagged-comment)) - original-ordinary-parent-id (:db/id (:block/parent ordinary))] + original-comment-parent-id (:db/id (:block/parent tagged-comment))] (d/transact! conn [{:db/id -1 :db/ident :logseq.class/Tag :block/uuid (random-uuid) @@ -207,15 +206,32 @@ (is (= original-comment-parent-id (:db/id (:block/parent (d/entity @conn (:db/id tagged-comment))))))) - (testing "ordinary blocks cannot be moved to #Comments blocks" + (testing "#Comments blocks cannot be moved as children" + (outliner-core/move-blocks! conn [comments-area] target {:sibling? false}) + (let [comments-area' (d/entity @conn (:db/id comments-area))] + (is (= (:db/id page) + (:db/id (:block/parent comments-area')))))) + + (testing "#Comments blocks can be moved as siblings" + (outliner-core/move-blocks! conn [comments-area] target {:sibling? true}) + (let [page' (d/entity @conn (:db/id page)) + children (->> (:block/_parent page') + ldb/sort-by-order + (mapv :block/title))] + (is (= ["target" "Comments" "tagged comment" "normal parent"] children)))) + + (testing "ordinary blocks can be moved as siblings of #Comments blocks" (outliner-core/move-blocks! conn [ordinary] comments-area {:sibling? true}) (let [ordinary' (d/entity @conn (:db/id ordinary))] - (is (= original-ordinary-parent-id - (:db/id (:block/parent ordinary')))) - (is (not= (:db/id page) - (:db/id (:block/parent ordinary')))))) + (is (= (:db/id page) + (:db/id (:block/parent ordinary')))))) + + (testing "ordinary blocks cannot be moved as children of #Comments blocks" + (outliner-core/move-blocks! conn [ordinary] comments-area {:sibling? false}) + (is (= (:db/id page) + (:db/id (:block/parent (d/entity @conn (:db/id ordinary))))))) (testing "ordinary blocks cannot be moved to #Comment blocks" (outliner-core/move-blocks! conn [ordinary] tagged-comment {:sibling? false}) - (is (= original-ordinary-parent-id + (is (= (:db/id page) (:db/id (:block/parent (d/entity @conn (:db/id ordinary))))))))) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 4813c68ab4..5bd41bfc47 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -2240,7 +2240,7 @@ link? (some :logseq.property/icon (:block/tags block)) (contains? #{"pdf"} (:logseq.property.asset/type block)))) - movable? (not (comments-model/protected-comment-block? block))] + movable? (not (comments-model/comment-block? block))] [:div.block-control-wrap.flex.flex-row.items-center.h-6 {:class (util/classnames [{:is-order-list order-list? :is-with-icon with-icon? @@ -4059,7 +4059,6 @@ (true? comment-thread-present?)) inline-thread (state/sub :comments/inline-thread) show-inline-comments? (inline-comment-thread? inline-thread uuid comment-thread) - protected-comment-block? (comments-model/protected-comment-block? block) page-icon (when (:page-title? config) (let [icon' (get block :logseq.property/icon)] (when-let [icon (and (ldb/page? block) @@ -4162,7 +4161,9 @@ :on-touch-cancel (fn [e] (block-handler/on-touch-cancel e))} - (and (util/capacitor?) (not (ldb/page? block)) (not protected-comment-block?)) + (and (util/capacitor?) + (not (ldb/page? block)) + (not (comments-model/comment-block? block))) (assoc :draggable true :on-drag-start diff --git a/src/main/frontend/components/block/comments_model.cljs b/src/main/frontend/components/block/comments_model.cljs index 423db6e50e..6dd42c03c9 100644 --- a/src/main/frontend/components/block/comments_model.cljs +++ b/src/main/frontend/components/block/comments_model.cljs @@ -36,16 +36,27 @@ (or (comments-area? block) (comment-block? block))) +(defn- move-source-allowed? + [block sibling?] + (and (not (comment-block? block)) + (or sibling? + (not (comments-area? block))))) + +(defn- move-target-allowed? + [target-block sibling?] + (and (not (comment-block? target-block)) + (or sibling? + (not (comments-area? target-block))))) + (defn move-allowed? ([blocks target-block] (move-allowed? blocks target-block {})) - ([blocks target-block _opts] + ([blocks target-block {:keys [sibling?]}] (boolean (and (seq blocks) target-block - (not-any? protected-comment-block? blocks) - (not (comment-block? target-block)) - (not (comments-area? target-block)))))) + (every? #(move-source-allowed? % sibling?) blocks) + (move-target-allowed? target-block sibling?))))) (defn comment-target-blocks [blocks] diff --git a/src/test/frontend/components/block/comments_model_test.cljs b/src/test/frontend/components/block/comments_model_test.cljs new file mode 100644 index 0000000000..907b4c4795 --- /dev/null +++ b/src/test/frontend/components/block/comments_model_test.cljs @@ -0,0 +1,24 @@ +(ns frontend.components.block.comments-model-test + (:require [cljs.test :refer [deftest is testing]] + [frontend.components.block.comments-model :as comments-model])) + +(deftest move-allowed-respects-comments-boundaries + (let [parent {:db/id 1} + comments-area {:db/id 2 + :block/parent parent + :block/tags [{:db/ident comments-model/comments-tag-ident}]} + comment-block {:db/id 3 + :block/parent comments-area} + ordinary-block {:db/id 4 + :block/parent parent}] + (testing "comments areas can only move as siblings" + (is (true? (comments-model/move-allowed? [comments-area] ordinary-block {:sibling? true}))) + (is (false? (comments-model/move-allowed? [comments-area] ordinary-block {:sibling? false})))) + + (testing "ordinary blocks can move next to comments areas but not into them" + (is (true? (comments-model/move-allowed? [ordinary-block] comments-area {:sibling? true}))) + (is (false? (comments-model/move-allowed? [ordinary-block] comments-area {:sibling? false})))) + + (testing "comment blocks remain protected" + (is (false? (comments-model/move-allowed? [comment-block] ordinary-block {:sibling? true}))) + (is (false? (comments-model/move-allowed? [ordinary-block] comment-block {:sibling? true})))))) diff --git a/src/test/frontend/modules/outliner/core_test.cljs b/src/test/frontend/modules/outliner/core_test.cljs index 07729a5d16..eddce3ae4b 100644 --- a/src/test/frontend/modules/outliner/core_test.cljs +++ b/src/test/frontend/modules/outliner/core_test.cljs @@ -348,23 +348,35 @@ (d/transact! (db/get-db test-db false) [{:db/ident :logseq.class/Comments} [:db/add (:db/id (get-block 4)) :block/tags :logseq.class/Comments]]) - (testing "comments area cannot be moved" + (testing "comments area cannot be moved as a child" (outliner-tx/transact! (transact-opts) (outliner-core/move-blocks! (db/get-db test-db false) [(get-block 4)] (get-block 3) {:sibling? false})) (is (= [3 4 5] (get-children 2))) (is (empty? (get-children 3)))) + (testing "comments area can be moved as a sibling" + (outliner-tx/transact! + (transact-opts) + (outliner-core/move-blocks! (db/get-db test-db false) [(get-block 4)] (get-block 5) {:sibling? true})) + (is (= [3 5 4] (get-children 2))) + (is (= [6] (get-children 4)))) (testing "comment item cannot be moved" (outliner-tx/transact! (transact-opts) (outliner-core/move-blocks! (db/get-db test-db false) [(get-block 6)] (get-block 5) {:sibling? false})) (is (= [6] (get-children 4))) (is (empty? (get-children 5)))) - (testing "ordinary blocks cannot be moved into comments" + (testing "ordinary blocks can be moved as siblings of comments" + (outliner-tx/transact! + (transact-opts) + (outliner-core/move-blocks! (db/get-db test-db false) [(get-block 3)] (get-block 4) {:sibling? true})) + (is (= [5 4 3] (get-children 2))) + (is (= [6] (get-children 4)))) + (testing "ordinary blocks cannot be moved into comments as children" (outliner-tx/transact! (transact-opts) (outliner-core/move-blocks! (db/get-db test-db false) [(get-block 5)] (get-block 4) {:sibling? false})) - (is (= [3 4 5] (get-children 2))) + (is (= [5 4 3] (get-children 2))) (is (= [6] (get-children 4)))))) (deftest test-delete-blocks