mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
fix(asset): handle external-url paths and plugin binary writes (#12656)
This commit is contained in:
@@ -562,7 +562,13 @@
|
||||
{:on-click (fn [e]
|
||||
(util/stop e)
|
||||
(let [repo-dir (config/get-repo-dir repo)
|
||||
file-fpath (path/path-join repo-dir (str "assets/" (:block/uuid asset-block) "." (name ext)))]
|
||||
ext-url (:logseq.property.asset/external-url asset-block)
|
||||
local-ext-url? (and (not (string/blank? ext-url))
|
||||
(common-config/local-relative-asset? ext-url))
|
||||
file-fpath (if local-ext-url?
|
||||
;; Plugin-sourced asset stored under assets/storages/<plugin-id>/...
|
||||
(path/path-join repo-dir (string/replace ext-url #"^[./]+" ""))
|
||||
(path/path-join repo-dir (str "assets/" (:block/uuid asset-block) "." (name ext))))]
|
||||
(js/window.apis.openPath file-fpath)))}
|
||||
file-name])
|
||||
|
||||
@@ -1113,13 +1119,19 @@
|
||||
img-placeholder (when image?
|
||||
[:div.img-placeholder.asset-container
|
||||
{:style img-metadata}])
|
||||
;; When external-url is set, use it as the render path so
|
||||
;; plugin-sandboxed assets (./assets/storages/<plugin-id>/...)
|
||||
;; resolve correctly; <make-asset-url handles both remote URLs
|
||||
;; and graph-root-relative paths.
|
||||
href (or (:logseq.property.asset/external-url block)
|
||||
(path/path-join (str "../" common-config/local-assets-dir) file))
|
||||
content (cond
|
||||
file-ready?
|
||||
(asset-link (assoc config
|
||||
:asset-block block
|
||||
:image-placeholder img-placeholder)
|
||||
(:block/title block)
|
||||
(path/path-join (str "../" common-config/local-assets-dir) file)
|
||||
href
|
||||
img-metadata
|
||||
nil)
|
||||
image?
|
||||
|
||||
@@ -356,7 +356,10 @@
|
||||
video? (contains? config/video-formats asset-type)
|
||||
pdf? (= :pdf asset-type)
|
||||
file-name (str (:block/uuid asset) "." asset-type-str)
|
||||
rel-path (path/path-join (str "../" common-config/local-assets-dir) file-name)]
|
||||
;; Prefer external-url so plugin-sandboxed assets resolve to their
|
||||
;; real on-disk path; mirrors the asset-cp render-side fix.
|
||||
rel-path (or (:logseq.property.asset/external-url asset)
|
||||
(path/path-join (str "../" common-config/local-assets-dir) file-name))]
|
||||
(cond
|
||||
image?
|
||||
(p/let [url (assets-handler/<make-asset-url rel-path)]
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
|
||||
(defn- schema-type-check!
|
||||
[type]
|
||||
(let [valid-types #{:default :number :date :datetime :checkbox :url :node :json :string}]
|
||||
(let [valid-types #{:default :number :date :datetime :checkbox :url :node :asset :json :string}]
|
||||
(when-not (contains? valid-types type)
|
||||
(throw (ex-info (str "Invalid type, type should be one of: " valid-types) {:type type})))))
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
|
||||
(defn upsert-property
|
||||
"schema:
|
||||
{:type :default | :number | :date | :datetime | :checkbox | :url | :node | :json | :string
|
||||
{:type :default | :number | :date | :datetime | :checkbox | :url | :node | :asset | :json | :string
|
||||
:cardinality :many | :one
|
||||
:hide? true
|
||||
:view-context :page
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
[electron.ipc :as ipc]
|
||||
[frontend.config :as config]
|
||||
[frontend.fs :as fs]
|
||||
[frontend.handler.assets :as assets-handler]
|
||||
[frontend.handler.command-palette :as palette-handler]
|
||||
[frontend.handler.common.plugin :as plugin-common-handler]
|
||||
[frontend.handler.plugin :as plugin-handler]
|
||||
@@ -88,6 +89,18 @@
|
||||
[plugin-id]
|
||||
(util/node-path.join "storages" (util/node-path.basename plugin-id)))
|
||||
|
||||
(defn- binary-content?
|
||||
"Detect payload shapes that can't be transit-serialized through ipc/ipc.
|
||||
Mirrors assets-handler/->uint8 — anything it accepts as binary, we route
|
||||
through writeFileBytes instead of write-plain-text-file!."
|
||||
[content]
|
||||
(or (instance? js/ArrayBuffer content)
|
||||
(instance? js/Uint8Array content)
|
||||
(and (exists? js/ArrayBuffer) (.isView js/ArrayBuffer content))
|
||||
(and (object? content)
|
||||
(= "Buffer" (aget content "type"))
|
||||
(array? (aget content "data")))))
|
||||
|
||||
(defn- write_rootdir_file
|
||||
[file content sub-root root-dir]
|
||||
(p/let [repo ""
|
||||
@@ -98,7 +111,13 @@
|
||||
user-path-root (util/node-path.dirname user-path)
|
||||
exist? (fs/file-exists? user-path-root "")
|
||||
_ (when-not exist? (fs/mkdir-recur! user-path-root))
|
||||
_ (fs/write-plain-text-file! repo nil user-path content {:skip-compare? true})]
|
||||
;; Binary content (ArrayBuffer/Uint8Array/...) can't survive
|
||||
;; transit serialization through ipc/ipc inside write-plain-text-file!,
|
||||
;; so on Electron we bypass to window.apis.writeFileBytes — same path
|
||||
;; the native fs/write-asset-file! uses for the same reason.
|
||||
_ (if (and (binary-content? content) (util/electron?))
|
||||
(js/window.apis.writeFileBytes user-path (assets-handler/->uint8 content))
|
||||
(fs/write-plain-text-file! repo nil user-path content {:skip-compare? true}))]
|
||||
user-path))
|
||||
|
||||
(defn write_dotdir_file
|
||||
|
||||
Reference in New Issue
Block a user