Răsfoiți Sursa

fix: avoid save whiteboard shapes if nonces have not been changed

Tienson Qin 1 an în urmă
părinte
comite
ab5606bd1f

+ 6 - 3
src/main/frontend/db_worker.cljs

@@ -276,9 +276,12 @@
              _ (when context (state/set-context! context))
              tx-meta' (if (:new-graph? tx-meta)
                         tx-meta
-                        (-> tx-meta
-                            (assoc :skip-store? true) ; delay writes to the disk
-                            (dissoc :insert-blocks?)))]
+                        (cond-> tx-meta
+                          (not (:whiteboard/transact? tx-meta)) ; delay writes to the disk
+                          (assoc :skip-store? true)
+
+                          true
+                          (dissoc :insert-blocks?)))]
          (when-not (and (:create-today-journal? tx-meta)
                         (:today-journal-name tx-meta)
                         (seq tx-data)

+ 13 - 3
src/main/frontend/extensions/tldraw.cljs

@@ -13,6 +13,7 @@
             [frontend.handler.route :as route-handler]
             [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.handler.history :as history]
+            [frontend.handler.notification :as notification]
             [frontend.rum :as r]
             [frontend.search :as search]
             [frontend.state :as state]
@@ -138,6 +139,8 @@
                            (route-handler/redirect-to-whiteboard! page-name {:block-id page-name-or-uuid})
                            (route-handler/redirect-to-page! (model/get-redirect-page-name page-name-or-uuid))))))})
 
