diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index a7884636c..1d14b75de 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -892,7 +892,7 @@ ;; TODO: improve naming (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"} [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}] (db/with-atomic [conn pool] diff --git a/common/src/app/common/pages/changes.cljc b/common/src/app/common/pages/changes.cljc index dcd5fe5d0..f7f21ee41 100644 --- a/common/src/app/common/pages/changes.cljc +++ b/common/src/app/common/pages/changes.cljc @@ -303,34 +303,34 @@ (defmethod process-change :mod-obj [data {:keys [id page-id component-id operations]}] - (let [objects (if page-id - (-> data :pages-index (get page-id) :objects) - (-> data :components (get component-id) :objects)) + (let [changed? (atom false) - modified-component-ids (atom #{}) - - 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))))) + process-and-register (partial process-operation + (fn [_shape] (reset! changed? true))) update-fn (fn [objects] - (if-let [obj (get objects id)] - (let [result (reduce (partial process-operation on-touched) obj operations)] - (assoc objects id result)) - objects)) + (d/update-when objects id + #(reduce process-and-register % operations))) - modify-components (fn [data] - (reduce ctkl/set-component-modified - data @modified-component-ids))] + check-modify-component (fn [data] + (if @changed? + ;; 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 $ (if page-id (d/update-in-when $ [:pages-index page-id :objects] update-fn) (d/update-in-when $ [:components component-id :objects] update-fn)) - (modify-components $)))) + (check-modify-component $)))) (defmethod process-change :del-obj [data {:keys [page-id component-id id ignore-touched]}] @@ -584,7 +584,7 @@ ;; === Operations (defmethod process-operation :set - [on-touched shape op] + [on-changed shape op] (let [attr (:attr op) group (get component-sync-attrs attr) val (:val op) @@ -609,10 +609,10 @@ (gsh/close-attrs? attr val shape-val 1) (gsh/close-attrs? attr val shape-val))] - (when (and group (not ignore) (not equal?) - (not (and ignore-geometry is-geometry?))) - ;; Notify touched even if it's not copy, because it may be a main instance - (on-touched shape)) + ;; Notify when value has changed, except when it has not moved relative to the + ;; component head. + (when (and group (not equal?) (not (and ignore-geometry is-geometry?))) + (on-changed shape)) (cond-> shape ;; Depending on the origin of the attribute change, we need or not to diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index ab7a52d35..14e532f28 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -232,13 +232,15 @@ ptk/WatchEvent (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]) - file-id (dm/get-in state [:workspace-file :id]) - needs-update? (seq (filter #(dwl/assets-need-sync % file-data ignore-until) - libraries))] - (when needs-update? - (rx/of (dwl/notify-sync-file file-id))))))) + needs-check? (some #(and (> (:modified-at %) (:synced-at %)) + (or (not ignore-until) + (> (:modified-at %) ignore-until))) + libraries)] + (when needs-check? + (rx/concat (rx/timer 1000) + (rx/of (dwl/notify-sync-file file-id)))))))) (defn- fetch-thumbnail-blob-uri [uri] diff --git a/frontend/src/app/main/data/workspace/changes.cljs b/frontend/src/app/main/data/workspace/changes.cljs index add461c14..a8461f415 100644 --- a/frontend/src/app/main/data/workspace/changes.cljs +++ b/frontend/src/app/main/data/workspace/changes.cljs @@ -195,6 +195,7 @@ (update [_ state] (log/info :msg "commit-changes" :js/undo-group (str undo-group) + :js/file-id (str (or file-id "nil")) :js/redo-changes redo-changes :js/undo-changes undo-changes) (let [current-file-id (get state :current-file-id) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index d47efe802..ee793bbf3 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -842,9 +842,9 @@ 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 ignore-until] - (let [sync-date (max (:synced-at library) (or ignore-until 0))] - (when (> (:modified-at library) sync-date) - (ctf/used-assets-changed-since file-data library sync-date))))) + (let [sync-date (max (:synced-at library) (or ignore-until 0))] + (when (> (:modified-at library) sync-date) + (ctf/used-assets-changed-since file-data library sync-date))))) (defn notify-sync-file [file-id] @@ -853,7 +853,8 @@ ptk/WatchEvent (watch [_ 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))) do-update #(do (apply st/emit! (map (fn [library] (sync-file (:current-file-id state) @@ -904,10 +905,15 @@ check-changes (fn [[event [old-data _mid_data _new-data]]] (when old-data - (let [{:keys [changes save-undo? undo-group]} (deref event) - components-changed (reduce #(into %1 (ch/components-changed old-data %2)) - #{} - changes)] + (let [{:keys [file-id changes save-undo? undo-group]} + (deref event) + + 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?) (log/info :msg "DETECTED COMPONENTS CHANGED" :ids (map str components-changed)