Explorar el Código

feat: Shift click to select multiple blocks

Tienson Qin hace 3 años
padre
commit
21c36e69e2

+ 46 - 37
src/main/frontend/components/block.cljs

@@ -1769,46 +1769,54 @@
          [:div.my-4
           (datetime-comp/date-picker nil nil ts)]))]))
 
+(defn- target-forbidden-edit?
+  [target]
+  (or
+   (d/has-class? target "forbid-edit")
+   (d/has-class? target "bullet")
+   (d/has-class? target "logbook")
+   (util/link? target)
+   (util/time? target)
+   (util/input? target)
+   (util/details-or-summary? target)
+   (and (util/sup? target)
+        (d/has-class? target "fn"))
+   (d/has-class? target "image-resize")))
+
 (defn- block-content-on-mouse-down
   [e block block-id _content edit-input-id]
   (.stopPropagation e)
   (let [target (gobj/get e "target")
-        button (gobj/get e "buttons")]
+        button (gobj/get e "buttons")
+        shift? (gobj/get e "shiftKey")]
     (when (contains? #{1 0} button)
-      (when-not (or
-                 (d/has-class? target "forbid-edit")
-                 (d/has-class? target "bullet")
-                 (d/has-class? target "logbook")
-                 (util/link? target)
-                 (util/time? target)
-                 (util/input? target)
-                 (util/details-or-summary? target)
-                 (and (util/sup? target)
-                      (d/has-class? target "fn"))
-                 (d/has-class? target "image-resize"))
-        (editor-handler/clear-selection!)
-        (editor-handler/unhighlight-blocks!)
-        (let [f #(let [block (or (db/pull [:block/uuid (:block/uuid block)]) block)
-                       cursor-range (util/caret-range (gdom/getElement block-id))
-                       {:block/keys [content format]} block
-                       content (->> content
-                                    (property/remove-built-in-properties format)
-                                    (drawer/remove-logbook))]
-                   ;; save current editing block
-                   (let [{:keys [value] :as state} (editor-handler/get-state)]
-                     (editor-handler/save-block! state value))
-                   (state/set-editing!
-                    edit-input-id
-                    content
-                    block
-                    cursor-range
-                    false))]
-          ;; wait a while for the value of the caret range
-          (if (util/ios?)
-            (f)
-            (js/setTimeout f 5)))
-
-        (when block-id (state/set-selection-start-block! block-id))))))
+      (when-not (target-forbidden-edit? target)
+        (if (and shift? (state/get-selection-start-block))
+          (editor-handler/highlight-selection-area! block-id)
+          (do
+            (editor-handler/clear-selection!)
+            (editor-handler/unhighlight-blocks!)
+            (let [f #(let [block (or (db/pull [:block/uuid (:block/uuid block)]) block)
+                           cursor-range (util/caret-range (gdom/getElement block-id))
+                           {:block/keys [content format]} block
+                           content (->> content
+                                        (property/remove-built-in-properties format)
+                                        (drawer/remove-logbook))]
+                       ;; save current editing block
+                       (let [{:keys [value] :as state} (editor-handler/get-state)]
+                         (editor-handler/save-block! state value))
+                       (state/set-editing!
+                        edit-input-id
+                        content
+                        block
+                        cursor-range
+                        false))]
+              ;; wait a while for the value of the caret range
+              (if (util/ios?)
+                (f)
+                (js/setTimeout f 5))
+
+              (when block-id (state/set-selection-start-block! block-id)))))))))
 
 (rum/defc dnd-separator-wrapper < rum/reactive
   [block block-id slide? top? block-content?]
@@ -1877,10 +1885,11 @@
                                         (block-content-on-mouse-down e block block-id content edit-input-id))))]
     [:div.block-content.inline
      (cond-> {:id (str "block-content-" uuid)
-              :on-mouse-up (fn [_e]
+              :on-mouse-up (fn [e]
                              (when (and
                                     (state/in-selection-mode?)
-                                    (not (string/includes? content "```")))
+                                    (not (string/includes? content "```"))
+                                    (not (gobj/get e "shiftKey")))
                                ;; clear highlighted text
                                (util/clear-selection!)))}
        (not slide?)

+ 4 - 3
src/main/frontend/components/sidebar.cljs

@@ -453,9 +453,10 @@
        "?"])))
 
 (defn- hide-context-menu-and-clear-selection
-  []
+  [e]
   (state/hide-custom-context-menu!)
-  (editor-handler/clear-selection!))
+  (when-not (gobj/get e "shiftKey")
+    (editor-handler/clear-selection!)))
 
 (rum/defcs sidebar <
   (mixins/modal :modal/show?)
@@ -468,7 +469,7 @@
                       (when (= 27 (.-keyCode e))
                         (if (state/modal-opened?)
                           (state/close-modal!)
-                          (hide-context-menu-and-clear-selection)))))))
+                          (hide-context-menu-and-clear-selection e)))))))
   {:did-mount (fn [state]
                 (swipe/setup-listeners!)
                 state)}

+ 0 - 1
src/main/frontend/handler/editor.cljs

@@ -3600,7 +3600,6 @@
                        expand-block!)))
             doall)
        (and clear-selection? (clear-selection!)))
-
      :else
      ;; expand one level
      (let [blocks-with-level (all-blocks-with-level {})

+ 6 - 5
src/main/frontend/util.cljc

@@ -385,11 +385,12 @@
                                     str)
                        ;; FIXME: this depends on the dom structure,
                        ;; need a converter from html to text includes newlines
-                       br-ended? (or
-                                  ;; first line with a new line
-                                  (string/ends-with? html "<div class=\"is-paragraph\"></div></div></span></div></div></div>")
-                                  ;; multiple lines with a new line
-                                  (string/ends-with? html "<br></div></div></span></div></div></div>"))
+                       br-ended? (and html
+                                      (or
+                                       ;; first line with a new line
+                                       (string/ends-with? html "<div class=\"is-paragraph\"></div></div></span></div></div></div>")
+                                       ;; multiple lines with a new line
+                                       (string/ends-with? html "<br></div></div></span></div></div></div>")))
                        value (.toString pre-caret-range)]
                    (if br-ended?
                      (str value "\n")