| 
					
				 | 
			
			
				@@ -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))))))))) 
			 |