+(defonce *transact-result (atom nil))
+
 (rum/defc tldraw-app-inner < rum/reactive
   [page-name block-id loaded-app set-loaded-app]
   (let [populate-onboarding? (whiteboard-handler/should-populate-onboarding-whiteboard? page-name)
@@ -171,9 +174,16 @@
                 :onMount on-mount
                 :readOnly config/publishing?
                 :onPersist (fn [app info]
-                             (state/set-state! [:whiteboard/last-persisted-at (state/get-current-repo)] (util/time-ms))
-                             (util/profile "tldraw persist"
-                                           (whiteboard-handler/<transact-tldr-delta! page-name app (.-replace info))))
+                             (->
+                              (p/let [_ @*transact-result
+                                      result (p/do!
+                                              (state/set-state! [:whiteboard/last-persisted-at (state/get-current-repo)] (util/time-ms))
+                                              (whiteboard-handler/<transact-tldr-delta! page-name app (.-replace info)))]
+                                (reset! *transact-result result))
+                              (p/catch (fn [^js error]
+                                         (js/console.error error)
+                                         (notification/show! [:div
+                                                              (str "Save whiteboard failed, error:" (.-cause error))])))))
                 :model data})])))
 
 (rum/defc tldraw-app

+ 58 - 47
src/main/frontend/handler/whiteboard.cljs

@@ -106,19 +106,29 @@
         changed-shapes (set/difference upsert-shapes created-shapes)
         prev-changed-blocks (when (seq changed-shapes)
                               (db/pull-many repo '[*] (mapv (fn [shape]
-                                                              [:block/uuid (uuid (:id shape))]) changed-shapes)))]
-    {:page-block (build-page-block page-name tl-page assets shapes-index)
-     :upserted-blocks (->> upsert-shapes
-                           (map #(shape->block % page-name))
-                           (map sqlite-util/block-with-timestamps))
-     :delete-blocks deleted-shapes-tx
-     :metadata {:whiteboard/transact? (not replace?)
-                :replace? replace?
-                :data {:page-name page-name
-                       :deleted-shapes deleted-shapes
-                       :new-shapes created-shapes
-                       :changed-shapes changed-shapes
-                       :prev-changed-blocks prev-changed-blocks}}}))
+                                                              [:block/uuid (uuid (:id shape))]) changed-shapes)))
+        upserted-blocks (->> (map #(shape->block % page-name) upsert-shapes)
+                             (remove (fn [b]
+                                       (= (:nonce
+                                           (pu/get-property
+                                            (db/entity [:block/uuid (:block/uuid b)])
+                                            :logseq.tldraw.shape))
+                                          (:nonce
+                                           (pu/get-property
+                                            b
+                                            :logseq.tldraw.shape))))))]
+    (when (or (seq upserted-blocks)
+              (seq deleted-shapes-tx))
+      {:page-block (build-page-block page-name tl-page assets shapes-index)
+       :upserted-blocks (map sqlite-util/block-with-timestamps upserted-blocks)
+       :delete-blocks deleted-shapes-tx
+       :metadata {:whiteboard/transact? (not replace?)
+                  :replace? replace?
+                  :data {:page-name page-name
+                         :deleted-shapes deleted-shapes
+                         :new-shapes created-shapes
+                         :changed-shapes changed-shapes
+                         :prev-changed-blocks prev-changed-blocks}}})))
 
 (defonce *last-shapes-nonce (atom {}))
 (defn <transact-tldr-delta!
@@ -130,50 +140,51 @@
         prev-shapes-index (:shapes-index prev-page-metadata)
         shape-id->prev-index (zipmap prev-shapes-index (range (count prev-shapes-index)))
         new-id-nonces (set (map-indexed (fn [idx shape]
-                                  (let [id (.-id shape)]
-                                    {:id id
-                                     :nonce (if (= idx (get shape-id->prev-index id))
-                                              (.-nonce shape)
-                                              (js/Date.now))})) shapes))
+                                          (let [id (.-id shape)]
+                                            {:id id
+                                             :nonce (if (= idx (get shape-id->prev-index id))
+                                                      (.-nonce shape)
+                                                      (js/Date.now))})) shapes))
         repo (state/get-current-repo)
         db-id-nonces (or
                       (get-in @*last-shapes-nonce [repo page-name])
                       (set (->> (model/get-whiteboard-id-nonces repo page-name)
                                 (map #(update % :id str)))))
-        {:keys [page-block upserted-blocks delete-blocks metadata]}
-        (compute-tx app tl-page new-id-nonces db-id-nonces page-name replace?)
-        tx-data (concat delete-blocks [page-block] upserted-blocks)
-        new-shapes (get-in metadata [:data :new-shapes])
-        deleted-shapes (get-in metadata [:data :deleted-shapes])
-        metadata' (cond
+        {:keys [page-block upserted-blocks delete-blocks metadata] :as result}
+        (compute-tx app tl-page new-id-nonces db-id-nonces page-name replace?)]
+    (when (seq result)
+      (let [tx-data (concat delete-blocks [page-block] upserted-blocks)
+            new-shapes (get-in metadata [:data :new-shapes])
+            deleted-shapes (get-in metadata [:data :deleted-shapes])
+            metadata' (cond
                     ;; group
-                    (some #(= "group" (:type %)) new-shapes)
-                    (assoc metadata :whiteboard/op :group)
+                        (some #(= "group" (:type %)) new-shapes)
+                        (assoc metadata :whiteboard/op :group)
 
                     ;; ungroup
-                    (and (not-empty deleted-shapes) (every? #(= "group" (:type %)) deleted-shapes))
-                    (assoc metadata :whiteboard/op :un-group)
+                        (and (not-empty deleted-shapes) (every? #(= "group" (:type %)) deleted-shapes))
+                        (assoc metadata :whiteboard/op :un-group)
 
                     ;; arrow
-                    (some #(and (= "line" (:type %))
-                                (= "arrow " (:end (:decorations %)))) new-shapes)
-
-                    (assoc metadata :whiteboard/op :new-arrow)
-                    :else
-                    metadata)
-        metadata' (if (seq (concat upserted-blocks delete-blocks))
-                    metadata'
-                    (assoc metadata :undo? true))]
-    (swap! *last-shapes-nonce assoc-in [repo page-name] new-id-nonces)
-    (if (contains? #{:new-arrow} (:whiteboard/op metadata'))
-      (state/set-state! :whiteboard/pending-tx-data
-                        {:tx-data tx-data
-                         :metadata metadata'})
-      (let [pending-tx-data (:whiteboard/pending-tx-data @state/state)
-            tx-data' (concat (:tx-data pending-tx-data) tx-data)
-            metadata'' (merge metadata' (:metadata pending-tx-data))]
-        (state/set-state! :whiteboard/pending-tx-data {})
-        (db/transact! repo tx-data' metadata'')))))
+                        (some #(and (= "line" (:type %))
+                                    (= "arrow " (:end (:decorations %)))) new-shapes)
+
+                        (assoc metadata :whiteboard/op :new-arrow)
+                        :else
+                        metadata)
+            metadata' (if (seq (concat upserted-blocks delete-blocks))
+                        metadata'
+                        (assoc metadata :undo? true))]
+        (swap! *last-shapes-nonce assoc-in [repo page-name] new-id-nonces)
+        (if (contains? #{:new-arrow} (:whiteboard/op metadata'))
+          (state/set-state! :whiteboard/pending-tx-data
+                            {:tx-data tx-data
+                             :metadata metadata'})
+          (let [pending-tx-data (:whiteboard/pending-tx-data @state/state)
+                tx-data' (concat (:tx-data pending-tx-data) tx-data)
+                metadata'' (merge metadata' (:metadata pending-tx-data))]
+            (state/set-state! :whiteboard/pending-tx-data {})
+            (db/transact! repo tx-data' metadata'')))))))
 
 (defn get-default-new-whiteboard-tx
   [page-name id]