mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 16:21:57 -05:00
🎉 Update component in a shared library
This commit is contained in:
parent
7f3ef7bb82
commit
870eff5826
10 changed files with 293 additions and 123 deletions
|
@ -2113,6 +2113,38 @@
|
|||
"es" : "Añadir “%s” como Biblioteca Compartida"
|
||||
}
|
||||
},
|
||||
"modals.update-remote-component.message" : {
|
||||
"translations" : {
|
||||
"en" : "Update a component in a shared library",
|
||||
"fr" : "",
|
||||
"ru" : "",
|
||||
"es" : "Actualizar un componente en librería"
|
||||
}
|
||||
},
|
||||
"modals.update-remote-component.hint" : {
|
||||
"translations" : {
|
||||
"en" : "You are about to update a component in a shared library. This may affect other files that use it.",
|
||||
"fr" : "",
|
||||
"ru" : "",
|
||||
"es" : "Vas a actualizar un componente en una librería compartida. Esto puede afectar a otros archivos que la usen."
|
||||
}
|
||||
},
|
||||
"modals.update-remote-component.accept" : {
|
||||
"translations" : {
|
||||
"en" : "Update component",
|
||||
"fr" : "",
|
||||
"ru" : "",
|
||||
"es" : "Actualizar componente"
|
||||
}
|
||||
},
|
||||
"modals.update-remote-component.cancel" : {
|
||||
"translations" : {
|
||||
"en" : "Cancel",
|
||||
"fr" : "",
|
||||
"ru" : "",
|
||||
"es" : "Cancelar"
|
||||
}
|
||||
},
|
||||
"notifications.profile-deletion-not-allowed" : {
|
||||
"used-in" : [ "src/app/main/ui/settings/delete_account.cljs:28" ],
|
||||
"translations" : {
|
||||
|
|
|
@ -66,7 +66,8 @@
|
|||
([changes undo-changes]
|
||||
(commit-changes changes undo-changes {}))
|
||||
([changes undo-changes {:keys [save-undo?
|
||||
commit-local?]
|
||||
commit-local?
|
||||
file-id]
|
||||
:or {save-undo? true
|
||||
commit-local? false}
|
||||
:as opts}]
|
||||
|
@ -79,17 +80,25 @@
|
|||
(let [error (volatile! nil)]
|
||||
(ptk/reify ::commit-changes
|
||||
cljs.core/IDeref
|
||||
(-deref [_] changes)
|
||||
(-deref [_] {:file-id file-id :changes changes})
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(try
|
||||
(let [state (update-in state [:workspace-file :data] cp/process-changes changes)]
|
||||
(cond-> state
|
||||
commit-local? (update :workspace-data cp/process-changes changes)))
|
||||
(catch :default e
|
||||
(vreset! error e)
|
||||
state)))
|
||||
(let [current-file-id (get state :current-file-id)
|
||||
file-id (or file-id current-file-id)
|
||||
path1 (if (= file-id current-file-id)
|
||||
[:workspace-file :data]
|
||||
[:workspace-libraries file-id :data])
|
||||
path2 (if (= file-id current-file-id)
|
||||
[:workspace-data]
|
||||
[:workspace-libraries file-id :data])]
|
||||
(try
|
||||
(let [state (update-in state path1 cp/process-changes changes)]
|
||||
(cond-> state
|
||||
commit-local? (update-in path2 cp/process-changes changes)))
|
||||
(catch :default e
|
||||
(vreset! error e)
|
||||
state))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
|
|
|
@ -36,21 +36,21 @@
|
|||
(log/set-level! :warn)
|
||||
|
||||
(defn- log-changes
|
||||
[changes local-library]
|
||||
[changes file]
|
||||
(let [extract-change
|
||||
(fn [change]
|
||||
(let [shape (when (:id change)
|
||||
(cond
|
||||
(:page-id change)
|
||||
(get-in local-library [:pages-index
|
||||
(:page-id change)
|
||||
:objects
|
||||
(:id change)])
|
||||
(get-in file [:pages-index
|
||||
(:page-id change)
|
||||
:objects
|
||||
(:id change)])
|
||||
(:component-id change)
|
||||
(get-in local-library [:components
|
||||
(:component-id change)
|
||||
:objects
|
||||
(:id change)])
|
||||
(get-in file [:components
|
||||
(:component-id change)
|
||||
:objects
|
||||
(:id change)])
|
||||
:default nil))
|
||||
|
||||
prefix (if (:component-id change) "[C] " "[P] ")
|
||||
|
@ -118,7 +118,7 @@
|
|||
uchg {:type :mod-color
|
||||
:color prev}]
|
||||
(rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})
|
||||
(sync-file file-id))))))
|
||||
(sync-file (:current-file-id state) file-id))))))
|
||||
|
||||
(defn delete-color
|
||||
[{:keys [id] :as params}]
|
||||
|
@ -208,7 +208,7 @@
|
|||
uchg {:type :mod-typography
|
||||
:typography prev}]
|
||||
(rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true})
|
||||
(sync-file file-id))))))
|
||||
(sync-file (:current-file-id state) file-id))))))
|
||||
|
||||
(defn delete-typography
|
||||
[id]
|
||||
|
@ -337,7 +337,7 @@
|
|||
(watch [_ state stream]
|
||||
(let [component (cp/get-component id
|
||||
(:current-file-id state)
|
||||
(dwlh/get-local-library state)
|
||||
(dwlh/get-local-file state)
|
||||
nil)
|
||||
all-components (vals (get-in state [:workspace-data :components]))
|
||||
unames (set (map :name all-components))
|
||||
|
@ -385,7 +385,7 @@
|
|||
(ptk/reify ::instantiate-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [local-library (dwlh/get-local-library state)
|
||||
(let [local-library (dwlh/get-local-file state)
|
||||
libraries (get state :workspace-libraries)
|
||||
component (cp/get-component component-id file-id local-library libraries)
|
||||
component-shape (cp/get-shape component component-id)
|
||||
|
@ -529,14 +529,15 @@
|
|||
(st/emit! (rt/nav-new-window :workspace pparams qparams))))))
|
||||
|
||||
(defn ext-library-changed
|
||||
[file-id modified-at changes]
|
||||
[file-id modified-at revn changes]
|
||||
(us/assert ::us/uuid file-id)
|
||||
(us/assert ::cp/changes changes)
|
||||
(ptk/reify ::ext-library-changed
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc-in [:workspace-libraries file-id :modified-at] modified-at)
|
||||
(update-in [:workspace-libraries file-id]
|
||||
#(assoc % :modified-at modified-at :revn revn))
|
||||
(d/update-in-when [:workspace-libraries file-id :data]
|
||||
cp/process-changes changes)))))
|
||||
|
||||
|
@ -550,7 +551,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(log/info :msg "RESET-COMPONENT of shape" :id (str id))
|
||||
(let [local-library (dwlh/get-local-library state)
|
||||
(let [local-library (dwlh/get-local-file state)
|
||||
libraries (dwlh/get-libraries state)
|
||||
container (cp/get-container (get state :current-page-id)
|
||||
:page
|
||||
|
@ -577,46 +578,84 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(log/info :msg "UPDATE-COMPONENT of shape" :id (str id))
|
||||
(let [local-library (dwlh/get-local-library state)
|
||||
(let [page-id (get state :current-page-id)
|
||||
local-library (dwlh/get-local-file state)
|
||||
libraries (dwlh/get-libraries state)
|
||||
|
||||
[rchanges uchanges]
|
||||
(dwlh/generate-sync-shape-inverse (get state :current-page-id)
|
||||
(dwlh/generate-sync-shape-inverse page-id
|
||||
id
|
||||
local-library
|
||||
libraries)]
|
||||
libraries)
|
||||
|
||||
(log/debug :msg "UPDATE-COMPONENT finished" :js/rchanges (log-changes
|
||||
rchanges
|
||||
local-library))
|
||||
container (cp/get-container page-id :page local-library)
|
||||
shape (cp/get-shape container id)
|
||||
file-id (:component-file shape)
|
||||
file (dwlh/get-file state file-id)
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
local-rchanges (->> rchanges
|
||||
(filter :local-change?)
|
||||
(map #(dissoc % :local-change?))
|
||||
vec)
|
||||
local-uchanges (->> uchanges
|
||||
(filter :local-change?)
|
||||
(map #(dissoc % :local-change?))
|
||||
vec)
|
||||
rchanges (->> rchanges
|
||||
(remove :local-change?)
|
||||
(map #(dissoc % :local-change?))
|
||||
vec)
|
||||
uchanges (->> uchanges
|
||||
(remove :local-change?)
|
||||
(map #(dissoc % :local-change?))
|
||||
vec)]
|
||||
|
||||
(log/debug :msg "UPDATE-COMPONENT finished"
|
||||
:js/local-rchanges (log-changes
|
||||
local-rchanges
|
||||
local-library)
|
||||
:js/rchanges (log-changes
|
||||
rchanges
|
||||
file))
|
||||
|
||||
(rx/of (when (seq local-rchanges)
|
||||
(dwc/commit-changes local-rchanges local-uchanges
|
||||
{:commit-local? true
|
||||
:file-id (:id local-library)}))
|
||||
(when (seq rchanges)
|
||||
(dwc/commit-changes rchanges uchanges
|
||||
{:commit-local? true
|
||||
:file-id file-id})))))))
|
||||
|
||||
(declare sync-file-2nd-stage)
|
||||
|
||||
(defn sync-file
|
||||
"Syhchronize the library file with the given id, with the current file.
|
||||
Walk through all shapes in all pages that use some color, typography or
|
||||
component of the library file, and copy the new values to the shapes.
|
||||
Do it also for shapes inside components of the local file library."
|
||||
[file-id]
|
||||
"Syhchronize the given file from ghe given library. Walk through all shapes
|
||||
in all pages in the file that use some color, typography or component of the
|
||||
library, and copy the new values to the shapes. Do it also for shapes inside
|
||||
components of the local file library."
|
||||
[file-id library-id]
|
||||
(us/assert ::us/uuid file-id)
|
||||
(us/assert ::us/uuid library-id)
|
||||
(ptk/reify ::sync-file
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(if (not= file-id (:current-file-id state))
|
||||
(assoc-in state [:workspace-libraries file-id :synced-at] (dt/now))
|
||||
(if (not= library-id (:current-file-id state))
|
||||
(assoc-in state [:workspace-libraries library-id :synced-at] (dt/now))
|
||||
state))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(log/info :msg "SYNC-FILE" :file (if (= file-id (:current-file-id state)) "local" (str file-id)))
|
||||
(let [local-library (dwlh/get-local-library state)
|
||||
library-changes [(dwlh/generate-sync-library :components file-id state)
|
||||
(dwlh/generate-sync-library :colors file-id state)
|
||||
(dwlh/generate-sync-library :typographies file-id state)]
|
||||
file-changes [(dwlh/generate-sync-file :components file-id state)
|
||||
(dwlh/generate-sync-file :colors file-id state)
|
||||
(dwlh/generate-sync-file :typographies file-id state)]
|
||||
(log/info :msg "SYNC-FILE"
|
||||
:file (dwlh/pretty-file file-id state)
|
||||
:library (dwlh/pretty-file library-id state))
|
||||
(let [file (dwlh/get-file state file-id)
|
||||
library-changes [(dwlh/generate-sync-library file-id :components library-id state)
|
||||
(dwlh/generate-sync-library file-id :colors library-id state)
|
||||
(dwlh/generate-sync-library file-id :typographies library-id state)]
|
||||
file-changes [(dwlh/generate-sync-file file-id :components library-id state)
|
||||
(dwlh/generate-sync-file file-id :colors library-id state)
|
||||
(dwlh/generate-sync-file file-id :typographies library-id state)]
|
||||
rchanges (d/concat []
|
||||
(->> library-changes (remove nil?) (map first) (flatten))
|
||||
(->> file-changes (remove nil?) (map first) (flatten)))
|
||||
|
@ -625,17 +664,22 @@
|
|||
(->> file-changes (remove nil?) (map second) (flatten)))]
|
||||
(log/debug :msg "SYNC-FILE finished" :js/rchanges (log-changes
|
||||
rchanges
|
||||
local-library))
|
||||
file))
|
||||
(rx/concat
|
||||
(rx/of (dm/hide-tag :sync-dialog))
|
||||
(when rchanges
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))
|
||||
(when (not= file-id (:current-file-id state))
|
||||
(rp/mutation :update-sync
|
||||
{:file-id (get-in state [:workspace-file :id])
|
||||
:library-id file-id}))
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true
|
||||
:file-id file-id})))
|
||||
(when (not= file-id library-id)
|
||||
;; When we have just updated the library file, give some time for the
|
||||
;; update to finish, before marking this file as synced.
|
||||
;; TODO: look for a more precise way of syncing this.
|
||||
(rx/concat (rx/timer 3000)
|
||||
(rp/mutation :update-sync
|
||||
{:file-id file-id
|
||||
:library-id library-id})))
|
||||
(when (some? library-changes)
|
||||
(rx/of (sync-file-2nd-stage file-id))))))))
|
||||
(rx/of (sync-file-2nd-stage file-id library-id))))))))
|
||||
|
||||
(defn sync-file-2nd-stage
|
||||
"If some components have been modified, we need to launch another synchronization
|
||||
|
@ -646,22 +690,26 @@
|
|||
;; recursively. But for this not to cause an infinite loop, we need to
|
||||
;; implement updated-at at component level, to detect what components have
|
||||
;; not changed, and then not to apply sync and terminate the loop.
|
||||
[file-id]
|
||||
[file-id library-id]
|
||||
(us/assert ::us/uuid file-id)
|
||||
(us/assert ::us/uuid library-id)
|
||||
(ptk/reify ::sync-file-2nd-stage
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(log/info :msg "SYNC-FILE (2nd stage)" :file (if (= file-id (:current-file-id state)) "local" (str file-id)))
|
||||
(let [local-library (dwlh/get-local-library state)
|
||||
[rchanges1 uchanges1] (dwlh/generate-sync-file :components file-id state)
|
||||
[rchanges2 uchanges2] (dwlh/generate-sync-library :components file-id state)
|
||||
(log/info :msg "SYNC-FILE (2nd stage)"
|
||||
:file (dwlh/pretty-file file-id state)
|
||||
:library (dwlh/pretty-file library-id state))
|
||||
(let [file (dwlh/get-file state file-id)
|
||||
[rchanges1 uchanges1] (dwlh/generate-sync-file file-id :components library-id state)
|
||||
[rchanges2 uchanges2] (dwlh/generate-sync-library file-id :components library-id state)
|
||||
rchanges (d/concat rchanges1 rchanges2)
|
||||
uchanges (d/concat uchanges1 uchanges2)]
|
||||
(when rchanges
|
||||
(log/debug :msg "SYNC-FILE (2nd stage) finished" :js/rchanges (log-changes
|
||||
rchanges
|
||||
local-library))
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))))
|
||||
file))
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true
|
||||
:file-id file-id})))))))
|
||||
|
||||
(def ignore-sync
|
||||
(ptk/reify ::ignore-sync
|
||||
|
@ -684,7 +732,8 @@
|
|||
(let [libraries-need-sync (filter #(> (:modified-at %) (:synced-at %))
|
||||
(vals (get state :workspace-libraries)))
|
||||
do-update #(do (apply st/emit! (map (fn [library]
|
||||
(sync-file (:id library)))
|
||||
(sync-file (:current-file-id state)
|
||||
(:id library)))
|
||||
libraries-need-sync))
|
||||
(st/emit! dm/hide))
|
||||
do-dismiss #(do (st/emit! ignore-sync)
|
||||
|
|
|
@ -59,14 +59,26 @@
|
|||
[(d/concat rchanges1 rchanges2)
|
||||
(d/concat uchanges1 uchanges2)])
|
||||
|
||||
(defn get-local-library
|
||||
(defn get-local-file
|
||||
[state]
|
||||
(get state :workspace-data))
|
||||
|
||||
(defn get-file
|
||||
[state file-id]
|
||||
(if (= file-id (:current-file-id state))
|
||||
(get state :workspace-data)
|
||||
(get-in state [:workspace-libraries file-id :data])))
|
||||
|
||||
(defn get-libraries
|
||||
[state]
|
||||
(get state :workspace-libraries))
|
||||
|
||||
(defn pretty-file
|
||||
[file-id state]
|
||||
(if (= file-id (:current-file-id state))
|
||||
"<local>"
|
||||
(str "<" (get-in state [:workspace-libraries file-id :name]) ">")))
|
||||
|
||||
|
||||
;; ---- Create a new component ----
|
||||
|
||||
|
@ -124,25 +136,26 @@
|
|||
;; ---- General library synchronization functions ----
|
||||
|
||||
(defn generate-sync-file
|
||||
"Generate changes to synchronize all shapes in all pages of the current file,
|
||||
"Generate changes to synchronize all shapes in all pages of the given file,
|
||||
that use assets of the given type in the given library."
|
||||
[asset-type library-id state]
|
||||
[file-id asset-type library-id state]
|
||||
(s/assert #{:colors :components :typographies} asset-type)
|
||||
(s/assert ::us/uuid file-id)
|
||||
(s/assert ::us/uuid library-id)
|
||||
|
||||
(log/info :msg "Sync local file with library"
|
||||
(log/info :msg "Sync file with library"
|
||||
:asset-type asset-type
|
||||
:library (str (or library-id "local")))
|
||||
:file (pretty-file file-id state)
|
||||
:library (pretty-file library-id state))
|
||||
|
||||
(let [library-items
|
||||
(if (= library-id (:current-file-id state))
|
||||
(get-in state [:workspace-data asset-type])
|
||||
(get-in state [:workspace-libraries library-id :data asset-type]))]
|
||||
(let [file (get-file state file-id)
|
||||
library (get-file state library-id)
|
||||
library-items (get library asset-type)]
|
||||
|
||||
(if (empty? library-items)
|
||||
empty-changes
|
||||
|
||||
(loop [pages (vals (get-in state [:workspace-data :pages-index]))
|
||||
(loop [pages (vals (get file :pages-index))
|
||||
rchanges []
|
||||
uchanges []]
|
||||
(if-let [page (first pages)]
|
||||
|
@ -157,22 +170,24 @@
|
|||
[rchanges uchanges])))))
|
||||
|
||||
(defn generate-sync-library
|
||||
"Generate changes to synchronize all shapes in all components of the current
|
||||
file library, that use assets of the given type in the given library."
|
||||
[asset-type library-id state]
|
||||
"Generate changes to synchronize all shapes in all components of the
|
||||
local library of the given file, that use assets of the given type in
|
||||
the given library."
|
||||
[file-id asset-type library-id state]
|
||||
|
||||
(log/info :msg "Sync local components with library"
|
||||
:asset-type asset-type
|
||||
:library (str library-id))
|
||||
:file (pretty-file file-id state)
|
||||
:library (pretty-file library-id state))
|
||||
|
||||
(let [file (get-file state file-id)
|
||||
library (get-file state library-id)
|
||||
library-items (get library asset-type)]
|
||||
|
||||
(let [library-items
|
||||
(if (= library-id (:current-file-id state))
|
||||
(get-in state [:workspace-data asset-type])
|
||||
(get-in state [:workspace-libraries library-id :data asset-type]))]
|
||||
(if (empty? library-items)
|
||||
empty-changes
|
||||
|
||||
(loop [local-components (seq (vals (get-in state [:workspace-data :components])))
|
||||
(loop [local-components (vals (get file :components))
|
||||
rchanges []
|
||||
uchanges []]
|
||||
(if-let [local-component (first local-components)]
|
||||
|
@ -261,7 +276,7 @@
|
|||
[_ library-id state container shape]
|
||||
(generate-sync-shape-direct container
|
||||
(:id shape)
|
||||
(get-local-library state)
|
||||
(get-local-file state)
|
||||
(get-libraries state)
|
||||
false))
|
||||
|
||||
|
@ -689,7 +704,18 @@
|
|||
only-master
|
||||
both
|
||||
moved
|
||||
true)]
|
||||
true)
|
||||
|
||||
;; The inverse sync may be made on a component that is inside a
|
||||
;; remote library. We need to separate changes that are from
|
||||
;; local and remote files.
|
||||
check-local (fn [change]
|
||||
(cond-> change
|
||||
(= (:id change) (:id shape-inst))
|
||||
(assoc :local-change? true)))
|
||||
|
||||
rchanges (vec (map check-local rchanges))
|
||||
uchanges (vec (map check-local uchanges))]
|
||||
|
||||
[(d/concat rchanges child-rchanges)
|
||||
(d/concat uchanges child-uchanges)]))
|
||||
|
|
|
@ -218,12 +218,12 @@
|
|||
::changes]))
|
||||
|
||||
(defn handle-library-change
|
||||
[{:keys [file-id modified-at changes] :as msg}]
|
||||
[{:keys [file-id modified-at changes revn] :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 modified-at changes)
|
||||
(rx/of (dwl/ext-library-changed file-id modified-at revn changes)
|
||||
(dwl/notify-sync-file file-id))))))
|
||||
|
||||
|
|
|
@ -55,6 +55,13 @@
|
|||
(rx/debounce 2000)
|
||||
(rx/merge stoper forcer))
|
||||
|
||||
local-file? #(let [event-file-id (:file-id %)]
|
||||
(or (nil? event-file-id)
|
||||
(= event-file-id file-id)))
|
||||
library-file? #(let [event-file-id (:file-id %)]
|
||||
(and (some? event-file-id)
|
||||
(not= event-file-id file-id)))
|
||||
|
||||
on-dirty
|
||||
(fn []
|
||||
;; Enable reload stoper
|
||||
|
@ -70,27 +77,36 @@
|
|||
;; Disable reload stoper
|
||||
(obj/set! js/window "onbeforeunload" nil)
|
||||
(st/emit! (update-persistence-status {:status :saved})))]
|
||||
|
||||
(->> (rx/merge
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::dwc/commit-changes))
|
||||
(rx/map deref)
|
||||
(rx/tap on-dirty)
|
||||
(rx/buffer-until notifier)
|
||||
(rx/map vec)
|
||||
(rx/filter (complement empty?))
|
||||
(rx/map #(persist-changes file-id %))
|
||||
(rx/tap on-saving)
|
||||
(rx/take-until (rx/delay 100 stoper)))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::changes-persisted))
|
||||
(rx/tap on-saved)
|
||||
(rx/ignore)
|
||||
(rx/take-until stoper)))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::dwc/commit-changes))
|
||||
(rx/map deref)
|
||||
(rx/filter local-file?)
|
||||
(rx/tap on-dirty)
|
||||
(rx/buffer-until notifier)
|
||||
(rx/filter (complement empty?))
|
||||
(rx/map (fn [buf] {:file-id file-id
|
||||
:changes (into [] (mapcat :changes) buf)}))
|
||||
(rx/map persist-changes)
|
||||
(rx/tap on-saving)
|
||||
(rx/take-until (rx/delay 100 stoper)))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::dwc/commit-changes))
|
||||
(rx/map deref)
|
||||
(rx/filter library-file?)
|
||||
(rx/filter (complement #(empty? (:changes %))))
|
||||
(rx/map persist-changes)
|
||||
(rx/take-until (rx/delay 100 stoper)))
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::changes-persisted))
|
||||
(rx/tap on-saved)
|
||||
(rx/ignore)
|
||||
(rx/take-until stoper)))
|
||||
(rx/subs #(st/emit! %)))))))
|
||||
|
||||
(defn persist-changes
|
||||
[file-id changes]
|
||||
[{:keys [file-id changes]}]
|
||||
(us/verify ::us/uuid file-id)
|
||||
(ptk/reify ::persist-changes
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
|
@ -102,10 +118,11 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [sid (:session-id state)
|
||||
file (:workspace-file state)
|
||||
file (if (= file-id (:current-file-id state))
|
||||
(get state :workspace-file)
|
||||
(get-in state [:workspace-libraries file-id]))
|
||||
queue (get-in state [:workspace-persistence :queue] [])
|
||||
xf-cat (comp (mapcat :changes)
|
||||
(mapcat identity))
|
||||
xf-cat (comp (mapcat :changes))
|
||||
changes (into [] xf-cat queue)
|
||||
params {:id (:id file)
|
||||
:revn (:revn file)
|
||||
|
@ -143,10 +160,9 @@
|
|||
(rx/delay 200)
|
||||
(rx/mapcat #(rx/throw error))))))]
|
||||
|
||||
(when (= file-id (:id file))
|
||||
(->> (rp/mutation :update-file params)
|
||||
(rx/mapcat handle-response)
|
||||
(rx/catch on-error)))))))
|
||||
(->> (rp/mutation :update-file params)
|
||||
(rx/mapcat handle-response)
|
||||
(rx/catch on-error))))))
|
||||
|
||||
|
||||
(defn update-persistence-status
|
||||
|
@ -171,14 +187,16 @@
|
|||
(ptk/reify ::changes-persisted
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [sid (:session-id state)
|
||||
file (:workspace-file state)]
|
||||
(if (= file-id (:id file))
|
||||
(let [state (update-in state [:workspace-file :revn] #(max % revn))]
|
||||
(-> state
|
||||
(update :workspace-data cp/process-changes changes)
|
||||
(update-in [:workspace-file :data] cp/process-changes changes)))
|
||||
state)))))
|
||||
(if (= file-id (:current-file-id state))
|
||||
(-> state
|
||||
(update-in [:workspace-file :revn] #(max % revn))
|
||||
(update :workspace-data cp/process-changes changes)
|
||||
(update-in [:workspace-file :data] cp/process-changes changes))
|
||||
(-> state
|
||||
(update-in state [:workspace-libraries file-id :revn]
|
||||
#(max % revn))
|
||||
(update-in [:workspace-libraries file-id :data]
|
||||
cp/process-changes changes))))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
(ns app.main.ui.workspace.context-menu
|
||||
"A workspace specific context menu (mouse right click)."
|
||||
(:require
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
|
@ -76,8 +77,24 @@
|
|||
do-update-component #(do
|
||||
(st/emit! (dwc/start-undo-transaction))
|
||||
(st/emit! (dwl/update-component id))
|
||||
(st/emit! (dwl/sync-file current-file-id))
|
||||
(st/emit! (dwl/sync-file current-file-id
|
||||
(:component-file shape)))
|
||||
(st/emit! (dwc/commit-undo-transaction)))
|
||||
confirm-update-remote-component #(do
|
||||
(st/emit! (dwl/update-component id))
|
||||
(st/emit! (dwl/sync-file current-file-id
|
||||
(:component-file shape)))
|
||||
(st/emit! (dwl/sync-file (:component-file shape)
|
||||
(:component-file shape))))
|
||||
do-update-remote-component (st/emitf (modal/show
|
||||
{:type :confirm
|
||||
:message ""
|
||||
:title (t locale "modals.update-remote-component.message")
|
||||
:hint (t locale "modals.update-remote-component.hint")
|
||||
:cancel-label (t locale "modals.update-remote-component.cancel")
|
||||
:accept-label (t locale "modals.update-remote-component.accept")
|
||||
:accept-style :primary
|
||||
:on-accept confirm-update-remote-component}))
|
||||
do-show-component #(st/emit! (dw/go-to-layout :assets))
|
||||
do-navigate-component-file #(st/emit! (dwl/nav-to-component-file
|
||||
(:component-file shape)))]
|
||||
|
@ -175,7 +192,9 @@
|
|||
[:& menu-entry {:title (t locale "workspace.shape.menu.reset-overrides")
|
||||
:on-click do-reset-component}]
|
||||
[:& menu-entry {:title (t locale "workspace.shape.menu.go-master")
|
||||
:on-click do-navigate-component-file}]]))
|
||||
:on-click do-navigate-component-file}]
|
||||
[:& menu-entry {:title (t locale "workspace.shape.menu.update-master")
|
||||
:on-click do-update-remote-component}]]))
|
||||
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title (t locale "workspace.shape.menu.delete")
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
[{:keys [file libraries] :as props}]
|
||||
(let [libraries-need-sync (filter #(> (:modified-at %) (:synced-at %))
|
||||
(vals libraries))
|
||||
update-library #(st/emit! (dwl/sync-file %))]
|
||||
update-library #(st/emit! (dwl/sync-file (:id file) %))]
|
||||
[:div.section
|
||||
(if (empty? libraries-need-sync)
|
||||
[:div.section-list-empty
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
(mf/deps state)
|
||||
(fn []
|
||||
(st/emit! (dwl/delete-component {:id (:component-id @state)}))
|
||||
(st/emit! (dwl/sync-file file-id))))
|
||||
(st/emit! (dwl/sync-file file-id file-id))))
|
||||
|
||||
on-rename
|
||||
(mf/use-callback
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.context :as ctx]
|
||||
|
@ -54,8 +55,23 @@
|
|||
do-update-component #(do
|
||||
(st/emit! (dwc/start-undo-transaction))
|
||||
(st/emit! (dwl/update-component id))
|
||||
(st/emit! (dwl/sync-file current-file-id))
|
||||
(st/emit! (dwl/sync-file current-file-id current-file-id))
|
||||
(st/emit! (dwc/commit-undo-transaction)))
|
||||
confirm-update-remote-component #(do
|
||||
(st/emit! (dwl/update-component id))
|
||||
(st/emit! (dwl/sync-file current-file-id
|
||||
(:component-file values)))
|
||||
(st/emit! (dwl/sync-file (:component-file values)
|
||||
(:component-file values))))
|
||||
do-update-remote-component (st/emitf (modal/show
|
||||
{:type :confirm
|
||||
:message ""
|
||||
:title (t locale "modals.update-remote-component.message")
|
||||
:hint (t locale "modals.update-remote-component.hint")
|
||||
:cancel-label (t locale "modals.update-remote-component.cancel")
|
||||
:accept-label (t locale "modals.update-remote-component.accept")
|
||||
:accept-style :primary
|
||||
:on-accept confirm-update-remote-component}))
|
||||
do-show-component #(st/emit! (dw/go-to-layout :assets))
|
||||
do-navigate-component-file #(st/emit! (dwl/nav-to-component-file
|
||||
(:component-file values)))]
|
||||
|
@ -83,5 +99,6 @@
|
|||
|
||||
[[(t locale "workspace.shape.menu.detach-instance") do-detach-component]
|
||||
[(t locale "workspace.shape.menu.reset-overrides") do-reset-component]
|
||||
[(t locale "workspace.shape.menu.go-master") do-navigate-component-file]])}]]]]])))
|
||||
[(t locale "workspace.shape.menu.go-master") do-navigate-component-file]
|
||||
[(t locale "workspace.shape.menu.update-master") do-update-remote-component]])}]]]]])))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue