mirror of
https://github.com/logseq/logseq.git
synced 2026-05-03 02:16:30 +00:00
Enhance/pdf improvements (#6475)
Full-text search, highlights and assets alias support
It also exposes a plugin API for highlight context menu
```ts
/**
* Current it's only available for pdf viewer
* @param label - displayed name of command
* @param action - callback for the clickable item
* @param opts - clearSelection: clear highlight selection when callback invoked
*/
registerHighlightContextMenuItem: (
label: string,
action: SimpleCommandCallback,
opts?: {
clearSelection: boolean
}
) => unknown
```
This commit is contained in:
@@ -7,10 +7,11 @@
|
||||
[frontend.fs :as fs]
|
||||
[frontend.handler.editor :as editor-handler]
|
||||
[frontend.handler.page :as page-handler]
|
||||
[frontend.handler.assets :as assets-handler]
|
||||
[frontend.util.page-property :as page-property]
|
||||
[frontend.state :as state]
|
||||
[frontend.util :as util]
|
||||
[logseq.graph-parser.util :as gp-util]
|
||||
[frontend.extensions.pdf.utils :as pdf-utils]
|
||||
[logseq.graph-parser.config :as gp-config]
|
||||
[logseq.graph-parser.util.block-ref :as block-ref]
|
||||
[medley.core :as medley]
|
||||
@@ -18,46 +19,16 @@
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(def HLS-PREFIX "hls__")
|
||||
|
||||
(def HLS-PREFIX-DISPLAY "📒")
|
||||
|
||||
(def HLS-PREFIX-LEN (count HLS-PREFIX))
|
||||
|
||||
(def HLS-PREFIX-PATTERN (re-pattern (str "^" HLS-PREFIX)))
|
||||
|
||||
(defn make-hls
|
||||
[name]
|
||||
(str HLS-PREFIX name))
|
||||
|
||||
(defn hls-page?
|
||||
[title]
|
||||
(and title (string? title) (string/starts-with? title HLS-PREFIX)))
|
||||
(defn hls-file?
|
||||
[filename]
|
||||
(and filename (string? filename) (string/starts-with? filename "hls__")))
|
||||
|
||||
(defn inflate-asset
|
||||
[full-path]
|
||||
(let [filename (util/node-path.basename full-path)
|
||||
web-link? (string/starts-with? full-path "http")
|
||||
[original-path]
|
||||
(let [filename (util/node-path.basename original-path)
|
||||
web-link? (string/starts-with? original-path "http")
|
||||
ext-name (util/get-file-ext filename)
|
||||
url (cond
|
||||
web-link?
|
||||
full-path
|
||||
|
||||
(util/absolute-path? full-path)
|
||||
(str "file://" full-path)
|
||||
|
||||
(string/starts-with? full-path "file:/")
|
||||
full-path
|
||||
|
||||
:else
|
||||
(let [full-path (string/replace full-path #"^[.\/\\]+" "")
|
||||
full-path (if-not (string/starts-with? full-path gp-config/local-assets-dir)
|
||||
(util/node-path.join gp-config/local-assets-dir full-path)
|
||||
full-path)]
|
||||
(str "file://" ;; TODO: bfs
|
||||
(util/node-path.join
|
||||
(config/get-repo-dir (state/get-current-repo))
|
||||
full-path))))]
|
||||
url (assets-handler/normalize-asset-resource-url original-path)]
|
||||
(when-let [key
|
||||
(if web-link?
|
||||
(str (hash url))
|
||||
@@ -68,7 +39,14 @@
|
||||
:identity (subs key (- (count key) 15))
|
||||
:filename filename
|
||||
:url url
|
||||
:hls-file (str "assets/" key ".edn")})))
|
||||
:hls-file (str "assets/" key ".edn")
|
||||
:original-path original-path})))
|
||||
|
||||
(defn resolve-area-image-file
|
||||
[img-stamp current {:keys [page id] :as _hl}]
|
||||
(when-let [key (:key current)]
|
||||
(-> (str gp-config/local-assets-dir "/" key "/")
|
||||
(str (util/format "%s_%s_%s.png" page id img-stamp)))))
|
||||
|
||||
(defn load-hls-data$
|
||||
[{:keys [hls-file]}]
|
||||
@@ -144,12 +122,14 @@
|
||||
(.toBlob canvas' callback))
|
||||
))))
|
||||
|
||||
(defn update-hl-area-block!
|
||||
(defn update-hl-block!
|
||||
[highlight]
|
||||
(when-let [block (and (area-highlight? highlight)
|
||||
(db-model/get-block-by-uuid (:id highlight)))]
|
||||
(editor-handler/set-block-property!
|
||||
(:block/uuid block) :hl-stamp (get-in highlight [:content :image]))))
|
||||
(when-let [block (db-model/get-block-by-uuid (:id highlight))]
|
||||
(doseq [[k v] {:hl-stamp (if (area-highlight? highlight)
|
||||
(get-in highlight [:content :image])
|
||||
(js/Date.now))
|
||||
:hl-color (get-in highlight [:properties :color])}]
|
||||
(editor-handler/set-block-property! (:block/uuid block) k v))))
|
||||
|
||||
(defn unlink-hl-area-image$
|
||||
[^js _viewer current hl]
|
||||
@@ -167,15 +147,15 @@
|
||||
[pdf-current]
|
||||
(let [page-name (:key pdf-current)
|
||||
page-name (string/trim page-name)
|
||||
page-name (make-hls page-name)
|
||||
page (db-model/get-page page-name)
|
||||
url (:url pdf-current)
|
||||
format (state/get-preferred-format)
|
||||
repo-dir (config/get-repo-dir (state/get-current-repo))
|
||||
page-name (str "hls__" page-name)
|
||||
page (db-model/get-page page-name)
|
||||
file-path (:original-path pdf-current)
|
||||
format (state/get-preferred-format)
|
||||
repo-dir (config/get-repo-dir (state/get-current-repo))
|
||||
asset-dir (util/node-path.join repo-dir gp-config/local-assets-dir)
|
||||
url (if (string/includes? url asset-dir)
|
||||
(str ".." (last (string/split url repo-dir)))
|
||||
url)]
|
||||
url (if (string/includes? file-path asset-dir)
|
||||
(str ".." (last (string/split file-path repo-dir)))
|
||||
file-path)]
|
||||
(if-not page
|
||||
(let [label (:filename pdf-current)]
|
||||
(page-handler/create! page-name {:redirect? false :create-first-block? false
|
||||
@@ -196,26 +176,28 @@
|
||||
(page-property/add-property! page-name :file-path url))
|
||||
page))
|
||||
|
||||
(defn create-ref-block!
|
||||
[{:keys [id content page]}]
|
||||
(when-let [pdf-current (:pdf/current @state/state)]
|
||||
(when-let [ref-page (resolve-ref-page pdf-current)]
|
||||
(if-let [ref-block (db-model/get-block-by-uuid id)]
|
||||
(do
|
||||
(js/console.debug "[existed ref block]" ref-block)
|
||||
ref-block)
|
||||
(let [text (:text content)
|
||||
wrap-props #(if-let [stamp (:image content)]
|
||||
(assoc % :hl-type "area" :hl-stamp stamp) %)]
|
||||
(defn ensure-ref-block!
|
||||
([pdf hl] (ensure-ref-block! pdf hl nil))
|
||||
([pdf-current {:keys [id content page properties]} insert-opts]
|
||||
(when-let [ref-page (and pdf-current (resolve-ref-page pdf-current))]
|
||||
(if-let [ref-block (db-model/query-block-by-uuid id)]
|
||||
(do
|
||||
(println "[existed ref block]" ref-block)
|
||||
ref-block)
|
||||
(let [text (:text content)
|
||||
wrap-props #(if-let [stamp (:image content)]
|
||||
(assoc % :hl-type "area" :hl-stamp stamp) %)]
|
||||
|
||||
(editor-handler/api-insert-new-block!
|
||||
text {:page (:block/name ref-page)
|
||||
:custom-uuid id
|
||||
:properties (wrap-props
|
||||
{:ls-type "annotation"
|
||||
:hl-page page
|
||||
;; force custom uuid
|
||||
:id (str id)})}))))))
|
||||
(editor-handler/api-insert-new-block!
|
||||
text (merge {:page (:block/name ref-page)
|
||||
:custom-uuid id
|
||||
:properties (wrap-props
|
||||
{:ls-type "annotation"
|
||||
:hl-page page
|
||||
:hl-color (:color properties)
|
||||
;; force custom uuid
|
||||
:id (str id)})}
|
||||
insert-opts)))))))
|
||||
|
||||
(defn del-ref-block!
|
||||
[{:keys [id]}]
|
||||
@@ -226,7 +208,7 @@
|
||||
|
||||
(defn copy-hl-ref!
|
||||
[highlight]
|
||||
(when-let [ref-block (create-ref-block! highlight)]
|
||||
(when-let [ref-block (ensure-ref-block! (state/get-current-pdf) highlight)]
|
||||
(util/copy-to-clipboard! (block-ref/->block-ref (:block/uuid ref-block)))))
|
||||
|
||||
(defn open-block-ref!
|
||||
@@ -235,10 +217,10 @@
|
||||
page (db-utils/pull (:db/id (:block/page block)))
|
||||
page-name (:block/original-name page)
|
||||
file-path (:file-path (:block/properties page))]
|
||||
(when-let [target-key (and page-name (subs page-name HLS-PREFIX-LEN))]
|
||||
(when-let [target-key (and page-name (subs page-name 5))]
|
||||
(p/let [hls (resolve-hls-data-by-key$ target-key)
|
||||
hls (and hls (:highlights hls))]
|
||||
(let [file-path (if file-path file-path (str target-key ".pdf"))]
|
||||
(let [file-path (or file-path (str "../assets/" target-key ".pdf"))]
|
||||
(if-let [matched (and hls (medley/find-first #(= id (:id %)) hls))]
|
||||
(do
|
||||
(state/set-state! :pdf/ref-highlight matched)
|
||||
@@ -247,47 +229,44 @@
|
||||
(js/console.debug "[Unmatched highlight ref]" block)))))))
|
||||
|
||||
(defn goto-block-ref!
|
||||
[{:keys [id]}]
|
||||
[{:keys [id] :as hl}]
|
||||
(when id
|
||||
(ensure-ref-block!
|
||||
(state/get-current-pdf) hl {:edit-block? false})
|
||||
(rfe/push-state :page {:name (str id)})))
|
||||
|
||||
(defn goto-annotations-page!
|
||||
([current] (goto-annotations-page! current nil))
|
||||
([current id]
|
||||
(when-let [name (:key current)]
|
||||
(rfe/push-state :page {:name (make-hls name)} (if id {:anchor (str "block-content-" + id)} nil)))))
|
||||
(rfe/push-state :page {:name (str "hls__" name)} (if id {:anchor (str "block-content-" + id)} nil)))))
|
||||
|
||||
(rum/defc area-display
|
||||
[block stamp]
|
||||
(let [id (:block/uuid block)
|
||||
props (:block/properties block)]
|
||||
(when-let [page (db-utils/pull (:db/id (:block/page block)))]
|
||||
(when-let [group-key (string/replace-first (:block/original-name page) HLS-PREFIX-PATTERN "")]
|
||||
(when-let [hl-page (:hl-page props)]
|
||||
(let [encoded-chars? (boolean (re-find gp-util/url-encoded-pattern group-key))
|
||||
group-key (if encoded-chars? (js/encodeURI group-key) group-key)
|
||||
asset-path (editor-handler/make-asset-url
|
||||
(str "/" gp-config/local-assets-dir "/" group-key "/" (str hl-page "_" id "_" stamp ".png")))]
|
||||
[:span.hl-area
|
||||
[:img {:src asset-path}]]))))))
|
||||
[block]
|
||||
(when-let [asset-path' (and block (pdf-utils/get-area-block-asset-url
|
||||
block (db-utils/pull (:db/id (:block/page block)))))]
|
||||
(let [asset-path (editor-handler/make-asset-url asset-path')]
|
||||
[:span.hl-area
|
||||
[:img {:src asset-path}]])))
|
||||
|
||||
(defn fix-local-asset-pagename
|
||||
[title]
|
||||
(when-not (string/blank? title)
|
||||
(let [local-asset? (re-find #"[0-9]{13}_\d$" title)]
|
||||
(if local-asset?
|
||||
(-> title
|
||||
(subs 0 (- (count title) 15))
|
||||
(string/replace HLS-PREFIX-PATTERN HLS-PREFIX-DISPLAY)
|
||||
[filename]
|
||||
(when-not (string/blank? filename)
|
||||
(let [local-asset? (re-find #"[0-9]{13}_\d$" filename)
|
||||
hls? (re-find #"^hls__" filename)
|
||||
len (count filename)]
|
||||
(if (or local-asset? hls?)
|
||||
(-> filename
|
||||
(subs 0 (if local-asset? (- len 15) len))
|
||||
(string/replace #"^hls__" "")
|
||||
(string/replace "_" " ")
|
||||
(string/trimr))
|
||||
(-> title
|
||||
(string/replace HLS-PREFIX-PATTERN HLS-PREFIX-DISPLAY)
|
||||
(gp-util/safe-url-decode)) ;; In case user import URI pdf resource like #6167
|
||||
))))
|
||||
filename))))
|
||||
|
||||
(rum/defc human-hls-pagename-display
|
||||
"Ensure it's a hls page by `hls-page?` before hand"
|
||||
[title]
|
||||
[:a.asset-ref
|
||||
(fix-local-asset-pagename title)])
|
||||
(defn human-page-name
|
||||
[page-name]
|
||||
(cond
|
||||
(string/starts-with? page-name "hls__")
|
||||
(fix-local-asset-pagename page-name)
|
||||
|
||||
:else (util/trim-safe page-name)))
|
||||
|
||||
Reference in New Issue
Block a user