|
|
@@ -1,13 +1,16 @@
|
|
|
(ns ^:no-doc frontend.handler.assets
|
|
|
- (:require [frontend.state :as state]
|
|
|
- [medley.core :as medley]
|
|
|
- [frontend.util :as util]
|
|
|
+ (:require [clojure.string :as string]
|
|
|
[frontend.config :as config]
|
|
|
+ [frontend.fs :as fs]
|
|
|
+ [frontend.fs.nfs :as nfs]
|
|
|
[frontend.mobile.util :as mobile-util]
|
|
|
+ [frontend.state :as state]
|
|
|
+ [frontend.util :as util]
|
|
|
[logseq.common.config :as common-config]
|
|
|
- [clojure.string :as string]
|
|
|
[logseq.common.path :as path]
|
|
|
- [logseq.common.util :as common-util]))
|
|
|
+ [logseq.common.util :as common-util]
|
|
|
+ [medley.core :as medley]
|
|
|
+ [promesa.core :as p]))
|
|
|
|
|
|
(defn alias-enabled?
|
|
|
[]
|
|
|
@@ -127,8 +130,70 @@
|
|
|
(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")
|
|
|
- (normalize-asset-resource-url "assets/a/b.pdf")
|
|
|
- (normalize-asset-resource-url "@图书/a/b.pdf"))
|
|
|
+(defn <make-data-url
|
|
|
+ [path]
|
|
|
+ (let [repo-dir (config/get-repo-dir (state/get-current-repo))]
|
|
|
+ (p/let [binary (fs/read-file repo-dir path {})
|
|
|
+ blob (js/Blob. (array binary) (clj->js {:type "image"}))]
|
|
|
+ (when blob (js/URL.createObjectURL blob)))))
|
|
|
+
|
|
|
+(defn <expand-assets-links-for-db-graph
|
|
|
+ "Expand ../assets/ links in custom.css file to blob url.
|
|
|
+
|
|
|
+ Only for db-based graph"
|
|
|
+ [css]
|
|
|
+ (let [rel-paths (re-seq #"\(['\"]?(\.\./assets/.*?)['\"]?\)" css)
|
|
|
+ rel-paths (vec (set (map second rel-paths)))
|
|
|
+ fixed-rel-paths (map (fn [p] (path/path-join "./logseq/" p)) rel-paths)]
|
|
|
+ (p/let [blob-urls (p/all (map <make-data-url fixed-rel-paths))]
|
|
|
+ (reduce (fn [css [rel-path blob-url]]
|
|
|
+ (string/replace css rel-path (str "'" blob-url "'")))
|
|
|
+ css
|
|
|
+ (map vector rel-paths blob-urls)))))
|
|
|
+
|
|
|
+(defonce *assets-url-cache (atom {}))
|
|
|
+
|
|
|
+(defn make-asset-url
|
|
|
+ "Make asset URL for UI element, to fill img.src"
|
|
|
+ [path] ;; path start with "/assets"(editor) or compatible for "../assets"(whiteboards)
|
|
|
+ (if config/publishing?
|
|
|
+ ;; Relative path needed since assets are not under '/' if published graph is not under '/'
|
|
|
+ (string/replace-first path #"^/" "")
|
|
|
+ (let [repo (state/get-current-repo)
|
|
|
+ repo-dir (config/get-repo-dir repo)
|
|
|
+ ;; Hack for path calculation
|
|
|
+ path (string/replace path #"^(\.\.)?/" "./")
|
|
|
+ full-path (path/path-join repo-dir path)
|
|
|
+ data-url? (string/starts-with? path "data:")]
|
|
|
+ (cond
|
|
|
+ data-url?
|
|
|
+ path ;; just return the original
|
|
|
+
|
|
|
+ (and (alias-enabled?)
|
|
|
+ (check-alias-path? path))
|
|
|
+ (resolve-asset-real-path-url (state/get-current-repo) path)
|
|
|
+
|
|
|
+ (util/electron?)
|
|
|
+ (path/prepend-protocol "assets:" full-path)
|
|
|
+
|
|
|
+ (mobile-util/native-platform?)
|
|
|
+ (mobile-util/convert-file-src full-path)
|
|
|
+
|
|
|
+ (config/db-based-graph? (state/get-current-repo)) ; memory fs
|
|
|
+ (p/let [binary (fs/read-file repo-dir path {})
|
|
|
+ blob (js/Blob. (array binary) (clj->js {:type "image"}))]
|
|
|
+ (when blob (js/URL.createObjectURL blob)))
|
|
|
+
|
|
|
+ :else ;; nfs
|
|
|
+ (let [handle-path (str "handle/" full-path)
|
|
|
+ cached-url (get @*assets-url-cache (keyword handle-path))]
|
|
|
+ (if cached-url
|
|
|
+ (p/resolved cached-url)
|
|
|
+ ;; Loading File from handle cache
|
|
|
+ ;; Use await file handle, to ensure all handles are loaded.
|
|
|
+ (p/let [handle (nfs/await-get-nfs-file-handle repo handle-path)
|
|
|
+ file (and handle (.getFile handle))]
|
|
|
+ (when file
|
|
|
+ (p/let [url (js/URL.createObjectURL file)]
|
|
|
+ (swap! *assets-url-cache assoc (keyword handle-path) url)
|
|
|
+ url)))))))))
|