Răsfoiți Sursa

Merge branch 'master' into feat/db

Gabriel Horner 2 ani în urmă
părinte
comite
fa1f8a76f8

+ 48 - 9
src/main/frontend/components/block.cljs

@@ -2692,6 +2692,7 @@
    (editor-handler/unhighlight-blocks!)))
 
 (defn- block-drop
+  "Block on-drop handler"
   [^js event uuid target-block original-block *move-to]
   (util/stop event)
   (when-not (dnd-same-block? uuid)
@@ -2700,15 +2701,53 @@
           selected (db/pull-many (state/get-current-repo) '[*] lookup-refs)
           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 original-block @*move-to))))
+      (if (seq blocks)
+        ;; dnd block moving in current Logseq instance
+        (dnd/move-blocks event blocks target-block original-block @*move-to)
+        ;; handle DataTransfer
+        (let [repo (state/get-current-repo)
+              data-transfer (.-dataTransfer event)
+              transfer-types (set (js->clj (.-types data-transfer)))]
+          (cond
+            (contains? transfer-types "text/plain")
+            (let [text (.getData data-transfer "text/plain")]
+              (editor-handler/api-insert-new-block!
+               text
+               {:block-uuid  uuid
+                :edit-block? false
+                :sibling?    (= @*move-to :sibling)
+                :before?     (= @*move-to :top)}))
+
+            (contains? transfer-types "Files")
+            (let [files (.-files data-transfer)
+                  format (:block/format target-block)]
+              ;; When editing, this event will be handled by editor-handler/upload-asset(editor-on-paste)
+              (when (and (config/local-file-based-graph? repo) (not (state/editing?)))
+                ;; Basically the same logic as editor-handler/upload-asset,
+                ;; does not require edting
+                (-> (editor-handler/save-assets! repo (js->clj files))
+                    (p/then
+                     (fn [res]
+                       (when-let [[asset-file-name file-obj asset-file-fpath matched-alias] (and (seq res) (first res))]
+                         (let [image? (config/ext-of-image? asset-file-name)
+                               link-content (assets-handler/get-asset-file-link format
+                                                                                (if matched-alias
+                                                                                  (str
+                                                                                   (if image? "../assets/" "")
+                                                                                   "@" (:name matched-alias) "/" asset-file-name)
+                                                                                  (editor-handler/resolve-relative-path (or asset-file-fpath asset-file-name)))
+                                                                                (if file-obj (.-name file-obj) (if image? "image" "asset"))
+                                                                                image?)]
+                           (editor-handler/api-insert-new-block!
+                            link-content
+                            {:block-uuid  uuid
+                             :edit-block? false
+                             :replace-empty-target? true
+                             :sibling?   true
+                             :before?    false}))))))))
+
+            :else
+            (prn ::unhandled-drop-data-transfer-type transfer-types))))))
   (block-drag-end event *move-to))
 
 (defn- block-mouse-over

+ 2 - 4
src/main/frontend/components/settings.cljs

@@ -1104,13 +1104,11 @@
           (when label
             [:li.settings-menu-item
              {:key      text
+              :data-id  id
               :class    (util/classnames [{:active (= label (first @*active))}])
               :on-click #(reset! *active [label (first @*active)])}
 
-             [:a.flex.items-center.settings-menu-link
-              {:data-id id}
-              icon
-              [:strong text]]]))]]
+             [:a.flex.items-center.settings-menu-link icon [:strong text]]]))]]
 
       [:article
        [:header.cp__settings-header

+ 4 - 0
src/main/frontend/components/settings.css

@@ -65,6 +65,10 @@
     .settings-menu-item {
       @apply list-none p-0 my-1.5 rounded;
       @apply hover:bg-black/10;
+
+      &[data-id=keymap] {
+        @apply hidden sm:block;
+      }
     }
 
     .settings-menu-link {

+ 1 - 1
src/main/frontend/extensions/tldraw.cljs

@@ -66,7 +66,7 @@
 
 (defn save-asset-handler
   [file]
-  (-> (editor-handler/save-assets! nil (state/get-current-repo) [(js->clj file)])
+  (-> (editor-handler/save-assets! (state/get-current-repo) [(js->clj file)])
       (p/then
        (fn [res]
          (when-let [[asset-file-name _ full-file-path] (and (seq res) (first res))]

+ 12 - 0
src/main/frontend/fs/capacitor_fs.cljs

@@ -41,6 +41,18 @@
            (fn [_error]
              false)))
 
+(defn <write-file-with-base64
+  "Write a binary file, requires base64 encoding"
+  [path content]
+  (when-not (string/blank? path)
+    (-> (p/chain (.writeFile Filesystem (clj->js {:path path
+                                                  :data content
+                                                  :recursive true}))
+                 #(js->clj % :keywordize-keys true))
+        (p/catch (fn [error]
+                   (js/console.error "writeFile Error: " path ": " error)
+                   nil)))))
+
 (defn- <write-file-with-utf8
   [path content]
   (when-not (string/blank? path)

+ 13 - 0
src/main/frontend/handler/assets.cljs

@@ -113,6 +113,19 @@
                  (get-alias-dirs))]
       alias)))
 
+(defn get-asset-file-link
+  "Link text for inserting to markdown/org"
+  [format url file-name image?]
+  (let [pdf?   (and url (string/ends-with? (string/lower-case url) ".pdf"))
+        media? (and url (or (config/ext-of-audio? url)
+                            (config/ext-of-video? url)))]
+    (case (keyword format)
+      :markdown (util/format (str (when (or image? media? pdf?) "!") "[%s](%s)") file-name url)
+      :org (if image?
+             (util/format "[[%s]]" url)
+             (util/format "[[%s][%s]]" url file-name))
+      nil)))
+
 (comment
  (normalize-asset-resource-url "https://x.com/a.pdf")
  (normalize-asset-resource-url "./a/b.pdf")

+ 14 - 20
src/main/frontend/handler/editor.cljs

@@ -49,6 +49,7 @@
             [goog.dom :as gdom]
             [goog.dom.classes :as gdom-classes]
             [goog.object :as gobj]
+            [goog.crypt.base64 :as base64]
             [lambdaisland.glogi :as log]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.graph-parser.block :as gp-block]
@@ -61,7 +62,8 @@
             [logseq.graph-parser.util.page-ref :as page-ref]
             [promesa.core :as p]
             [rum.core :as rum]
-            [frontend.handler.db-based.property :as db-property-handler]))
+            [frontend.handler.db-based.property :as db-property-handler]
+            [frontend.fs.capacitor-fs :as capacitor-fs]))
 
 ;; FIXME: should support multiple images concurrently uploading
 
@@ -1361,19 +1363,6 @@
   (when restore?
     (commands/restore-state)))
 
