mirror of
https://github.com/penpot/penpot.git
synced 2025-01-23 23:18:48 -05:00
🎉 Notify shared files clients for update
This commit is contained in:
parent
494cd1e96c
commit
3b516aa139
6 changed files with 80 additions and 31 deletions
|
@ -188,10 +188,6 @@
|
|||
:library-file-id library-id}))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;; A generic, Changes based (granular) file update method.
|
||||
|
||||
(s/def ::changes
|
||||
|
@ -202,6 +198,13 @@
|
|||
(s/def ::update-file
|
||||
(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 retrieve-lagged-changes)
|
||||
(declare insert-change)
|
||||
|
@ -239,11 +242,27 @@
|
|||
:file-id (:id file)
|
||||
:session-id sid
|
||||
:revn (:revn file)
|
||||
:changes changes}]
|
||||
:changes changes}
|
||||
|
||||
library-changes (filter #(library-changes (:type %)) changes)]
|
||||
|
||||
@(redis/run! :publish {:channel (str (:id file))
|
||||
: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
|
||||
{:revn (:revn file)
|
||||
:data (:data file)}
|
||||
|
|
|
@ -368,12 +368,12 @@
|
|||
(defmethod change-spec :add-component [_]
|
||||
(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 [_]
|
||||
(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 ::changes (s/coll-of ::change))
|
||||
|
||||
|
@ -782,17 +782,17 @@
|
|||
:name name
|
||||
:objects (d/index-by :id shapes)}))
|
||||
|
||||
(defmethod process-change :del-component
|
||||
[data {:keys [id]}]
|
||||
(d/dissoc-in data [:components id]))
|
||||
|
||||
(defmethod process-change :update-component
|
||||
(defmethod process-change :mod-component
|
||||
[data {:keys [id name shapes]}]
|
||||
(update-in data [:components id]
|
||||
#(assoc %
|
||||
:name name
|
||||
:objects (d/index-by :id shapes))))
|
||||
|
||||
(defmethod process-change :del-component
|
||||
[data {:keys [id]}]
|
||||
(d/dissoc-in data [:components id]))
|
||||
|
||||
(defmethod process-operation :set
|
||||
[shape op]
|
||||
(let [attr (:attr op)
|
||||
|
|
|
@ -345,6 +345,16 @@
|
|||
qparams {:page-id (first (get-in file [:data :pages]))}]
|
||||
(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-page)
|
||||
(declare generate-sync-shape-and-children)
|
||||
|
@ -407,12 +417,12 @@
|
|||
[new-shape new-shapes _]
|
||||
(cph/clone-object root-shape nil objects update-new-shape)
|
||||
|
||||
rchanges [{:type :update-component
|
||||
rchanges [{:type :mod-component
|
||||
:id component-id
|
||||
:name (:name new-shape)
|
||||
:shapes new-shapes}]
|
||||
|
||||
uchanges [{:type :update-component
|
||||
uchanges [{:type :mod-component
|
||||
:id component-id
|
||||
:name (:name component-obj)
|
||||
:shapes (vals component-objs)}]]
|
||||
|
@ -420,7 +430,7 @@
|
|||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
(defn sync-file
|
||||
[{:keys [file-id] :as params}]
|
||||
[file-id]
|
||||
(us/assert (s/nilable ::us/uuid) file-id)
|
||||
(ptk/reify ::sync-file
|
||||
ptk/WatchEvent
|
||||
|
@ -434,22 +444,25 @@
|
|||
(if (nil? file-id)
|
||||
(get-in state [:workspace-data :components])
|
||||
(get-in state [:workspace-libraries file-id :data :components]))]
|
||||
(loop [pages (seq (vals (get-in state [:workspace-data :pages-index])))
|
||||
rchanges []
|
||||
uchanges []]
|
||||
(let [page (first pages)]
|
||||
(if (nil? page)
|
||||
[rchanges uchanges]
|
||||
(let [[page-rchanges page-uchanges]
|
||||
(generate-sync-page page components)]
|
||||
(recur (next pages)
|
||||
(concat rchanges page-rchanges)
|
||||
(concat uchanges page-uchanges))))))))
|
||||
(when (some? components)
|
||||
(loop [pages (seq (vals (get-in state [:workspace-data :pages-index])))
|
||||
rchanges []
|
||||
uchanges []]
|
||||
(let [page (first pages)]
|
||||
(if (nil? page)
|
||||
[rchanges uchanges]
|
||||
(let [[page-rchanges page-uchanges]
|
||||
(generate-sync-page file-id page components)]
|
||||
(recur (next pages)
|
||||
(concat rchanges page-rchanges)
|
||||
(concat uchanges page-uchanges)))))))))
|
||||
|
||||
(defn- generate-sync-page
|
||||
[page components]
|
||||
[file-id page components]
|
||||
(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)
|
||||
rchanges []
|
||||
uchanges []]
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[app.common.spec :as us]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.persistence :as dwp]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
|
@ -31,6 +32,7 @@
|
|||
(declare handle-presence)
|
||||
(declare handle-pointer-update)
|
||||
(declare handle-file-change)
|
||||
(declare handle-library-change)
|
||||
(declare handle-pointer-send)
|
||||
(declare send-keepalive)
|
||||
|
||||
|
@ -73,6 +75,7 @@
|
|||
:presence (handle-presence msg)
|
||||
:pointer-update (handle-pointer-update msg)
|
||||
:file-change (handle-file-change msg)
|
||||
:library-change (handle-library-change msg)
|
||||
::unknown))
|
||||
|
||||
(defn- send-keepalive
|
||||
|
@ -197,3 +200,17 @@
|
|||
(rx/of (dwp/shapes-changes-persisted file-id msg))
|
||||
(when (seq 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))))))
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
do-reset-component #(st/emit! (dwl/reset-component id))
|
||||
do-update-component #(do
|
||||
(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
|
||||
(:component-file root-shape)))]
|
||||
[:*
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
(mf/deps state)
|
||||
(fn []
|
||||
(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
|
||||
(mf/use-callback
|
||||
|
|
Loading…
Add table
Reference in a new issue