mirror of
https://github.com/penpot/penpot.git
synced 2025-05-20 03:16:11 +02:00
Merge pull request #3290 from penpot/hiru-fix-update-notifications
🐛 Solve error in notification of library changes
This commit is contained in:
commit
498ba257b6
6 changed files with 60 additions and 46 deletions
|
@ -892,7 +892,7 @@
|
||||||
;; TODO: improve naming
|
;; TODO: improve naming
|
||||||
|
|
||||||
(sv/defmethod ::update-file-library-sync-status
|
(sv/defmethod ::update-file-library-sync-status
|
||||||
"Update the synchronization statos of a file->library link"
|
"Update the synchronization status of a file->library link"
|
||||||
{::doc/added "1.17"}
|
{::doc/added "1.17"}
|
||||||
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}]
|
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}]
|
||||||
(db/with-atomic [conn pool]
|
(db/with-atomic [conn pool]
|
||||||
|
|
|
@ -216,8 +216,9 @@
|
||||||
[:type [:= :del-typography]]
|
[:type [:= :del-typography]]
|
||||||
[:id ::sm/uuid]]]]])
|
[:id ::sm/uuid]]]]])
|
||||||
|
|
||||||
|
(sm/def! ::changes
|
||||||
|
[:sequential {:gen/max 2} ::change])
|
||||||
|
|
||||||
(def change?
|
(def change?
|
||||||
(sm/pred-fn ::change))
|
(sm/pred-fn ::change))
|
||||||
|
|
||||||
|
@ -302,34 +303,34 @@
|
||||||
|
|
||||||
(defmethod process-change :mod-obj
|
(defmethod process-change :mod-obj
|
||||||
[data {:keys [id page-id component-id operations]}]
|
[data {:keys [id page-id component-id operations]}]
|
||||||
(let [objects (if page-id
|
(let [changed? (atom false)
|
||||||
(-> data :pages-index (get page-id) :objects)
|
|
||||||
(-> data :components (get component-id) :objects))
|
|
||||||
|
|
||||||
modified-component-ids (atom #{})
|
process-and-register (partial process-operation
|
||||||
|
(fn [_shape] (reset! changed? true)))
|
||||||
on-touched (fn [shape]
|
|
||||||
;; When a shape is modified, if it belongs to a main component instance,
|
|
||||||
;; the component needs to be marked as modified.
|
|
||||||
(let [component-root (ctn/get-component-shape objects shape {:allow-main? true})]
|
|
||||||
(when (ctk/main-instance? component-root)
|
|
||||||
(swap! modified-component-ids conj (:component-id component-root)))))
|
|
||||||
|
|
||||||
update-fn (fn [objects]
|
update-fn (fn [objects]
|
||||||
(if-let [obj (get objects id)]
|
(d/update-when objects id
|
||||||
(let [result (reduce (partial process-operation on-touched) obj operations)]
|
#(reduce process-and-register % operations)))
|
||||||
(assoc objects id result))
|
|
||||||
objects))
|
|
||||||
|
|
||||||
modify-components (fn [data]
|
check-modify-component (fn [data]
|
||||||
(reduce ctkl/set-component-modified
|
(if @changed?
|
||||||
data @modified-component-ids))]
|
;; When a shape is modified, if it belongs to a main component instance,
|
||||||
|
;; the component needs to be marked as modified.
|
||||||
|
(let [objects (if page-id
|
||||||
|
(-> data :pages-index (get page-id) :objects)
|
||||||
|
(-> data :components (get component-id) :objects))
|
||||||
|
shape (get objects id)
|
||||||
|
component-root (ctn/get-component-shape objects shape {:allow-main? true})]
|
||||||
|
(if (and (some? component-root) (ctk/main-instance? component-root))
|
||||||
|
(ctkl/set-component-modified data (:id component-root))
|
||||||
|
data))
|
||||||
|
data))]
|
||||||
|
|
||||||
(as-> data $
|
(as-> data $
|
||||||
(if page-id
|
(if page-id
|
||||||
(d/update-in-when $ [:pages-index page-id :objects] update-fn)
|
(d/update-in-when $ [:pages-index page-id :objects] update-fn)
|
||||||
(d/update-in-when $ [:components component-id :objects] update-fn))
|
(d/update-in-when $ [:components component-id :objects] update-fn))
|
||||||
(modify-components $))))
|
(check-modify-component $))))
|
||||||
|
|
||||||
(defmethod process-change :del-obj
|
(defmethod process-change :del-obj
|
||||||
[data {:keys [page-id component-id id ignore-touched]}]
|
[data {:keys [page-id component-id id ignore-touched]}]
|
||||||
|
@ -583,7 +584,7 @@
|
||||||
;; === Operations
|
;; === Operations
|
||||||
|
|
||||||
(defmethod process-operation :set
|
(defmethod process-operation :set
|
||||||
[on-touched shape op]
|
[on-changed shape op]
|
||||||
(let [attr (:attr op)
|
(let [attr (:attr op)
|
||||||
group (get component-sync-attrs attr)
|
group (get component-sync-attrs attr)
|
||||||
val (:val op)
|
val (:val op)
|
||||||
|
@ -608,10 +609,10 @@
|
||||||
(gsh/close-attrs? attr val shape-val 1)
|
(gsh/close-attrs? attr val shape-val 1)
|
||||||
(gsh/close-attrs? attr val shape-val))]
|
(gsh/close-attrs? attr val shape-val))]
|
||||||
|
|
||||||
(when (and group (not ignore) (not equal?)
|
;; Notify when value has changed, except when it has not moved relative to the
|
||||||
(not (and ignore-geometry is-geometry?)))
|
;; component head.
|
||||||
;; Notify touched even if it's not copy, because it may be a main instance
|
(when (and group (not equal?) (not (and ignore-geometry is-geometry?)))
|
||||||
(on-touched shape))
|
(on-changed shape))
|
||||||
|
|
||||||
(cond-> shape
|
(cond-> shape
|
||||||
;; Depending on the origin of the attribute change, we need or not to
|
;; Depending on the origin of the attribute change, we need or not to
|
||||||
|
|
|
@ -211,8 +211,9 @@
|
||||||
(->> (rp/cmd! :get-file-libraries {:file-id id})
|
(->> (rp/cmd! :get-file-libraries {:file-id id})
|
||||||
(rx/mapcat identity)
|
(rx/mapcat identity)
|
||||||
(rx/merge-map
|
(rx/merge-map
|
||||||
(fn [{:keys [id]}]
|
(fn [{:keys [id synced-at]}]
|
||||||
(rp/cmd! :get-file {:id id :features features})))
|
(->> (rp/cmd! :get-file {:id id :features features})
|
||||||
|
(rx/map #(assoc % :synced-at synced-at)))))
|
||||||
(rx/merge-map
|
(rx/merge-map
|
||||||
(fn [{:keys [id data] :as file}]
|
(fn [{:keys [id data] :as file}]
|
||||||
(->> (resolve-file-data id data)
|
(->> (resolve-file-data id data)
|
||||||
|
@ -231,13 +232,15 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-data (:workspace-data state)
|
(let [file-id (dm/get-in state [:workspace-file :id])
|
||||||
ignore-until (dm/get-in state [:workspace-file :ignore-sync-until])
|
ignore-until (dm/get-in state [:workspace-file :ignore-sync-until])
|
||||||
file-id (dm/get-in state [:workspace-file :id])
|
needs-check? (some #(and (> (:modified-at %) (:synced-at %))
|
||||||
needs-update? (seq (filter #(dwl/assets-need-sync % file-data ignore-until)
|
(or (not ignore-until)
|
||||||
libraries))]
|
(> (:modified-at %) ignore-until)))
|
||||||
(when needs-update?
|
libraries)]
|
||||||
(rx/of (dwl/notify-sync-file file-id)))))))
|
(when needs-check?
|
||||||
|
(rx/concat (rx/timer 1000)
|
||||||
|
(rx/of (dwl/notify-sync-file file-id))))))))
|
||||||
|
|
||||||
(defn- fetch-thumbnail-blob-uri
|
(defn- fetch-thumbnail-blob-uri
|
||||||
[uri]
|
[uri]
|
||||||
|
|
|
@ -195,6 +195,7 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(log/info :msg "commit-changes"
|
(log/info :msg "commit-changes"
|
||||||
:js/undo-group (str undo-group)
|
:js/undo-group (str undo-group)
|
||||||
|
:js/file-id (str (or file-id "nil"))
|
||||||
:js/redo-changes redo-changes
|
:js/redo-changes redo-changes
|
||||||
:js/undo-changes undo-changes)
|
:js/undo-changes undo-changes)
|
||||||
(let [current-file-id (get state :current-file-id)
|
(let [current-file-id (get state :current-file-id)
|
||||||
|
|
|
@ -842,9 +842,9 @@
|
||||||
The sequence items are tuples of (page-id shape-id asset-id asset-type)."
|
The sequence items are tuples of (page-id shape-id asset-id asset-type)."
|
||||||
([library file-data] (assets-need-sync library file-data nil))
|
([library file-data] (assets-need-sync library file-data nil))
|
||||||
([library file-data ignore-until]
|
([library file-data ignore-until]
|
||||||
(let [sync-date (max (:synced-at library) (or ignore-until 0))]
|
(let [sync-date (max (:synced-at library) (or ignore-until 0))]
|
||||||
(when (> (:modified-at library) sync-date)
|
(when (> (:modified-at library) sync-date)
|
||||||
(ctf/used-assets-changed-since file-data library sync-date)))))
|
(ctf/used-assets-changed-since file-data library sync-date)))))
|
||||||
|
|
||||||
(defn notify-sync-file
|
(defn notify-sync-file
|
||||||
[file-id]
|
[file-id]
|
||||||
|
@ -853,7 +853,8 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [file-data (:workspace-data state)
|
(let [file-data (:workspace-data state)
|
||||||
libraries-need-sync (filter #(seq (assets-need-sync % file-data))
|
ignore-until (dm/get-in state [:workspace-file :ignore-sync-until])
|
||||||
|
libraries-need-sync (filter #(seq (assets-need-sync % file-data ignore-until))
|
||||||
(vals (get state :workspace-libraries)))
|
(vals (get state :workspace-libraries)))
|
||||||
do-update #(do (apply st/emit! (map (fn [library]
|
do-update #(do (apply st/emit! (map (fn [library]
|
||||||
(sync-file (:current-file-id state)
|
(sync-file (:current-file-id state)
|
||||||
|
@ -904,10 +905,15 @@
|
||||||
check-changes
|
check-changes
|
||||||
(fn [[event [old-data _mid_data _new-data]]]
|
(fn [[event [old-data _mid_data _new-data]]]
|
||||||
(when old-data
|
(when old-data
|
||||||
(let [{:keys [changes save-undo? undo-group]} (deref event)
|
(let [{:keys [file-id changes save-undo? undo-group]}
|
||||||
components-changed (reduce #(into %1 (ch/components-changed old-data %2))
|
(deref event)
|
||||||
#{}
|
|
||||||
changes)]
|
components-changed
|
||||||
|
(when (or (nil? file-id) (= file-id (:id old-data)))
|
||||||
|
(reduce #(into %1 (ch/components-changed old-data %2))
|
||||||
|
#{}
|
||||||
|
changes))]
|
||||||
|
|
||||||
(when (and (d/not-empty? components-changed) save-undo?)
|
(when (and (d/not-empty? components-changed) save-undo?)
|
||||||
(log/info :msg "DETECTED COMPONENTS CHANGED"
|
(log/info :msg "DETECTED COMPONENTS CHANGED"
|
||||||
:ids (map str components-changed)
|
:ids (map str components-changed)
|
||||||
|
|
|
@ -234,9 +234,10 @@
|
||||||
|
|
||||||
(mf/defc updates-tab
|
(mf/defc updates-tab
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[{:keys [file-id libraries]}]
|
[{:keys [file-id file-data libraries]}]
|
||||||
(let [libraries (mf/with-memo [libraries]
|
(let [libraries (mf/with-memo [file-data libraries]
|
||||||
(filter #(> (:modified-at %) (:synced-at %)) (vals libraries)))
|
(filter #(seq (dwl/assets-need-sync % file-data))
|
||||||
|
(vals libraries)))
|
||||||
|
|
||||||
update (mf/use-fn
|
update (mf/use-fn
|
||||||
(mf/deps file-id)
|
(mf/deps file-id)
|
||||||
|
@ -267,6 +268,7 @@
|
||||||
::mf/register-as :libraries-dialog}
|
::mf/register-as :libraries-dialog}
|
||||||
[]
|
[]
|
||||||
(let [project (mf/deref refs/workspace-project)
|
(let [project (mf/deref refs/workspace-project)
|
||||||
|
file-data (mf/deref refs/workspace-data)
|
||||||
file (mf/deref ref:workspace-file)
|
file (mf/deref ref:workspace-file)
|
||||||
|
|
||||||
team-id (:team-id project)
|
team-id (:team-id project)
|
||||||
|
@ -319,5 +321,6 @@
|
||||||
:shared-libraries shared-libraries}]
|
:shared-libraries shared-libraries}]
|
||||||
:updates
|
:updates
|
||||||
[:& updates-tab {:file-id file-id
|
[:& updates-tab {:file-id file-id
|
||||||
|
:file-data file-data
|
||||||
:libraries libraries}])]]]]))
|
:libraries libraries}])]]]]))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue