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

feat: copy selected blocks as X

rcmerci 4 лет назад
Родитель
Сommit
48f07e8aef

+ 9 - 2
src/main/frontend/components/content.cljs

@@ -59,7 +59,14 @@
     (ui/menu-link
      {:key "copy"
       :on-click editor-handler/copy-selection-blocks}
-     "Copy")]])
+     "Copy")
+    (ui/menu-link
+     {:key "copy as"
+      :on-click (fn [_]
+                  (let [block-uuids (editor-handler/get-selected-toplevel-block-uuids)]
+                    (state/set-modal!
+                     #(export/export-blocks block-uuids))))}
+     "Copy as")]])
 
 ;; FIXME: Make it configurable
 (def block-background-colors
@@ -178,7 +185,7 @@
           (ui/menu-link
            {:key "Copy as"
             :on-click (fn [_]
-                        (state/set-modal! #(export/export-blocks block-id)))}
+                        (state/set-modal! #(export/export-blocks [block-id])))}
            "Copy as")
 
           (if (srs/card-block? block)

+ 5 - 5
src/main/frontend/components/export.cljs

@@ -73,7 +73,7 @@
 (rum/defcs export-blocks
   < rum/reactive
   (rum/local false ::copied?)
-  [state root-block-id]
+  [state root-block-ids]
   (let [current-repo (state/get-current-repo)
         type (rum/react *export-block-type)
         text-indent-style (rum/react (state/get-export-block-text-indent-style))
@@ -81,10 +81,10 @@
         copied? (::copied? state)
         content
         (case type
-          :text (export/export-blocks-as-markdown current-repo root-block-id text-indent-style (into [] text-remove-options))
-          :opml (export/export-blocks-as-opml current-repo root-block-id)
-          :html (export/export-blocks-as-html current-repo root-block-id)
-          (export/export-blocks-as-markdown current-repo root-block-id text-indent-style (into [] text-remove-options)))]
+          :text (export/export-blocks-as-markdown current-repo root-block-ids text-indent-style (into [] text-remove-options))
+          :opml (export/export-blocks-as-opml current-repo root-block-ids)
+          :html (export/export-blocks-as-html current-repo root-block-ids)
+          (export/export-blocks-as-markdown current-repo root-block-ids text-indent-style (into [] text-remove-options)))]
     [:div.export.w-96.resize
      [:div
       {:class "mb-2"}

+ 26 - 5
src/main/frontend/handler/editor.cljs

@@ -1083,12 +1083,11 @@
         level-blocks (mapv (fn [uuid] (get level-blocks-uuid-map uuid)) block-ids*)
         tree (blocks-vec->tree level-blocks)
         top-level-block-uuids (mapv :block/uuid (filterv #(not (vector? %)) tree))
-        exported-md-contents (mapv #(export/export-blocks-as-markdown
-                                     repo %
+        exported-md-contents (export/export-blocks-as-markdown
+                                     repo top-level-block-uuids
                                      @(state/get-export-block-text-indent-style)
-                                     (into [] @(state/get-export-block-text-remove-options)))
-                                   top-level-block-uuids)]
-    [(string/join "\n" (mapv string/trim-newline exported-md-contents)) tree]))
+                                     (into [] @(state/get-export-block-text-remove-options)))]
+    [exported-md-contents tree]))
 
 (defn copy-selection-blocks
   []
@@ -1103,6 +1102,28 @@
       (state/set-copied-blocks content tree)
       (notification/show! "Copied!" :success))))
 
+(defn get-selected-toplevel-block-uuids
+  []
+  (when-let [blocks (seq (get-selected-blocks-with-children))]
+    (let [repo (state/get-current-repo)
+          block-ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")]
+                                     (uuid id)) blocks))
+                   (remove nil?))
+          blocks (db-utils/pull-many repo '[*] (mapv (fn [id] [:block/uuid id]) block-ids))
+          blocks* (flatten
+                   (mapv (fn [b] (if (:collapsed (:block/properties b))
+                                   (vec (tree/sort-blocks (db/get-block-children repo (:block/uuid b)) b))
+                                   [b])) blocks))
+          block-ids* (mapv :block/uuid blocks*)
+          unordered? (:block/unordered (first blocks*))
+          format (:block/format (first blocks*))
+          level-blocks-map (blocks-with-level blocks*)
+          level-blocks-uuid-map (into {} (mapv (fn [b] [(:block/uuid b) b]) (vals level-blocks-map)))
+          level-blocks (mapv (fn [uuid] (get level-blocks-uuid-map uuid)) block-ids*)
+          tree (blocks-vec->tree level-blocks)
+          top-level-block-uuids (mapv :block/uuid (filterv #(not (vector? %)) tree))]
+      top-level-block-uuids)))
+
 (defn cut-selection-blocks
   [copy?]
   (when copy? (copy-selection-blocks))

+ 30 - 35
src/main/frontend/handler/export.cljs

@@ -21,7 +21,6 @@
             [goog.dom :as gdom]
             [promesa.core :as p]))
 
-
 (defn- get-page-content
   [page]
   (outliner-file/tree->file-content
@@ -433,45 +432,42 @@
                                            (clj->js (f (first names)))))]))))
          (remove nil?))))
 
