0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-03 12:59:12 -05:00

🎉 Notify shared files clients for update

This commit is contained in:
Andrés Moya 2020-09-17 15:34:31 +02:00 committed by Andrey Antukh
parent 494cd1e96c
commit 3b516aa139
6 changed files with 80 additions and 31 deletions

View file

@ -188,10 +188,6 @@
:library-file-id library-id})) :library-file-id library-id}))
;; A generic, Changes based (granular) file update method. ;; A generic, Changes based (granular) file update method.
(s/def ::changes (s/def ::changes
@ -202,6 +198,13 @@
(s/def ::update-file (s/def ::update-file
(s/keys :req-un [::id ::session-id ::profile-id ::revn ::changes])) (s/keys :req-un [::id ::session-id ::profile-id ::revn ::changes]))
;; File changes that affect to the library, and must be notified
;; to all clients using it.
(def library-changes
#{:add-color :mod-color :del-color
:add-media :mod-media :del-media
:add-component :mod-component :del-component})
(declare update-file) (declare update-file)
(declare retrieve-lagged-changes) (declare retrieve-lagged-changes)
(declare insert-change) (declare insert-change)
@ -239,11 +242,27 @@
:file-id (:id file) :file-id (:id file)
:session-id sid :session-id sid
:revn (:revn file) :revn (:revn file)
:changes changes}] :changes changes}
library-changes (filter #(library-changes (:type %)) changes)]
@(redis/run! :publish {:channel (str (:id file)) @(redis/run! :publish {:channel (str (:id file))
:message (t/encode-str msg)}) :message (t/encode-str msg)})
(if (and (:is-shared file) (seq library-changes))
(let [{:keys [team-id] :as project}
(db/get-by-id conn :project (:project-id file))
msg {:type :library-change
:profile-id (:profile-id params)
:file-id (:id file)
:session-id sid
:revn (:revn file)
:changes library-changes}]
@(redis/run! :publish {:channel (str team-id)
:message (t/encode-str msg)})))
(db/update! conn :file (db/update! conn :file
{:revn (:revn file) {:revn (:revn file)
:data (:data file)} :data (:data file)}

View file

@ -368,12 +368,12 @@
(defmethod change-spec :add-component [_] (defmethod change-spec :add-component [_]
(s/keys :req-un [::id ::name :internal.changes.add-component/shapes])) (s/keys :req-un [::id ::name :internal.changes.add-component/shapes]))
(defmethod change-spec :mod-component [_]
(s/keys :req-un [::id ::name :internal.changes.add-component/shapes]))
(defmethod change-spec :del-component [_] (defmethod change-spec :del-component [_]
(s/keys :req-un [::id])) (s/keys :req-un [::id]))
(defmethod change-spec :update-component [_]
(s/keys :req-un [::id ::name :internal.changes.add-component/shapes]))
(s/def ::change (s/multi-spec change-spec :type)) (s/def ::change (s/multi-spec change-spec :type))
(s/def ::changes (s/coll-of ::change)) (s/def ::changes (s/coll-of ::change))
@ -782,17 +782,17 @@
:name name :name name
:objects (d/index-by :id shapes)})) :objects (d/index-by :id shapes)}))
(defmethod process-change :del-component (defmethod process-change :mod-component
[data {:keys [id]}]
(d/dissoc-in data [:components id]))
(defmethod process-change :update-component
[data {:keys [id name shapes]}] [data {:keys [id name shapes]}]
(update-in data [:components id] (update-in data [:components id]
#(assoc % #(assoc %
:name name :name name
:objects (d/index-by :id shapes)))) :objects (d/index-by :id shapes))))
(defmethod process-change :del-component
[data {:keys [id]}]
(d/dissoc-in data [:components id]))
(defmethod process-operation :set (defmethod process-operation :set
[shape op] [shape op]
(let [attr (:attr op) (let [attr (:attr op)

View file

@ -345,6 +345,16 @@
qparams {:page-id (first (get-in file [:data :pages]))}] qparams {:page-id (first (get-in file [:data :pages]))}]
(st/emit! (rt/nav-new-window :workspace pparams qparams)))))) (st/emit! (rt/nav-new-window :workspace pparams qparams))))))
(defn ext-library-changed
[file-id changes]
(us/assert ::us/uuid file-id)
(us/assert ::cp/changes changes)
(ptk/reify ::ext-library-changed
ptk/UpdateEvent
(update [_ state]
(d/update-in-when state [:workspace-libraries file-id :data]
cp/process-changes changes))))
(declare generate-sync-file) (declare generate-sync-file)
(declare generate-sync-page) (declare generate-sync-page)
(declare generate-sync-shape-and-children) (declare generate-sync-shape-and-children)
@ -407,12 +417,12 @@
[new-shape new-shapes _] [new-shape new-shapes _]
(cph/clone-object root-shape nil objects update-new-shape) (cph/clone-object root-shape nil objects update-new-shape)
rchanges [{:type :update-component rchanges [{:type :mod-component
:id component-id :id component-id
:name (:name new-shape) :name (:name new-shape)
:shapes new-shapes}] :shapes new-shapes}]
uchanges [{:type :update-component uchanges [{:type :mod-component
:id component-id :id component-id
:name (:name component-obj) :name (:name component-obj)
:shapes (vals component-objs)}]] :shapes (vals component-objs)}]]
@ -420,7 +430,7 @@
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
(defn sync-file (defn sync-file
[{:keys [file-id] :as params}] [file-id]
(us/assert (s/nilable ::us/uuid) file-id) (us/assert (s/nilable ::us/uuid) file-id)
(ptk/reify ::sync-file (ptk/reify ::sync-file
ptk/WatchEvent ptk/WatchEvent
@ -434,6 +444,7 @@
(if (nil? file-id) (if (nil? file-id)
(get-in state [:workspace-data :components]) (get-in state [:workspace-data :components])
(get-in state [:workspace-libraries file-id :data :components]))] (get-in state [:workspace-libraries file-id :data :components]))]
(when (some? components)
(loop [pages (seq (vals (get-in state [:workspace-data :pages-index]))) (loop [pages (seq (vals (get-in state [:workspace-data :pages-index])))
rchanges [] rchanges []
uchanges []] uchanges []]
@ -441,15 +452,17 @@
(if (nil? page) (if (nil? page)
[rchanges uchanges] [rchanges uchanges]
(let [[page-rchanges page-uchanges] (let [[page-rchanges page-uchanges]
(generate-sync-page page components)] (generate-sync-page file-id page components)]
(recur (next pages) (recur (next pages)
(concat rchanges page-rchanges) (concat rchanges page-rchanges)
(concat uchanges page-uchanges)))))))) (concat uchanges page-uchanges)))))))))
(defn- generate-sync-page (defn- generate-sync-page
[page components] [file-id page components]
(let [linked-shapes (let [linked-shapes
(cph/select-objects #(some? (:component-id %)) page)] (cph/select-objects #(and (some? (:component-id %))
(= (:component-file %) file-id))
page)]
(loop [shapes (seq linked-shapes) (loop [shapes (seq linked-shapes)
rchanges [] rchanges []
uchanges []] uchanges []]

View file

@ -15,6 +15,7 @@
[app.common.spec :as us] [app.common.spec :as us]
[app.main.data.workspace.common :as dwc] [app.main.data.workspace.common :as dwc]
[app.main.data.workspace.persistence :as dwp] [app.main.data.workspace.persistence :as dwp]
[app.main.data.workspace.libraries :as dwl]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st] [app.main.store :as st]
[app.main.streams :as ms] [app.main.streams :as ms]
@ -31,6 +32,7 @@
(declare handle-presence) (declare handle-presence)
(declare handle-pointer-update) (declare handle-pointer-update)
(declare handle-file-change) (declare handle-file-change)
(declare handle-library-change)
(declare handle-pointer-send) (declare handle-pointer-send)
(declare send-keepalive) (declare send-keepalive)
@ -73,6 +75,7 @@
:presence (handle-presence msg) :presence (handle-presence msg)
:pointer-update (handle-pointer-update msg) :pointer-update (handle-pointer-update msg)
:file-change (handle-file-change msg) :file-change (handle-file-change msg)
:library-change (handle-library-change msg)
::unknown)) ::unknown))
(defn- send-keepalive (defn- send-keepalive
@ -197,3 +200,17 @@
(rx/of (dwp/shapes-changes-persisted file-id msg)) (rx/of (dwp/shapes-changes-persisted file-id msg))
(when (seq page-ids) (when (seq page-ids)
(rx/from (map dwc/update-indices page-ids)))))))) (rx/from (map dwc/update-indices page-ids))))))))
(s/def ::library-change-event
(s/keys :req-un [::type ::profile-id ::file-id ::session-id ::revn ::changes]))
(defn handle-library-change
[{:keys [file-id changes] :as msg}]
(us/assert ::library-change-event msg)
(ptk/reify ::handle-library-change
ptk/WatchEvent
(watch [_ state stream]
(when (contains? (:workspace-libraries state) file-id)
(rx/of (dwl/ext-library-changed file-id changes)
(dwl/sync-file file-id))))))

View file

@ -67,7 +67,7 @@
do-reset-component #(st/emit! (dwl/reset-component id)) do-reset-component #(st/emit! (dwl/reset-component id))
do-update-component #(do do-update-component #(do
(st/emit! (dwl/update-component id)) (st/emit! (dwl/update-component id))
(st/emit! (dwl/sync-file {:file-id nil}))) (st/emit! (dwl/sync-file nil)))
do-navigate-component-file #(st/emit! (dwl/nav-to-component-file do-navigate-component-file #(st/emit! (dwl/nav-to-component-file
(:component-file root-shape)))] (:component-file root-shape)))]
[:* [:*

View file

@ -51,7 +51,7 @@
(mf/deps state) (mf/deps state)
(fn [] (fn []
(st/emit! (dwl/delete-component {:id (:component-id @state)})) (st/emit! (dwl/delete-component {:id (:component-id @state)}))
(st/emit! (dwl/sync-file {:file-id nil})))) (st/emit! (dwl/sync-file nil))))
on-context-menu on-context-menu
(mf/use-callback (mf/use-callback