-(defn get-asset-file-link
-  "Link text for inserting to markdown/org"
-  [format url file-name image?]
-  (let [pdf?   (and url (string/ends-with? (string/lower-case url) ".pdf"))
-        media? (and url (or (config/ext-of-audio? url)
-                            (config/ext-of-video? url)))]
-    (case (keyword format)
-      :markdown (util/format (str (when (or image? media? pdf?) "!") "[%s](%s)") file-name url)
-      :org (if image?
-             (util/format "[[%s]]" url)
-             (util/format "[[%s][%s]]" url file-name))
-      nil)))
-
 (defn- ensure-assets-dir!
   [repo]
   (p/let [repo-dir (config/get-repo-dir repo)
@@ -1391,7 +1380,7 @@
   "Save incoming(pasted) assets to assets directory.
 
    Returns: [file-rpath file-obj file-fpath matched-alias]"
-  ([_ repo files]
+  ([repo files]
    (p/let [[repo-dir assets-dir] (ensure-assets-dir! repo)]
      (save-assets! repo repo-dir assets-dir files
                    (fn [index file-stem]
@@ -1435,7 +1424,13 @@
                 (p/catch #(js/console.error "Debug: Copy Asset Error#" %))))
 
           (p/do! (js/console.debug "Debug: Writing Asset #" dir file-rpath)
-                 (fs/write-file! repo dir file-rpath (.stream file) nil)
+                 (if (mobile-util/native-platform?)
+                   ;; capacitor fs accepts Blob, File implements Blob
+                   (p/let [buffer (.arrayBuffer file)
+                           content (base64/encodeByteArray (js/Uint8Array. buffer))
+                           fpath (path/path-join dir file-rpath)]
+                     (capacitor-fs/<write-file-with-base64 fpath content))
+                   (fs/write-file! repo dir file-rpath (.stream file) nil))
                  [file-rpath file (path/path-join dir file-rpath) matched-alias])))))))
 
 (defonce *assets-url-cache (atom {}))
@@ -1517,11 +1512,10 @@
 (defn upload-asset
   "Paste asset and insert link to current editing block"
   [id ^js files format uploading? drop-or-paste?]
-  (let [repo (state/get-current-repo)
-        block (state/get-edit-block)]
+  (let [repo (state/get-current-repo)]
     (when (or (config/local-file-based-graph? repo)
               (config/db-based-graph? repo))
-      (-> (save-assets! block repo (js->clj files))
+      (-> (save-assets! repo (js->clj files))
           ;; FIXME: only the first asset is handled
           (p/then
            (fn [res]
@@ -1529,7 +1523,7 @@
                (let [image? (config/ext-of-image? asset-file-name)]
                  (insert-command!
                   id
-                  (get-asset-file-link format
+                  (assets-handler/get-asset-file-link format
                                        (if matched-alias
                                          (str
                                           (if image? "../assets/" "")

+ 7 - 6
src/main/frontend/mobile/camera.cljs

@@ -1,14 +1,15 @@
 (ns frontend.mobile.camera
   (:require ["@capacitor/camera" :refer [Camera CameraResultType]]
             ["@capacitor/filesystem" :refer [Filesystem]]
-            [lambdaisland.glogi :as log]
-            [promesa.core :as p]
+            [frontend.commands :as commands]
+            [frontend.date :as date]
+            [frontend.handler.assets :as assets-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.state :as state]
-            [frontend.date :as date]
-            [frontend.commands :as commands]
+            [frontend.util.cursor :as cursor]
             [goog.object :as gobj]
-            [frontend.util.cursor :as cursor]))
+            [lambdaisland.glogi :as log]
+            [promesa.core :as p]))
 
 (defn- take-or-choose-photo []
   (-> (.getPhoto Camera (clj->js
@@ -55,6 +56,6 @@
         (commands/simple-insert!
          id
          (str left-padding
-              (editor-handler/get-asset-file-link format (str "../assets/" filename) filename true)
+              (assets-handler/get-asset-file-link format (str "../assets/" filename) filename true)
               " ")
          {})))))

+ 3 - 2
src/main/frontend/mobile/intent.cljs

@@ -8,6 +8,7 @@
             [frontend.config :as config]
             [frontend.date :as date]
             [frontend.db :as db]
+            [frontend.handler.assets :as assets-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.handler.notification :as notification]
             [frontend.mobile.util :as mobile-util]
@@ -72,7 +73,7 @@
                  (fn [error]
                    (log/error :copy-file-error {:error error})))
           url (util/format "../assets/%s" basename)
-          url (editor-handler/get-asset-file-link format url label true)
+          url (assets-handler/get-asset-file-link format url label true)
           template (get-in (state/get-config)
                            [:quick-capture-templates :media]
                            "**{time}** [[quick capture]]: {url}")]
@@ -169,7 +170,7 @@
                  (fn [error]
                    (log/error :copy-file-error {:error error})))
           url (util/format "../assets/%s" basename)
-          url-link (editor-handler/get-asset-file-link format url label true)]
+          url-link (assets-handler/get-asset-file-link format url label true)]
     url-link))
 
 (defn- handle-payload-resource

+ 7 - 6
src/main/frontend/mobile/record.cljs

@@ -1,14 +1,15 @@
 (ns frontend.mobile.record
   (:require ["@capacitor/filesystem" :refer [Filesystem]]
             ["capacitor-voice-recorder" :refer [VoiceRecorder]]
-            [promesa.core :as p]
+            [clojure.string :as string]
+            [frontend.date :as date]
+            [frontend.db :as db]
+            [frontend.handler.assets :as assets-handler]
             [frontend.handler.editor :as editor-handler]
             [frontend.state :as state]
-            [frontend.date :as date]
-            [lambdaisland.glogi :as log]
             [frontend.util :as util]
-            [clojure.string :as string]
-            [frontend.db :as db]))
+            [lambdaisland.glogi :as log]
+            [promesa.core :as p]))
 
 (defn request-audio-recording-permission []
   (p/then
@@ -56,7 +57,7 @@
                    (log/error :file/write-failed {:path path
                                                   :error error})))
           url (util/format "../assets/%s" filename)
-          file-link (editor-handler/get-asset-file-link format url filename true)
+          file-link (assets-handler/get-asset-file-link format url filename true)
           args (merge (if (parse-uuid page)
                         {:block-uuid (uuid page)}
                         {:page page})