-(defn export-blocks-as-opml
-  [repo root-block-uuid]
+(defn export-blocks-as-aux
+  [repo root-block-uuids auxf]
+  {:pre [(> (count root-block-uuids) 0)]}
   (let [get-page&block-refs-by-query-aux (get-embed-and-refs-blocks-pages-aux)
         f #(get-page&block-refs-by-query repo % get-page&block-refs-by-query-aux {:is-block? true})
-        root-block (db/entity [:block/uuid root-block-uuid])
-        blocks (db/get-block-and-children repo root-block-uuid)
+        root-blocks (mapv #(db/entity [:block/uuid %]) root-block-uuids)
+        blocks (mapcat #(db/get-block-and-children repo %) root-block-uuids)
         refs (f blocks)
-        content (get-blocks-contents repo root-block-uuid)
-        format (or (:block/format root-block) (state/get-preferred-format))]
-    (fp/exportOPML f/mldoc-record content
-                   (f/get-default-config format)
-                   "untitled"
-                   (js/JSON.stringify (clj->js refs)))))
+        contents (mapv #(get-blocks-contents repo %) root-block-uuids)
+        content (string/join "\n" (mapv string/trim-newline contents))
+        format (or (:block/format (first root-blocks)) (state/get-preferred-format))]
+    (auxf content format refs)))
 
-(defn export-blocks-as-markdown
-  [repo root-block-uuid indent-style remove-options]
-  (let [get-page&block-refs-by-query-aux (get-embed-and-refs-blocks-pages-aux)
-        f #(get-page&block-refs-by-query repo % get-page&block-refs-by-query-aux {:is-block? true})
-        root-block (db/entity [:block/uuid root-block-uuid])
-        blocks (db/get-block-and-children repo root-block-uuid)
-        refs (f blocks)
-        content (get-blocks-contents repo root-block-uuid)
-        format (or (:block/format root-block) (state/get-preferred-format))]
-    (fp/exportMarkdown f/mldoc-record content
-                       (f/get-default-config format {:export-md-indent-style indent-style :export-md-remove-options remove-options})
-                       (js/JSON.stringify (clj->js refs)))))
+(defn export-blocks-as-opml
+  [repo root-block-uuids]
+  (export-blocks-as-aux repo root-block-uuids
+                        #(fp/exportOPML f/mldoc-record %1
+                                        (f/get-default-config %2)
+                                        "untitled"
+                                        (js/JSON.stringify (clj->js %3)))))
 
+(defn export-blocks-as-markdown
+  [repo root-block-uuids indent-style remove-options]
+  (export-blocks-as-aux repo root-block-uuids
+                        #(fp/exportMarkdown f/mldoc-record %1
+                                            (f/get-default-config
+                                             %2
+                                             {:export-md-indent-style indent-style
+                                              :export-md-remove-options remove-options})
+                                            (js/JSON.stringify (clj->js %3)))))
 (defn export-blocks-as-html
-  [repo root-block-uuid]
-  (let [get-page&block-refs-by-query-aux (get-embed-and-refs-blocks-pages-aux)
-        f #(get-page&block-refs-by-query repo % get-page&block-refs-by-query-aux {:is-block? true})
-        root-block (db/entity [:block/uuid root-block-uuid])
-        blocks (db/get-block-and-children repo root-block-uuid)
-        refs (f blocks)
-        content (get-blocks-contents repo root-block-uuid)
-        format (or (:block/format root-block) (state/get-preferred-format))]
-    (fp/toHtml f/mldoc-record content
-                       (f/get-default-config format)
-                       (js/JSON.stringify (clj->js refs)))))
+  [repo root-block-uuids]
+  (export-blocks-as-aux repo root-block-uuids
+                        #(fp/toHtml f/mldoc-record %1
+                                    (f/get-default-config %2)
+                                    (js/JSON.stringify (clj->js %3)))))
 
 (defn- convert-md-files-unordered-list-or-heading
   [repo files heading-to-list?]
@@ -562,7 +558,6 @@
                   (.setAttribute anchor "download" opml-path)
                   (.click anchor))))))))))
 
-
 (defn convert-page-markdown-unordered-list-or-heading!
   [page-name]
   (when-let [repo (state/get-current-repo)]