fix: selection for virtualized blocks

pull/11433/head
Tienson Qin 2024-07-25 21:35:40 +08:00
parent 5c8190e5e4
commit 0eaf10cacc
3 changed files with 58 additions and 36 deletions

View File

@ -2855,7 +2855,7 @@
(non-dragging? e))
(when-let [container (gdom/getElement "app-container-wrapper")]
(dom/add-class! container "blocks-selection-mode"))
(editor-handler/highlight-selection-area! block-id {:append? false}))))
(editor-handler/highlight-selection-area! block-id {:append? true}))))
(defn- block-mouse-leave
[e *control-show? block-id doc-mode?]
@ -2956,7 +2956,7 @@
edit-input-id (str "edit-block-" (:block/uuid block))
container-id (:container-id config*)
editing? (or (state/sub-editing? [container-id (:block/uuid block)])
(state/sub-editing? [:unknown-container (:block/uuid block)]))
(state/sub-editing? [:unknown-container (:block/uuid block)]))
table? (:table? config*)
custom-query? (boolean (:custom-query? config*))
ref-or-custom-query? (or ref? custom-query?)
@ -3042,7 +3042,7 @@
:on-touch-cancel (fn [_e]
(block-handler/on-touch-cancel *show-left-menu? *show-right-menu?))
:on-mouse-enter (fn [e]
(block-mouse-over e *control-show? block-id doc-mode?))
(block-mouse-over e *control-show? block-id doc-mode?))
:on-mouse-leave (fn [e]
(block-mouse-leave e *control-show? block-id doc-mode?))}
(when (and (not slide?) (not in-whiteboard?) (not table?))
@ -3064,7 +3064,7 @@
[:div.flex.flex-col.w-full
(let [block (merge block (block/parse-title-and-body uuid (:block/format block) pre-block? content))
hide-block-refs-count? (or (and (:embed? config)
(= (:block/uuid block) (:embed-id config)))
(= (:block/uuid block) (:embed-id config)))
table?)]
(block-content-or-editor config block
{:edit-input-id edit-input-id

View File

@ -1229,27 +1229,34 @@
(delete-block-aux! block))))
(defn highlight-selection-area!
[end-block & {:keys [append?]}]
[end-block-id & {:keys [append?]}]
(when-let [start-block (state/get-selection-start-block-or-first)]
(let [node (gdom/getElement start-block)
selected-blocks (state/get-selection-blocks)
latest-visible-block (or node
(when-let [node (first selected-blocks)]
(.-id ^js node))
(when-let [node (last selected-blocks)]
(.-id ^js node)))]
(let [end-block-node (gdom/getElement end-block-id)
node (gdom/getElement start-block)
select-direction (state/get-selection-direction)
visible? (and node (util/el-visible-in-viewport? node))
selected-blocks (state/get-unsorted-selection-blocks)
last-node (when-let [node (last selected-blocks)]
(when-let [node (gdom/getElement (.-id ^js node))]
(when (util/el-visible-in-viewport? node)
node)))
latest-visible-block (or last-node (when visible? node))
latest-block-id (when latest-visible-block (.-id latest-visible-block))]
(when latest-visible-block
(let [blocks (util/get-nodes-between-two-nodes latest-visible-block end-block "ls-block")
direction (util/get-direction-between-two-nodes latest-visible-block end-block "ls-block")
blocks (if (= :up direction)
(reverse blocks)
blocks)]
(let [blocks (util/get-nodes-between-two-nodes latest-block-id end-block-id "ls-block")
direction (if (= latest-block-id end-block-id)
select-direction
(util/get-direction-between-two-nodes latest-block-id end-block-id "ls-block"))
blocks (if (= direction :up)
(reverse (util/sort-by-height blocks))
(util/sort-by-height blocks))]
(if append?
(do (state/clear-edit!)
(state/conj-selection-block! blocks direction))
(if (and select-direction (not= direction select-direction))
(state/drop-selection-blocks-starts-with! end-block-node)
(state/conj-selection-block! blocks direction)))
(state/exit-editing-and-set-selected-blocks! blocks direction)))))))
(defn- select-block-up-down
[direction]
(cond

View File

@ -161,9 +161,9 @@
;; Warning: blocks order is determined when setting this attribute
:selection/blocks (atom [])
:selection/start-block (atom nil)
;; either :up or :down, defaults to down
;; nil, :up or :down
;; used to determine selection direction when two or more blocks are selected
:selection/direction (atom :down)
:selection/direction (atom nil)
:selection/selected-all? (atom false)
:custom-context-menu/show? false
:custom-context-menu/links nil
@ -1137,9 +1137,21 @@ Similar to re-frame subscriptions"
[start-block]
(set-state! :selection/start-block start-block))
(defn get-selection-direction
[]
@(:selection/direction @state))
(defn get-unsorted-selection-blocks
[]
@(:selection/blocks @state))
(defn get-selection-blocks
[]
(util/sort-by-height @(:selection/blocks @state)))
(let [result (get-unsorted-selection-blocks)
direction (get-selection-direction)]
(if (= direction :up)
(vec (reverse result))
result)))
(defn get-selection-block-ids
[]
@ -1172,13 +1184,13 @@ Similar to re-frame subscriptions"
(defn set-selection-blocks!
([blocks]
(set-selection-blocks! blocks :down))
(set-selection-blocks! blocks nil))
([blocks direction]
(when (seq blocks)
(let [blocks (vec (util/sort-by-height (remove nil? blocks)))]
(let [blocks (vec (remove nil? blocks))]
(set-state! :selection/mode true)
(set-selection-blocks-aux! blocks)
(set-state! :selection/direction direction)))))
(when direction (set-state! :selection/direction direction))))))
(defn into-selection-mode!
[]
@ -1188,7 +1200,7 @@ Similar to re-frame subscriptions"
[]
(set-state! :selection/mode false)
(set-state! :selection/blocks nil)
(set-state! :selection/direction :down)
(set-state! :selection/direction nil)
(set-state! :selection/start-block nil)
(set-state! :selection/selected-all? false))
@ -1214,9 +1226,9 @@ Similar to re-frame subscriptions"
(defn conj-selection-block!
[block-or-blocks direction]
(let [selection-blocks (get-selection-blocks)
(let [selection-blocks (get-unsorted-selection-blocks)
blocks (-> (if (sequential? block-or-blocks)
(apply conj selection-blocks block-or-blocks)
(concat selection-blocks block-or-blocks)
(conj selection-blocks block-or-blocks))
distinct)]
(set-selection-blocks! blocks direction)))
@ -1224,10 +1236,18 @@ Similar to re-frame subscriptions"
(defn drop-selection-block!
[block]
(set-state! :selection/mode true)
(set-selection-blocks-aux! (-> (remove #(= block %) (get-selection-blocks))
util/sort-by-height
(set-selection-blocks-aux! (-> (remove #(= block %) (get-unsorted-selection-blocks))
vec)))
(defn drop-selection-blocks-starts-with!
[block]
(set-state! :selection/mode true)
(let [blocks (get-unsorted-selection-blocks)
blocks' (-> (take-while (fn [b] (not= (.-id b) (.-id block))) blocks)
vec
(conj block))]
(set-selection-blocks-aux! blocks')))
(defn drop-last-selection-block!
[]
(let [direction @(:selection/direction @state)
@ -1239,16 +1259,11 @@ Similar to re-frame subscriptions"
blocks' (-> (if up?
(rest blocks)
(pop (vec blocks)))
util/sort-by-height
vec)]
(set-state! :selection/mode true)
(set-selection-blocks-aux! blocks')
last-block))
(defn get-selection-direction
[]
@(:selection/direction @state))
(defn hide-custom-context-menu!
[]
(swap! state assoc
@ -2010,7 +2025,7 @@ Similar to re-frame subscriptions"
(defn exit-editing-and-set-selected-blocks!
([blocks]
(exit-editing-and-set-selected-blocks! blocks :down))
(exit-editing-and-set-selected-blocks! blocks nil))
([blocks direction]
(clear-edit!)
(set-selection-blocks! blocks direction)))