Просмотр исходного кода

feat:pdf highlight drag & drop (#8103)

* refactor(pdf): names
* improve(pdf): support highlight region draggable
* improve(pdf): unused class of pdf container
* improve(pdf): unused class of pdf container
* fix(pdf): ensure highlight block ref exists when draging to editor & whiteboard region

Co-authored-by: Bad3r <[email protected]>
Co-authored-by: Andelf <[email protected]>
Charlie 3 лет назад
Родитель
Сommit
401c416484

+ 12 - 3
src/main/frontend/components/block.cljs

@@ -2611,14 +2611,23 @@
    (editor-handler/unhighlight-blocks!)))
    (editor-handler/unhighlight-blocks!)))
 
 
 (defn- block-drop
 (defn- block-drop
-  [event uuid target-block *move-to]
+  [^js event uuid target-block *move-to]
   (util/stop event)
   (util/stop event)
   (when-not (dnd-same-block? uuid)
   (when-not (dnd-same-block? uuid)
     (let [block-uuids (state/get-selection-block-ids)
     (let [block-uuids (state/get-selection-block-ids)
           lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
           lookup-refs (map (fn [id] [:block/uuid id]) block-uuids)
           selected (db/pull-many (state/get-current-repo) '[*] lookup-refs)
           selected (db/pull-many (state/get-current-repo) '[*] lookup-refs)
-          blocks (if (seq selected) selected [@*dragging-block])]
-      (dnd/move-blocks event blocks target-block @*move-to)))
+          blocks (if (seq selected) selected [@*dragging-block])
+          blocks (remove-nils blocks)]
+      (if-not (seq blocks)
+        (when-let [text (.getData (.-dataTransfer event) "text/plain")]
+          (editor-handler/api-insert-new-block!
+           text
+           {:block-uuid  uuid
+            :edit-block? false
+            :sibling?    (= @*move-to :sibling)
+            :before?     (= @*move-to :top)}))
+        (dnd/move-blocks event blocks target-block @*move-to))))
   (block-drag-end event *move-to))
   (block-drag-end event *move-to))
 
 
 (defn- block-mouse-over
 (defn- block-mouse-over

+ 20 - 19
src/main/frontend/extensions/pdf/assets.cljs

@@ -184,25 +184,26 @@
   ([pdf hl] (ensure-ref-block! pdf hl nil))
   ([pdf hl] (ensure-ref-block! pdf hl nil))
   ([pdf-current {:keys [id content page properties]} insert-opts]
   ([pdf-current {:keys [id content page properties]} insert-opts]
    (when-let [ref-page (and pdf-current (resolve-ref-page pdf-current))]
    (when-let [ref-page (and pdf-current (resolve-ref-page pdf-current))]
-     (if-let [ref-block (db-model/query-block-by-uuid id)]
-       (do
-         (println "[existed ref block]" ref-block)
-         ref-block)
-       (let [text       (:text content)
-             wrap-props #(if-let [stamp (:image content)]
-                           (assoc % :hl-type "area" :hl-stamp stamp) %)]
-
-         (when (string? text)
-           (editor-handler/api-insert-new-block!
-            text (merge {:page        (:block/name ref-page)
-                         :custom-uuid id
-                         :properties  (wrap-props
-                                       {:ls-type  "annotation"
-                                        :hl-page  page
-                                        :hl-color (:color properties)
-                                        ;; force custom uuid
-                                        :id       (str id)})}
-                        insert-opts))))))))
+     (let [ref-block (db-model/query-block-by-uuid id)]
+       (if-not (nil? (:block/content ref-block))
+         (do
+           (println "[existed ref block]" ref-block)
+           ref-block)
+         (let [text       (:text content)
+               wrap-props #(if-let [stamp (:image content)]
+                             (assoc % :hl-type "area" :hl-stamp stamp) %)]
+
+           (when (string? text)
+             (editor-handler/api-insert-new-block!
+              text (merge {:page        (:block/name ref-page)
+                           :custom-uuid id
+                           :properties  (wrap-props
+                                         {:ls-type  "annotation"
+                                          :hl-page  page
+                                          :hl-color (:color properties)
+                                          ;; force custom uuid
+                                          :id       (str id)})}
+                          insert-opts)))))))))
 
 
 (defn del-ref-block!
 (defn del-ref-block!
   [{:keys [id]}]
   [{:keys [id]}]

+ 62 - 44
src/main/frontend/extensions/pdf/highlights.cljs

@@ -2,6 +2,7 @@
   (:require [cljs-bean.core :as bean]
   (:require [cljs-bean.core :as bean]
             [clojure.string :as string]
             [clojure.string :as string]
             [frontend.components.svg :as svg]
             [frontend.components.svg :as svg]
+            [frontend.components.block :as block]
             [frontend.context.i18n :refer [t]]
             [frontend.context.i18n :refer [t]]
             [frontend.extensions.pdf.assets :as pdf-assets]
             [frontend.extensions.pdf.assets :as pdf-assets]
             [frontend.extensions.pdf.utils :as pdf-utils]
             [frontend.extensions.pdf.utils :as pdf-utils]
@@ -93,11 +94,11 @@
   "The contextual menu which appears over a text selection and allows e.g. creating a highlight."
   "The contextual menu which appears over a text selection and allows e.g. creating a highlight."
   [^js viewer
   [^js viewer
    {:keys [highlight point ^js selection]}
    {:keys [highlight point ^js selection]}
-   {:keys [clear-ctx-tip! add-hl! upd-hl! del-hl!]}]
+   {:keys [clear-ctx-menu! add-hl! upd-hl! del-hl!]}]
 
 
   (rum/use-effect!
   (rum/use-effect!
    (fn []
    (fn []
-     (let [cb #(clear-ctx-tip!)]
+     (let [cb #(clear-ctx-menu!)]
        (js/setTimeout #(js/document.addEventListener "click" cb))
        (js/setTimeout #(js/document.addEventListener "click" cb))
        #(js/document.removeEventListener "click" cb)))
        #(js/document.removeEventListener "click" cb)))
    [])
    [])
@@ -158,7 +159,7 @@
 
 
                               (reset! *highlight-last-color (keyword action)))))
                               (reset! *highlight-last-color (keyword action)))))
 
 
-                        (and clear? (js/setTimeout #(clear-ctx-tip!) 68))))]
+                        (and clear? (js/setTimeout #(clear-ctx-menu!) 68))))]
 
 
     (rum/use-effect!
     (rum/use-effect!
      (fn []
      (fn []
@@ -208,43 +209,58 @@
      ]))
      ]))
 
 
 (rum/defc pdf-highlights-text-region
 (rum/defc pdf-highlights-text-region
-  [^js viewer vw-hl hl
-   {:keys [show-ctx-tip!]}]
+  [^js viewer vw-hl hl {:keys [show-ctx-menu!]}]
 
 
-  (let [{:keys [rects]} (:position vw-hl)
+  (let [{:keys [id]} hl
+        {:keys [rects]} (:position vw-hl)
         {:keys [color]} (:properties hl)
         {:keys [color]} (:properties hl)
-        open-tip! (fn [^js/MouseEvent e]
-                    (.preventDefault e)
-                    (let [x (.-clientX e)
-                          y (.-clientY e)]
 
 
-                      (show-ctx-tip! viewer hl {:x x :y y})))]
+        open-ctx-menu!
+        (fn [^js/MouseEvent e]
+          (.preventDefault e)
+          (let [x (.-clientX e)
+                y (.-clientY e)]
+
+            (show-ctx-menu! viewer hl {:x x :y y})))
+
+        dragstart-handle!
+        (fn [^js e]
+          (when-let [^js dt (and id (.-dataTransfer e))]
+            (reset! block/*dragging? true)
+            (pdf-assets/ensure-ref-block! (state/get-current-pdf) hl)
+            (.setData dt "text/plain" (str "((" id "))"))))]
 
 
     [:div.extensions__pdf-hls-text-region
     [:div.extensions__pdf-hls-text-region
-     {:on-click        open-tip!
-      :on-context-menu open-tip!}
+     {:on-click        open-ctx-menu!
+      :on-context-menu open-ctx-menu!}
 
 
      (map-indexed
      (map-indexed
       (fn [idx rect]
       (fn [idx rect]
         [:div.hls-text-region-item
         [:div.hls-text-region-item
-         {:key        idx
-          :style      rect
-          :data-color color}])
+         {:key           idx
+          :style         rect
+          :draggable     "true"
+          :on-drag-start dragstart-handle!
+          :data-color    color}])
       rects)]))
       rects)]))
 
 
 (rum/defc ^:large-vars/cleanup-todo pdf-highlight-area-region
 (rum/defc ^:large-vars/cleanup-todo pdf-highlight-area-region
-  [^js viewer vw-hl hl
-   {:keys [show-ctx-tip! upd-hl!]}]
+  [^js viewer vw-hl hl {:keys [show-ctx-menu! upd-hl!]}]
+
+  (let [{:keys [id]} hl
+        *el    (rum/use-ref nil)
+        *dirty (rum/use-ref nil)
+        open-ctx-menu! (fn [^js/MouseEvent e]
+                         (.preventDefault e)
+                         (when-not (rum/deref *dirty)
+                           (let [x (.-clientX e)
+                                 y (.-clientY e)]
 
 
-  (let [*el       (rum/use-ref nil)
-        *dirty    (rum/use-ref nil)
-        open-tip! (fn [^js/MouseEvent e]
-                    (.preventDefault e)
-                    (when-not (rum/deref *dirty)
-                      (let [x (.-clientX e)
-                            y (.-clientY e)]
+                             (show-ctx-menu! viewer hl {:x x :y y}))))
 
 
-                        (show-ctx-tip! viewer hl {:x x :y y}))))]
+        dragstart-handle! (fn [^js e]
+                            (when-let [^js dt (and id (.-dataTransfer e))]
+                              (.setData dt "text/plain" (str "((" id "))"))))]
 
 
     ;; resizable
     ;; resizable
     (rum/use-effect!
     (rum/use-effect!
@@ -331,8 +347,10 @@
          {:ref             *el
          {:ref             *el
           :style           vw-bounding
           :style           vw-bounding
           :data-color      color
           :data-color      color
-          :on-click        open-tip!
-          :on-context-menu open-tip!}]))))
+          :draggable       "true"
+          :on-drag-start   dragstart-handle!
+          :on-click        open-ctx-menu!
+          :on-context-menu open-ctx-menu!}]))))
 
 
 (rum/defc pdf-highlights-region-container
 (rum/defc pdf-highlights-region-container
   "Displays the highlights over a pdf document."
   "Displays the highlights over a pdf document."
@@ -349,7 +367,7 @@
        ))])
        ))])
 
 
 (rum/defc ^:large-vars/cleanup-todo pdf-highlight-area-selection
 (rum/defc ^:large-vars/cleanup-todo pdf-highlight-area-selection
-  [^js viewer {:keys [show-ctx-tip!]}]
+  [^js viewer {:keys [show-ctx-menu!]}]
 
 
   (let [^js viewer-clt          (.. viewer -viewer -classList)
   (let [^js viewer-clt          (.. viewer -viewer -classList)
         ^js cnt-el              (.-container viewer)
         ^js cnt-el              (.-container viewer)
@@ -439,7 +457,7 @@
                                                      :properties {}}]
                                                      :properties {}}]
 
 
                                     ;; ctx tips
                                     ;; ctx tips
-                                    (show-ctx-tip! viewer hl point {:reset-fn #(reset-coords)})
+                                    (show-ctx-menu! viewer hl point {:reset-fn #(reset-coords)})
 
 
                                     ;; export area highlight
                                     ;; export area highlight
                                     ;;(dd "[selection end] :start"
                                     ;;(dd "[selection end] :start"
@@ -481,17 +499,17 @@
         *mounted       (rum/use-ref false)
         *mounted       (rum/use-ref false)
         [sel-state, set-sel-state!] (rum/use-state {:selection nil :range nil :collapsed nil :point nil})
         [sel-state, set-sel-state!] (rum/use-state {:selection nil :range nil :collapsed nil :point nil})
         [highlights, set-highlights!] (rum/use-state initial-hls)
         [highlights, set-highlights!] (rum/use-state initial-hls)
-        [tip-state, set-tip-state!] (rum/use-state {:highlight nil :vw-pos nil :selection nil :point nil :reset-fn nil})
+        [ctx-menu-state, set-ctx-menu-state!] (rum/use-state {:highlight nil :vw-pos nil :selection nil :point nil :reset-fn nil})
 
 
-        clear-ctx-tip! (rum/use-callback
-                        #(let [reset-fn (:reset-fn tip-state)]
-                           (set-tip-state! {})
+        clear-ctx-menu! (rum/use-callback
+                        #(let [reset-fn (:reset-fn ctx-menu-state)]
+                           (set-ctx-menu-state! {})
                            (and (fn? reset-fn) (reset-fn)))
                            (and (fn? reset-fn) (reset-fn)))
-                        [tip-state])
+                        [ctx-menu-state])
 
 
-        show-ctx-tip!  (fn [^js viewer hl point & ops]
+        show-ctx-menu!  (fn [^js viewer hl point & ops]
                          (let [vw-pos (pdf-utils/scaled-to-vw-pos viewer (:position hl))]
                          (let [vw-pos (pdf-utils/scaled-to-vw-pos viewer (:position hl))]
-                           (set-tip-state! (apply merge (list* {:highlight hl :vw-pos vw-pos :point point} ops)))))
+                           (set-ctx-menu-state! (apply merge (list* {:highlight hl :vw-pos vw-pos :point point} ops)))))
 
 
         add-hl!        (fn [hl] (when (:id hl)
         add-hl!        (fn [hl] (when (:id hl)
                                   ;; fix js object
                                   ;; fix js object
@@ -603,7 +621,7 @@
 
 
            ;; show ctx menu
            ;; show ctx menu
            (js/setTimeout (fn []
            (js/setTimeout (fn []
-                            (set-tip-state! {:highlight hl-fn
+                            (set-ctx-menu-state! {:highlight hl-fn
                                              :selection selection
                                              :selection selection
                                              :point     point})))) 0))
                                              :point     point})))) 0))
 
 
@@ -621,7 +639,7 @@
 
 
                (rum/mount
                (rum/mount
                 (pdf-highlights-region-container
                 (pdf-highlights-region-container
-                 viewer page-hls {:show-ctx-tip! show-ctx-tip!
+                 viewer page-hls {:show-ctx-menu! show-ctx-menu!
                                   :upd-hl!       upd-hl!})
                                   :upd-hl!       upd-hl!})
 
 
                 hls-layer)))))
                 hls-layer)))))
@@ -633,10 +651,10 @@
     [:div.extensions__pdf-highlights-cnt
     [:div.extensions__pdf-highlights-cnt
 
 
      ;; hl context tip menu
      ;; hl context tip menu
-     (when-let [_hl (:highlight tip-state)]
+     (when-let [_hl (:highlight ctx-menu-state)]
        (js/ReactDOM.createPortal
        (js/ReactDOM.createPortal
-        (pdf-highlights-ctx-menu viewer tip-state
-                                 {:clear-ctx-tip! clear-ctx-tip!
+        (pdf-highlights-ctx-menu viewer ctx-menu-state
+                                 {:clear-ctx-menu! clear-ctx-menu!
                                   :add-hl!        add-hl!
                                   :add-hl!        add-hl!
                                   :del-hl!        del-hl!
                                   :del-hl!        del-hl!
                                   :upd-hl!        upd-hl!})
                                   :upd-hl!        upd-hl!})
@@ -660,8 +678,8 @@
      ;; area selection container
      ;; area selection container
      (pdf-highlight-area-selection
      (pdf-highlight-area-selection
       viewer
       viewer
-      {:clear-ctx-tip! clear-ctx-tip!
-       :show-ctx-tip!  show-ctx-tip!
+      {:clear-ctx-menu! clear-ctx-menu!
+       :show-ctx-menu!  show-ctx-menu!
        :add-hl!        add-hl!
        :add-hl!        add-hl!
        })]))
        })]))
 
 

+ 5 - 1
src/main/frontend/handler/editor/keyboards.cljs

@@ -11,7 +11,7 @@
     (mixins/hide-when-esc-or-outside
     (mixins/hide-when-esc-or-outside
      state
      state
      :on-hide
      :on-hide
-     (fn [_state _e event]
+     (fn [_state e event]
        (cond
        (cond
          (contains?
          (contains?
           #{:commands :block-commands
           #{:commands :block-commands
@@ -25,6 +25,10 @@
          (= :input (state/get-editor-action))
          (= :input (state/get-editor-action))
          nil
          nil
 
 
+         (some-> (.-target e)
+                 (.closest ".ls-keep-editing-when-outside-click"))
+         nil
+
          :else
          :else
          (let [{:keys [on-hide value]} (editor-handler/get-state)]
          (let [{:keys [on-hide value]} (editor-handler/get-state)]
            (when on-hide
            (when on-hide