Просмотр исходного кода

fix(pdf): not persist highlights data when load hls file error

charlie 3 лет назад
Родитель
Сommit
6d210e6371

+ 43 - 41
src/main/frontend/extensions/pdf/assets.cljs

@@ -56,8 +56,8 @@
   (when hls-file
     (let [repo-cur (state/get-current-repo)
           repo-dir (config/get-repo-dir repo-cur)]
-      (p/let [_ (fs/create-if-not-exists repo-cur repo-dir hls-file "{:highlights []}")
-              res (fs/read-file repo-dir hls-file)
+      (p/let [_    (fs/create-if-not-exists repo-cur repo-dir hls-file "{:highlights []}")
+              res  (fs/read-file repo-dir hls-file)
               data (if res (reader/read-string res) {})]
         data))))
 
@@ -66,7 +66,7 @@
   (when hls-file
     (let [repo-cur (state/get-current-repo)
           repo-dir (config/get-repo-dir repo-cur)
-          data (pr-str {:highlights highlights :extra extra})]
+          data     (pr-str {:highlights highlights :extra extra})]
       (fs/write-file! repo-cur repo-dir hls-file data {:skip-compare? true}))))
 
 (defn resolve-hls-data-by-key$
@@ -82,13 +82,13 @@
 (defn persist-hl-area-image$
   [^js viewer current new-hl old-hl {:keys [top left width height]}]
   (when-let [^js canvas (and (:key current) (.-canvas (.getPageView viewer (dec (:page new-hl)))))]
-    (let [^js doc (.-ownerDocument canvas)
+    (let [^js doc     (.-ownerDocument canvas)
           ^js canvas' (.createElement doc "canvas")
-          dpr js/window.devicePixelRatio
-          repo-cur (state/get-current-repo)
-          repo-dir (config/get-repo-dir repo-cur)
-          dw (* dpr width)
-          dh (* dpr height)]
+          dpr         js/window.devicePixelRatio
+          repo-cur    (state/get-current-repo)
+          repo-dir    (config/get-repo-dir repo-cur)
+          dw          (* dpr width)
+          dh          (* dpr height)]
 
       (set! (. canvas' -width) dw)
       (set! (. canvas' -height) dh)
@@ -96,31 +96,31 @@
       (when-let [^js ctx (.getContext canvas' "2d" #js{:alpha false})]
         (set! (. ctx -imageSmoothingEnabled) false)
         (.drawImage
-          ctx canvas
-          (* left dpr) (* top dpr) (* width dpr) (* height dpr)
-          0 0 dw dh)
+         ctx canvas
+         (* left dpr) (* top dpr) (* width dpr) (* height dpr)
+         0 0 dw dh)
 
         (let [callback (fn [^js png]
                          ;; write image file
                          (p/catch
-                           (p/let [_ (js/console.time :write-area-image)
-                                   ^js png (.arrayBuffer png)
-                                   {:keys [key]} current
-                                   ;; dir
-                                   fstamp (get-in new-hl [:content :image])
-                                   old-fstamp (and old-hl (get-in old-hl [:content :image]))
-                                   fname (str (:page new-hl) "_" (:id new-hl))
-                                   fdir (str gp-config/local-assets-dir "/" key)
-                                   _ (fs/mkdir-if-not-exists (str repo-dir "/" fdir))
-                                   new-fpath (str fdir "/" fname "_" fstamp ".png")
-                                   old-fpath (and old-fstamp (str fdir "/" fname "_" old-fstamp ".png"))
-                                   _ (and old-fpath (apply fs/rename! repo-cur (map #(util/node-path.join repo-dir %) [old-fpath new-fpath])))
-                                   _ (fs/write-file! repo-cur repo-dir new-fpath png {:skip-compare? true})]
-
-                             (js/console.timeEnd :write-area-image))
-
-                           (fn [err]
-                             (js/console.error "[write area image Error]" err))))]
+                          (p/let [_          (js/console.time :write-area-image)
+                                  ^js png    (.arrayBuffer png)
+                                  {:keys [key]} current
+                                  ;; dir
+                                  fstamp     (get-in new-hl [:content :image])
+                                  old-fstamp (and old-hl (get-in old-hl [:content :image]))
+                                  fname      (str (:page new-hl) "_" (:id new-hl))
+                                  fdir       (str gp-config/local-assets-dir "/" key)
+                                  _          (fs/mkdir-if-not-exists (str repo-dir "/" fdir))
+                                  new-fpath  (str fdir "/" fname "_" fstamp ".png")
+                                  old-fpath  (and old-fstamp (str fdir "/" fname "_" old-fstamp ".png"))
+                                  _          (and old-fpath (apply fs/rename! repo-cur (map #(util/node-path.join repo-dir %) [old-fpath new-fpath])))
+                                  _          (fs/write-file! repo-cur repo-dir new-fpath png {:skip-compare? true})]
+
+                            (js/console.timeEnd :write-area-image))
+
+                          (fn [err]
+                            (js/console.error "[write area image Error]" err))))]
 
           (.toBlob canvas' callback))
         ))))
@@ -139,10 +139,10 @@
   (when-let [fkey (and (area-highlight? hl) (:key current))]
     (let [repo-cur (state/get-current-repo)
           repo-dir (config/get-repo-dir repo-cur)
-          fstamp (get-in hl [:content :image])
-          fname (str (:page hl) "_" (:id hl))
-          fdir (str gp-config/local-assets-dir "/" fkey)
-          fpath (util/node-path.join repo-dir (str fdir "/" fname "_" fstamp ".png"))]
+          fstamp   (get-in hl [:content :image])
+          fname    (str (:page hl) "_" (:id hl))
+          fdir     (str gp-config/local-assets-dir "/" fkey)
+          fpath    (util/node-path.join repo-dir (str fdir "/" fname "_" fstamp ".png"))]
 
       (fs/unlink! repo-cur fpath {}))))
 
@@ -218,15 +218,17 @@
 
 (defn open-block-ref!
   [block]
-  (let [id (:block/uuid block)
-        page (db-utils/pull (:db/id (:block/page block)))
+  (let [id        (:block/uuid block)
+        page      (db-utils/pull (:db/id (:block/page block)))
         page-name (:block/original-name page)
-        file-path (:file-path (:block/properties page))]
+        file-path (:file-path (:block/properties page))
+        hl-page   (:hl-page (:block/properties block))]
     (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 (or file-path (str "../assets/" target-key ".pdf"))]
-          (if-let [matched (and hls (medley/find-first #(= id (:id %)) hls))]
+          (if-let [matched (or (and hls (medley/find-first #(= id (:id %)) hls))
+                               (and hl-page {:page hl-page}))]
             (do
               (state/set-state! :pdf/ref-highlight matched)
               ;; open pdf viewer
@@ -252,7 +254,7 @@
         images (to-array images)
         images (if-not (= (count images) 1)
                  (let [^js image (.closest (.-target e) ".hl-area")
-                       image (. image querySelector "img")]
+                       image     (. image querySelector "img")]
                    (->> images
                         (sort-by (juxt #(.-y %) #(.-x %)))
                         (split-with (complement #{image}))
@@ -260,8 +262,8 @@
                         (apply concat)))
                  images)
         images (for [^js it images] {:src (.-src it)
-                                     :w (.-naturalWidth it)
-                                     :h (.-naturalHeight it)})]
+                                     :w   (.-naturalWidth it)
+                                     :h   (.-naturalHeight it)})]
 
     (when (seq images)
       (lightbox/preview-images! images))))

+ 78 - 61
src/main/frontend/extensions/pdf/highlights.cljs

@@ -35,8 +35,15 @@
     (when viewer
       (when-let [ref-hl (state/sub :pdf/ref-highlight)]
         ;; delay handle: aim to fix page blink
-        (js/setTimeout #(pdf-utils/scroll-to-highlight viewer ref-hl) (if @*mounted? 50 500))
-        (js/setTimeout #(state/set-state! :pdf/ref-highlight nil) 1000)))
+        (js/setTimeout
+         (fn []
+           (if (:id ref-hl)
+             (pdf-utils/scroll-to-highlight viewer ref-hl)
+             (set! (.-currentPageNumber viewer) (or (:page ref-hl) 1))))
+         (if @*mounted? 50 500))
+
+        (js/setTimeout
+         #(state/set-state! :pdf/ref-highlight nil) 1000)))
     (reset! *mounted? true)))
 
 (rum/defc pdf-page-finder < rum/static
@@ -121,7 +128,7 @@
         action-fn!  (fn [action clear?]
                       (when-let [action (and action (name action))]
                         (let [highlight (if (fn? highlight) (highlight) highlight)
-                              content (:content highlight)]
+                              content   (:content highlight)]
                           (case action
                             "ref"
                             (pdf-assets/copy-hl-ref! highlight)
@@ -249,15 +256,15 @@
   [^js viewer vw-hl hl {:keys [show-ctx-menu! upd-hl!]}]
 
   (let [{:keys [id]} hl
-        *el    (rum/use-ref nil)
-        *dirty (rum/use-ref nil)
-        open-ctx-menu! (fn [^js/MouseEvent e]
-                         (.preventDefault e)
-                         (when-not (rum/deref *dirty)
-                           (let [x (.-clientX e)
-                                 y (.-clientY e)]
+        *el               (rum/use-ref nil)
+        *dirty            (rum/use-ref nil)
+        open-ctx-menu!    (fn [^js/MouseEvent e]
+                            (.preventDefault e)
+                            (when-not (rum/deref *dirty)
+                              (let [x (.-clientX e)
+                                    y (.-clientY e)]
 
-                             (show-ctx-menu! viewer hl {:x x :y y}))))
+                                (show-ctx-menu! viewer hl {:x x :y y}))))
 
         dragstart-handle! (fn [^js e]
                             (when-let [^js dt (and id (.-dataTransfer e))]
@@ -495,43 +502,43 @@
 (rum/defc ^:large-vars/cleanup-todo pdf-highlights
   [^js el ^js viewer initial-hls loaded-pages {:keys [set-dirty-hls!]}]
 
-  (let [^js doc        (.-ownerDocument el)
-        ^js win        (.-defaultView doc)
-        *mounted       (rum/use-ref false)
+  (let [^js doc         (.-ownerDocument el)
+        ^js win         (.-defaultView doc)
+        *mounted        (rum/use-ref false)
         [sel-state, set-sel-state!] (rum/use-state {:selection nil :range nil :collapsed nil :point nil})
         [highlights, set-highlights!] (rum/use-state initial-hls)
         [ctx-menu-state, set-ctx-menu-state!] (rum/use-state {:highlight nil :vw-pos nil :selection nil :point nil :reset-fn nil})
 
         clear-ctx-menu! (rum/use-callback
-                        #(let [reset-fn (:reset-fn ctx-menu-state)]
-                           (set-ctx-menu-state! {})
-                           (and (fn? reset-fn) (reset-fn)))
-                        [ctx-menu-state])
+                         #(let [reset-fn (:reset-fn ctx-menu-state)]
+                            (set-ctx-menu-state! {})
+                            (and (fn? reset-fn) (reset-fn)))
+                         [ctx-menu-state])
 
         show-ctx-menu!  (fn [^js viewer hl point & ops]
-                         (let [vw-pos (pdf-utils/scaled-to-vw-pos viewer (:position hl))]
-                           (set-ctx-menu-state! (apply merge (list* {:highlight hl :vw-pos vw-pos :point point} ops)))))
-
-        add-hl!        (fn [hl] (when (:id hl)
-                                  ;; fix js object
-                                  (let [highlights (pdf-utils/fix-nested-js highlights)]
-                                    (set-highlights! (conj highlights hl)))
-
-                                  (when-let [vw-pos (and (pdf-assets/area-highlight? hl)
-                                                         (pdf-utils/scaled-to-vw-pos viewer (:position hl)))]
-                                    ;; exceptions
-                                    (pdf-assets/persist-hl-area-image$ viewer (:pdf/current @state/state)
-                                                                       hl nil (:bounding vw-pos)))))
-
-        upd-hl!        (fn [hl]
-                         (let [highlights (pdf-utils/fix-nested-js highlights)]
-                           (when-let [[target-idx] (medley/find-first
-                                                    #(= (:id (second %)) (:id hl))
-                                                    (medley/indexed highlights))]
-                             (set-highlights! (assoc-in highlights [target-idx] hl))
-                             (pdf-assets/update-hl-block! hl))))
-
-        del-hl!        (fn [hl] (when-let [id (:id hl)] (set-highlights! (into [] (remove #(= id (:id %)) highlights)))))]
+                          (let [vw-pos (pdf-utils/scaled-to-vw-pos viewer (:position hl))]
+                            (set-ctx-menu-state! (apply merge (list* {:highlight hl :vw-pos vw-pos :point point} ops)))))
+
+        add-hl!         (fn [hl] (when (:id hl)
+                                   ;; fix js object
+                                   (let [highlights (pdf-utils/fix-nested-js highlights)]
+                                     (set-highlights! (conj highlights hl)))
+
+                                   (when-let [vw-pos (and (pdf-assets/area-highlight? hl)
+                                                          (pdf-utils/scaled-to-vw-pos viewer (:position hl)))]
+                                     ;; exceptions
+                                     (pdf-assets/persist-hl-area-image$ viewer (:pdf/current @state/state)
+                                                                        hl nil (:bounding vw-pos)))))
+
+        upd-hl!         (fn [hl]
+                          (let [highlights (pdf-utils/fix-nested-js highlights)]
+                            (when-let [[target-idx] (medley/find-first
+                                                     #(= (:id (second %)) (:id hl))
+                                                     (medley/indexed highlights))]
+                              (set-highlights! (assoc-in highlights [target-idx] hl))
+                              (pdf-assets/update-hl-block! hl))))
+
+        del-hl!         (fn [hl] (when-let [id (:id hl)] (set-highlights! (into [] (remove #(= id (:id %)) highlights)))))]
 
     ;; consume dirtied
     (rum/use-effect!
@@ -623,8 +630,8 @@
            ;; show ctx menu
            (js/setTimeout (fn []
                             (set-ctx-menu-state! {:highlight hl-fn
-                                             :selection selection
-                                             :point     point})))) 0))
+                                                  :selection selection
+                                                  :point     point})))) 0))
 
      [(:range sel-state)])
 
@@ -641,7 +648,7 @@
                (rum/mount
                 (pdf-highlights-region-container
                  viewer page-hls {:show-ctx-menu! show-ctx-menu!
-                                  :upd-hl!       upd-hl!})
+                                  :upd-hl!        upd-hl!})
 
                 hls-layer)))))
 
@@ -656,9 +663,9 @@
        (js/ReactDOM.createPortal
         (pdf-highlights-ctx-menu viewer ctx-menu-state
                                  {:clear-ctx-menu! clear-ctx-menu!
-                                  :add-hl!        add-hl!
-                                  :del-hl!        del-hl!
-                                  :upd-hl!        upd-hl!})
+                                  :add-hl!         add-hl!
+                                  :del-hl!         del-hl!
+                                  :upd-hl!         upd-hl!})
 
         (.querySelector el ".pp-holder")))
 
@@ -672,8 +679,7 @@
      ;;       (str "#" (:id hl) "#  ")]
      ;;      (:text (:content hl))])
      ;;   ])
-     ;; refs
-     (pdf-highlight-finder viewer)
+
      (pdf-page-finder viewer)
 
      ;; area selection container
@@ -681,11 +687,11 @@
       viewer
       {:clear-ctx-menu! clear-ctx-menu!
        :show-ctx-menu!  show-ctx-menu!
-       :add-hl!        add-hl!
+       :add-hl!         add-hl!
        })]))
 
 (rum/defc pdf-viewer
-  [_url initial-hls initial-page ^js pdf-document ops]
+  [_url ^js pdf-document {:keys [initial-hls initial-page initial-error]} ops]
 
   (let [*el-ref (rum/create-ref)
         [state, set-state!] (rum/use-state {:viewer nil :bus nil :link nil :el nil})
@@ -766,7 +772,10 @@
         [:div.pdfViewer "viewer pdf"]
         [:div.pp-holder]
 
-        (when (and page-ready? viewer)
+        ;; block hls refs
+        (pdf-highlight-finder viewer)
+
+        (when (and page-ready? viewer (not initial-error))
           [(rum/with-key
             (pdf-highlights
              (:el state) viewer
@@ -781,9 +790,9 @@
   [{:keys [url hls-file] :as pdf-current}]
   (let [*doc-ref       (rum/use-ref nil)
         [loader-state, set-loader-state!] (rum/use-state {:error nil :pdf-document nil :status nil})
-        [hls-state, set-hls-state!] (rum/use-state {:initial-hls nil :latest-hls nil :extra nil :loaded false})
+        [hls-state, set-hls-state!] (rum/use-state {:initial-hls nil :latest-hls nil :extra nil :loaded false :error nil})
         [initial-page, set-initial-page!] (rum/use-state 1)
-        set-dirty-hls! (fn [latest-hls]  ;; TODO: incremental
+        set-dirty-hls! (fn [latest-hls]                     ;; TODO: incremental
                          (set-hls-state! #(merge % {:initial-hls [] :latest-hls latest-hls})))
         set-hls-extra! (fn [extra]
                          (set-hls-state! #(merge % {:extra extra})))]
@@ -799,9 +808,12 @@
           (set-hls-state! {:initial-hls highlights :latest-hls highlights :extra extra :loaded true}))
 
         ;; error
-        (fn [e]
+        (fn [^js e]
           (js/console.error "[load hls error]" e)
-          (set-hls-state! {:initial-hls [] :loaded true})))
+
+          (let [msg (str "Error: load initial highlights failed! \n" e)]
+            (notification/show! msg :error)
+            (set-hls-state! {:loaded true :error e}))))
 
        ;; cancel
        #())
@@ -812,8 +824,9 @@
      (fn []
        (when (= :completed (:status loader-state))
          (p/catch
-          (pdf-assets/persist-hls-data$
-           pdf-current (:latest-hls hls-state) (:extra hls-state))
+          (when-not (:error hls-state)
+            (pdf-assets/persist-hls-data$
+             pdf-current (:latest-hls hls-state) (:extra hls-state)))
 
           ;; write hls file error
           (fn [e]
@@ -874,8 +887,9 @@
     (rum/bind-context
      [*highlights-ctx* hls-state]
      [:div.extensions__pdf-loader {:ref *doc-ref}
-      (let [status-doc  (:status loader-state)
-            initial-hls (:initial-hls hls-state)]
+      (let [status-doc    (:status loader-state)
+            initial-hls   (:initial-hls hls-state)
+            initial-error (:error hls-state)]
 
         (if (= status-doc :loading)
 
@@ -884,7 +898,10 @@
 
           (when-let [pdf-document (and (:loaded hls-state) (:pdf-document loader-state))]
             [(rum/with-key (pdf-viewer
-                            url initial-hls initial-page pdf-document
+                            url pdf-document
+                            {:initial-hls   initial-hls
+                             :initial-page  initial-page
+                             :initial-error initial-error}
                             {:set-dirty-hls! set-dirty-hls!
                              :set-hls-extra! set-hls-extra!}) "pdf-viewer")])))])))