fix(editor): not being about to save dropped assets

- Refactor: mv get-asset-file-link to assets-handler
- Fix: iOS binary file saving using base64
- Fix: Drop assets on non-editing block
pull/10389/head
Andelf 2023-10-14 00:19:55 +08:00
parent c996bfe658
commit fc653c9f05
7 changed files with 96 additions and 45 deletions

View File

@ -78,7 +78,8 @@
[rum.core :as rum] [rum.core :as rum]
[shadow.loader :as loader] [shadow.loader :as loader]
[datascript.impl.entity :as e] [datascript.impl.entity :as e]
[logseq.common.path :as path])) [logseq.common.path :as path]
[frontend.handler.page :as page-handler]))
@ -2629,6 +2630,7 @@
(editor-handler/unhighlight-blocks!))) (editor-handler/unhighlight-blocks!)))
(defn- block-drop (defn- block-drop
"Block on-drop handler"
[^js 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)
@ -2637,15 +2639,53 @@
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]) blocks (if (seq selected) selected [@*dragging-block])
blocks (remove-nils blocks)] blocks (remove-nils blocks)]
(if-not (seq blocks) (if (seq blocks)
(when-let [text (.getData (.-dataTransfer event) "text/plain")] ;; dnd block moving in current Logseq instance
(editor-handler/api-insert-new-block! (dnd/move-blocks event blocks target-block @*move-to)
text ;; handle DataTransfer
{:block-uuid uuid (let [repo (state/get-current-repo)
:edit-block? false data-transfer (.-dataTransfer event)
:sibling? (= @*move-to :sibling) transfer-types (js->clj (.-types data-transfer))
:before? (= @*move-to :top)})) transfer-type (first transfer-types)]
(dnd/move-blocks event blocks target-block @*move-to)))) (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)}))
(= transfer-type "Files")
(let [files (.-files data-transfer)
format (:block/format target-block)]
(when (config/local-db? repo)
;; 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
:sibling? (= @*move-to :sibling)
:before? (= @*move-to :top)}))))))))
:else
(prn ::unhandled-drop-data-transfer-type transfer-types)))
)))
(block-drag-end event *move-to)) (block-drag-end event *move-to))
(defn- block-mouse-over (defn- block-mouse-over

View File

@ -66,7 +66,7 @@
(defn save-asset-handler (defn save-asset-handler
[file] [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 (p/then
(fn [res] (fn [res]
(when-let [[asset-file-name _ full-file-path] (and (seq res) (first res))] (when-let [[asset-file-name _ full-file-path] (and (seq res) (first res))]

View File

@ -113,6 +113,19 @@
(get-alias-dirs))] (get-alias-dirs))]
alias))) 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 (comment
(normalize-asset-resource-url "https://x.com/a.pdf") (normalize-asset-resource-url "https://x.com/a.pdf")
(normalize-asset-resource-url "./a/b.pdf") (normalize-asset-resource-url "./a/b.pdf")

View File

@ -46,6 +46,7 @@
[goog.dom :as gdom] [goog.dom :as gdom]
[goog.dom.classes :as gdom-classes] [goog.dom.classes :as gdom-classes]
[goog.object :as gobj] [goog.object :as gobj]
[goog.crypt.base64 :as base64]
[lambdaisland.glogi :as log] [lambdaisland.glogi :as log]
[logseq.db.schema :as db-schema] [logseq.db.schema :as db-schema]
[logseq.graph-parser.block :as gp-block] [logseq.graph-parser.block :as gp-block]
@ -57,7 +58,8 @@
[logseq.graph-parser.util.block-ref :as block-ref] [logseq.graph-parser.util.block-ref :as block-ref]
[logseq.graph-parser.util.page-ref :as page-ref] [logseq.graph-parser.util.page-ref :as page-ref]
[promesa.core :as p] [promesa.core :as p]
[rum.core :as rum])) [rum.core :as rum]
[frontend.fs.capacitor-fs :as capacitor-fs]))
;; FIXME: should support multiple images concurrently uploading ;; FIXME: should support multiple images concurrently uploading
@ -1375,19 +1377,6 @@
(when restore? (when restore?
(commands/restore-state))) (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! (defn- ensure-assets-dir!
[repo] [repo]
(p/let [repo-dir (config/get-repo-dir repo) (p/let [repo-dir (config/get-repo-dir repo)
@ -1405,7 +1394,7 @@
"Save incoming(pasted) assets to assets directory. "Save incoming(pasted) assets to assets directory.
Returns: [file-rpath file-obj file-fpath matched-alias]" Returns: [file-rpath file-obj file-fpath matched-alias]"
([_ repo files] ([repo files]
(p/let [[repo-dir assets-dir] (ensure-assets-dir! repo)] (p/let [[repo-dir assets-dir] (ensure-assets-dir! repo)]
(save-assets! repo repo-dir assets-dir files (save-assets! repo repo-dir assets-dir files
(fn [index file-stem] (fn [index file-stem]
@ -1449,7 +1438,13 @@
(p/catch #(js/console.error "Debug: Copy Asset Error#" %)))) (p/catch #(js/console.error "Debug: Copy Asset Error#" %))))
(p/do! (js/console.debug "Debug: Writing Asset #" dir file-rpath) (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]))))))) [file-rpath file (path/path-join dir file-rpath) matched-alias])))))))
(defonce *assets-url-cache (atom {})) (defonce *assets-url-cache (atom {}))
@ -1531,10 +1526,10 @@
(defn upload-asset (defn upload-asset
"Paste asset and insert link to current editing block" "Paste asset and insert link to current editing block"
[id ^js files format uploading? drop-or-paste?] [id ^js files format uploading? drop-or-paste?]
(let [repo (state/get-current-repo) (let [repo (state/get-current-repo)]
block (state/get-edit-block)] (prn ::upload-asset id)
(when (config/local-db? repo) (when (config/local-db? repo)
(-> (save-assets! block repo (js->clj files)) (-> (save-assets! repo (js->clj files))
;; FIXME: only the first asset is handled ;; FIXME: only the first asset is handled
(p/then (p/then
(fn [res] (fn [res]
@ -1542,7 +1537,7 @@
(let [image? (config/ext-of-image? asset-file-name)] (let [image? (config/ext-of-image? asset-file-name)]
(insert-command! (insert-command!
id id
(get-asset-file-link format (assets-handler/get-asset-file-link format
(if matched-alias (if matched-alias
(str (str
(if image? "../assets/" "") (if image? "../assets/" "")

View File

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

View File

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

View File

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