0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-13 07:21:40 -05:00

🎉 Add experimental trazability to update-file.

This commit is contained in:
Andrey Antukh 2021-05-08 14:59:58 +02:00 committed by Andrés Moya
parent c70bc5baff
commit 0f8e2a9b1b
15 changed files with 407 additions and 272 deletions

View file

@ -228,16 +228,10 @@
{:id file-id}))
;; --- MUTATION: update-file
;; A generic, Changes based (granular) file update method.
(s/def ::changes
(s/coll-of map? :kind vector?))
(s/def ::session-id ::us/uuid)
(s/def ::revn ::us/integer)
(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.
(defn library-change?
@ -256,6 +250,31 @@
(declare send-notifications)
(declare update-file)
(s/def ::changes
(s/coll-of map? :kind vector?))
(s/def ::hint-origin ::us/keyword)
(s/def ::hint-events
(s/every ::us/keyword :kind vector?))
(s/def ::change-with-metadata
(s/keys :req-un [::changes]
:opt-un [::hint-origin
::hint-events]))
(s/def ::changes-with-metadata
(s/every ::change-with-metadata :kind vector?))
(s/def ::session-id ::us/uuid)
(s/def ::revn ::us/integer)
(s/def ::update-file
(s/and
(s/keys :req-un [::id ::session-id ::profile-id ::revn]
:opt-un [::changes ::changes-with-metadata])
(fn [o]
(or (contains? o :changes)
(contains? o :changes-with-metadata)))))
(sv/defmethod ::update-file
[{:keys [pool] :as cfg} {:keys [id profile-id] :as params}]
(db/with-atomic [conn pool]
@ -265,7 +284,7 @@
(assoc params :file file)))))
(defn- update-file
[{:keys [conn] :as cfg} {:keys [file changes session-id profile-id] :as params}]
[{:keys [conn] :as cfg} {:keys [file changes changes-with-metadata session-id profile-id] :as params}]
(when (> (:revn params)
(:revn file))
(ex/raise :type :validation
@ -274,15 +293,19 @@
:context {:incoming-revn (:revn params)
:stored-revn (:revn file)}))
(let [file (-> file
(update :revn inc)
(update :data (fn [data]
(-> data
(blob/decode)
(assoc :id (:id file))
(pmg/migrate-data)
(cp/process-changes changes)
(blob/encode)))))]
(let [changes (if changes-with-metadata
(mapcat :changes changes-with-metadata)
changes)
file (-> file
(update :revn inc)
(update :data (fn [data]
(-> data
(blob/decode)
(assoc :id (:id file))
(pmg/migrate-data)
(cp/process-changes changes)
(blob/encode)))))]
;; Insert change to the xlog
(db/insert! conn :file-change
{:id (uuid/next)

View file

@ -134,7 +134,7 @@
(or layout default-layout))))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(if (and layout-name (contains? layout-names layout-name))
(rx/of (ensure-layout layout-name))
(rx/of (ensure-layout :layers))))))
@ -153,7 +153,7 @@
:workspace-presence {}))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rx/merge
(rx/of (dwp/fetch-bundle project-id file-id))
@ -188,7 +188,7 @@
file))))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [ignore-until (get-in state [:workspace-file :ignore-sync-until])
needs-update? (some #(and (> (:modified-at %) (:synced-at %))
(or (not ignore-until)
@ -209,7 +209,7 @@
:workspace-persistence))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rx/of (dwn/finalize file-id)
::dwp/finalize))))
@ -263,7 +263,7 @@
{:id id :file-id file-id})
ptk/WatchEvent
(watch [this state stream]
(watch [it state stream]
(let [pages (get-in state [:workspace-data :pages-index])
unames (dwc/retrieve-used-names pages)
name (dwc/generate-unique-name unames "Page")
@ -273,9 +273,12 @@
:name name}
uchange {:type :del-page
:id id}]
(rx/of (dch/commit-changes [rchange] [uchange] {:commit-local? true})))))))
(rx/of (dch/commit-changes {:redo-changes [rchange]
:undo-changes [uchange]
:origin it})))))))
(defn duplicate-page [page-id]
(defn duplicate-page
[page-id]
(ptk/reify ::duplicate-page
ptk/WatchEvent
(watch [this state stream]
@ -291,7 +294,9 @@
:page page}
uchange {:type :del-page
:id id}]
(rx/of (dch/commit-changes [rchange] [uchange] {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes [rchange]
:undo-changes [uchange]
:origin this}))))))
(s/def ::rename-page
(s/keys :req-un [::id ::name]))
@ -302,7 +307,7 @@
(us/verify string? name)
(ptk/reify ::rename-page
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page (get-in state [:workspace-data :pages-index id])
rchg {:type :mod-page
:id id
@ -310,7 +315,9 @@
uchg {:type :mod-page
:id id
:name (:name page)}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it}))))))
(declare purge-page)
(declare go-to-file)
@ -321,13 +328,15 @@
[id]
(ptk/reify ::delete-page
ptk/WatchEvent
(watch [_ state s]
(watch [it state stream]
(let [page (get-in state [:workspace-data :pages-index id])
rchg {:type :del-page
:id id}
uchg {:type :add-page
:page page}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it})
(when (= id (:current-page-id state))
go-to-file))))))
@ -345,7 +354,7 @@
(assoc-in state [:workspace-file :name] name))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [params {:id id :name name}]
(->> (rp/mutation :rename-file params)
(rx/ignore))))))
@ -444,7 +453,7 @@
(defn start-panning []
(ptk/reify ::start-panning
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [stopper (->> stream (rx/filter (ptk/type? ::finish-panning)))
zoom (-> (get-in state [:workspace-local :zoom]) gpt/point)]
(when-not (get-in state [:workspace-local :panning])
@ -607,7 +616,7 @@
(us/verify ::shape-attrs attrs)
(ptk/reify ::update-shape
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rx/of (dch/update-shapes [id] #(merge % attrs))))))
(defn start-rename-shape
@ -632,7 +641,7 @@
(us/verify ::shape-attrs attrs)
(ptk/reify ::update-selected-shapes
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [selected (wsh/lookup-selected state)]
(rx/from (map #(update-shape % attrs) selected))))))
@ -670,7 +679,7 @@
"Deselect all and remove all selected shapes."
(ptk/reify ::delete-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [selected (wsh/lookup-selected state)]
(rx/of (dwc/delete-shapes selected)
(dws/deselect-all))))))
@ -682,9 +691,9 @@
(defn vertical-order-selected
[loc]
(us/verify ::loc loc)
(ptk/reify ::vertical-order-selected-shpes
(ptk/reify ::vertical-order-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
@ -716,7 +725,9 @@
:index (cp/position-on-parent id objects)}))
selected)]
;; TODO: maybe missing the :reg-objects event?
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
;; --- Change Shape Order (D&D Ordering)
@ -891,7 +902,7 @@
(ptk/reify ::relocate-shapes
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -990,14 +1001,16 @@
shapes-to-detach
shapes-to-reroot
shapes-to-deroot)]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-chanes uchanges
:origin it})
(dwc/expand-collapse parent-id))))))
(defn relocate-selected-shapes
[parent-id to-index]
(ptk/reify ::relocate-selected-shapes
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [selected (wsh/lookup-selected state)]
(rx/of (relocate-shapes selected parent-id to-index))))))
@ -1006,7 +1019,7 @@
[]
(ptk/reify ::start-editing-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [selected (wsh/lookup-selected state)]
(if-not (= 1 (count selected))
(rx/empty)
@ -1034,7 +1047,7 @@
[id index]
(ptk/reify ::relocate-pages
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [cidx (-> (get-in state [:workspace-data :pages])
(d/index-of id))
rchg {:type :mov-page
@ -1043,7 +1056,9 @@
uchg {:type :mov-page
:id id
:index cidx}]
(rx/of (dch/commit-changes [rchg] [uchg]))))))
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-chanes [uchg]
:origin it}))))))
;; --- Shape / Selection Alignment and Distribution
@ -1055,7 +1070,7 @@
(us/verify ::gal/align-axis axis)
(ptk/reify :align-objects
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
@ -1086,7 +1101,7 @@
(us/verify ::gal/dist-axis axis)
(ptk/reify :align-objects
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
@ -1104,7 +1119,7 @@
[id lock]
(ptk/reify ::set-shape-proportion-lock
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(letfn [(assign-proportions [shape]
(if-not lock
(assoc shape :proportion-lock false)
@ -1125,7 +1140,7 @@
(us/verify ::position position)
(ptk/reify ::update-position
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
shape (get objects id)
@ -1147,7 +1162,7 @@
(s/assert ::shape-attrs flags)
(ptk/reify ::update-shape-flags
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(letfn [(update-fn [obj]
(cond-> obj
(boolean? blocked) (assoc :blocked blocked)
@ -1163,7 +1178,7 @@
[project-id]
(ptk/reify ::navigate-to-project
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-ids (get-in state [:projects project-id :pages])
params {:project project-id :page (first page-ids)}]
(rx/of (rt/nav :workspace/page params))))))
@ -1172,7 +1187,7 @@
([]
(ptk/reify ::go-to-page
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [project-id (:current-project-id state)
file-id (:current-file-id state)
page-id (get-in state [:workspace-data :pages 0])
@ -1184,7 +1199,7 @@
(us/verify ::us/uuid page-id)
(ptk/reify ::go-to-page
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [project-id (:current-project-id state)
file-id (:current-file-id state)
pparams {:file-id file-id :project-id project-id}
@ -1196,7 +1211,7 @@
(us/verify ::layout-flag layout)
(ptk/reify ::go-to-layout
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [project-id (get-in state [:workspace-project :id])
file-id (get-in state [:workspace-file :id])
page-id (get-in state [:current-page-id])
@ -1207,7 +1222,7 @@
(def go-to-file
(ptk/reify ::go-to-file
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [{:keys [id project-id data] :as file} (:workspace-file state)
page-id (get-in data [:pages 0])
pparams {:project-id project-id :file-id id}
@ -1220,7 +1235,7 @@
([{:keys [file-id page-id]}]
(ptk/reify ::go-to-viewer
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [{:keys [current-file-id current-page-id]} state
params {:file-id (or file-id current-file-id)
:page-id (or page-id current-page-id)}]
@ -1232,7 +1247,7 @@
([{:keys [team-id]}]
(ptk/reify ::go-to-dashboard
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [team-id (or team-id (get-in state [:workspace-project :team-id]))]
(rx/of ::dwp/force-persist
(rt/nav :dashboard-projects {:team-id team-id})))))))
@ -1262,7 +1277,7 @@
(us/verify ::cp/minimal-shape shape)
(ptk/reify ::show-shape-context-menu
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [selected (wsh/lookup-selected state)]
(rx/concat
(when-not (selected (:id shape))
@ -1354,7 +1369,7 @@
(ptk/reify ::copy-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)
selected (->> (wsh/lookup-selected state)
(cp/clean-loops objects))
@ -1381,7 +1396,7 @@
(def paste
(ptk/reify ::paste
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(try
(let [clipboard-str (wapi/read-from-clipboard)
@ -1420,7 +1435,7 @@
[event in-viewport?]
(ptk/reify ::paste-from-event
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(try
(let [objects (wsh/lookup-page-objects state)
paste-data (wapi/read-from-paste-event event)
@ -1538,7 +1553,7 @@
change)))
;; Procceed with the standard shape paste procediment.
(do-paste [state mouse-pos media]
(do-paste [it state mouse-pos media]
(let [media-idx (d/index-by :prev-id media)
page-id (:current-page-id state)
@ -1584,19 +1599,21 @@
(map #(get-in % [:obj :id]))
(into (d/ordered-set)))]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(dwc/select-shapes selected))))]
(ptk/reify ::paste-shape
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [file-id (:current-file-id state)
mouse-pos (deref ms/mouse-position)]
(if (= file-id (:file-id data))
(do-paste state mouse-pos [])
(do-paste it state mouse-pos [])
(->> (rx/from images)
(rx/merge-map (partial upload-media file-id))
(rx/reduce conj [])
(rx/mapcat (partial do-paste state mouse-pos)))))))))
(rx/mapcat (partial do-paste it state mouse-pos)))))))))
(defn as-content [text]
@ -1612,7 +1629,7 @@
(s/assert string? text)
(ptk/reify ::paste-text
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [id (uuid/next)
{:keys [x y]} @ms/mouse-position
width (max 8 (min (* 7 (count text)) 700))
@ -1641,7 +1658,7 @@
(s/assert string? text)
(ptk/reify ::paste-svg
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [position (deref ms/mouse-position)
file-id (:current-file-id state)]
(->> (dwp/parse-svg ["svg" text])
@ -1651,7 +1668,7 @@
[image]
(ptk/reify ::paste-bin-impl
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [file-id (get-in state [:workspace-file :id])
params {:file-id file-id
:blobs [image]
@ -1676,7 +1693,7 @@
[]
(ptk/reify ::start-create-interaction
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [initial-pos @ms/mouse-position
selected (wsh/lookup-selected state)
stopper (rx/filter ms/mouse-up? stream)]
@ -1713,7 +1730,7 @@
(assoc-in [:workspace-local :draw-interaction-to-frame] nil)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [position @ms/mouse-position
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -1741,20 +1758,20 @@
[color]
(ptk/reify ::change-canvas-color
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (get state :current-page-id)
options (wsh/lookup-page-options state page-id)
previus-color (:background options)]
(rx/of (dch/commit-changes
[{:type :set-option
:page-id page-id
:option :background
:value (:color color)}]
[{:type :set-option
:page-id page-id
:option :background
:value previus-color}]
{:commit-local? true}))))))
{:redo-changes [{:type :set-option
:page-id page-id
:option :background
:value (:color color)}]
:undo-changes [{:type :set-option
:page-id page-id
:option :background
:value previus-color}]
:origin it}))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -12,6 +12,7 @@
[app.common.spec :as us]
[app.main.data.workspace.undo :as dwu]
[app.main.worker :as uw]
[app.main.store :as st]
[app.util.logging :as log]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
@ -66,7 +67,7 @@
(us/assert fn? f)
(ptk/reify ::update-shapes
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (get-in state [:workspace-data :pages-index page-id :objects])
reg-objects {:type :reg-objects :page-id page-id :shapes (vec ids)}]
@ -79,7 +80,9 @@
rch (cond-> rch (and has-rch? reg-objects?) (conj reg-objects))
uch (cond-> uch (and has-rch? reg-objects?) (conj reg-objects))]
(when (and has-rch? has-uch?)
(commit-changes rch uch {:commit-local? true}))))
(commit-changes {:redo-changes rch
:undo-changes uch
:origin it}))))
(let [id (first ids)
obj1 (get objects id)
@ -140,11 +143,13 @@
(conj uchanges uchg))))))]
(ptk/reify ::update-shapes-recursive
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (get-in state [:workspace-data :pages-index page-id :objects])
[rchanges uchanges] (impl-gen-changes objects page-id (seq ids))]
(rx/of (commit-changes rchanges uchanges {:commit-local? true})))))))
(rx/of (commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})))))))
(defn update-indices
[page-id changes]
@ -156,62 +161,60 @@
:changes changes}))))
(defn commit-changes
([changes undo-changes]
(commit-changes changes undo-changes {}))
([changes undo-changes {:keys [save-undo?
file-id]
:or {save-undo? true}
:as opts}]
[{:keys [redo-changes undo-changes origin save-undo? file-id]
:or {save-undo? true}}]
(log/debug :msg "commit-changes"
:js/changes changes
:js/undo-changes undo-changes)
(log/debug :msg "commit-changes"
:js/redo-changes redo-changes
:js/undo-changes undo-changes)
(let [error (volatile! nil)]
(ptk/reify ::commit-changes
cljs.core/IDeref
(-deref [_]
{:file-id file-id
:changes changes})
(let [error (volatile! nil)]
(ptk/reify ::commit-changes
cljs.core/IDeref
(-deref [_]
{:file-id file-id
:hint-events @st/last-events
:hint-origin (ptk/type origin)
:changes redo-changes})
ptk/UpdateEvent
(update [_ state]
(let [current-file-id (get state :current-file-id)
file-id (or file-id current-file-id)
path (if (= file-id current-file-id)
[:workspace-data]
[:workspace-libraries file-id :data])]
(try
(us/assert ::spec/changes changes)
(us/assert ::spec/changes undo-changes)
(update-in state path cp/process-changes changes false)
(catch :default e
(vreset! error e)
state))))
ptk/UpdateEvent
(update [_ state]
(let [current-file-id (get state :current-file-id)
file-id (or file-id current-file-id)
path (if (= file-id current-file-id)
[:workspace-data]
[:workspace-libraries file-id :data])]
(try
(us/assert ::spec/changes redo-changes)
(us/assert ::spec/changes undo-changes)
(update-in state path cp/process-changes redo-changes false)
(catch :default e
(vreset! error e)
state))))
ptk/WatchEvent
(watch [_ state stream]
(when-not @error
(let [;; adds page-id to page changes (that have the `id` field instead)
add-page-id
(fn [{:keys [id type page] :as change}]
(cond-> change
(page-change? type)
(assoc :page-id (or id (:id page)))))
ptk/WatchEvent
(watch [it state stream]
(when-not @error
(let [;; adds page-id to page changes (that have the `id` field instead)
add-page-id
(fn [{:keys [id type page] :as change}]
(cond-> change
(page-change? type)
(assoc :page-id (or id (:id page)))))
changes-by-pages
(->> changes
(map add-page-id)
(remove #(nil? (:page-id %)))
(group-by :page-id))
changes-by-pages
(->> redo-changes
(map add-page-id)
(remove #(nil? (:page-id %)))
(group-by :page-id))
process-page-changes
(fn [[page-id changes]]
(update-indices page-id changes))]
(rx/concat
(rx/from (map process-page-changes changes-by-pages))
process-page-changes
(fn [[page-id changes]]
(update-indices page-id redo-changes))]
(rx/concat
(rx/from (map process-page-changes changes-by-pages))
(when (and save-undo? (seq undo-changes))
(let [entry {:undo-changes undo-changes
:redo-changes changes}]
(rx/of (dwu/append-undo entry))))))))))))
(when (and save-undo? (seq undo-changes))
(let [entry {:undo-changes undo-changes
:redo-changes redo-changes}]
(rx/of (dwu/append-undo entry)))))))))))

View file

@ -40,7 +40,7 @@
[{:keys [file] :as bundle}]
(ptk/reify ::setup-selection-index
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [msg {:cmd :initialize-indices
:file-id (:id file)
:data (:data file)}]
@ -112,7 +112,7 @@
(def undo
(ptk/reify ::undo
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [edition (get-in state [:workspace-local :edition])
drawing (get state :workspace-drawing)]
;; Editors handle their own undo's
@ -123,12 +123,15 @@
(when-not (or (empty? items) (= index -1))
(let [changes (get-in items [index :undo-changes])]
(rx/of (dwu/materialize-undo changes (dec index))
(dch/commit-changes changes [] {:save-undo? false}))))))))))
(dch/commit-changes {:redo-changes changes
:undo-changes []
:save-undo? false
:origin it}))))))))))
(def redo
(ptk/reify ::redo
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [edition (get-in state [:workspace-local :edition])
drawing (get state :workspace-drawing)]
(when-not (or (some? edition) (not-empty drawing))
@ -138,7 +141,10 @@
(when-not (or (empty? items) (= index (dec (count items))))
(let [changes (get-in items [(inc index) :redo-changes])]
(rx/of (dwu/materialize-undo changes (inc index))
(dch/commit-changes changes [] {:save-undo? false}))))))))))
(dch/commit-changes {:redo-changes changes
:undo-changes []
:origin it
:save-undo? false}))))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shapes
@ -174,7 +180,7 @@
(assoc-in state [:workspace-local :selected] ids))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)]
(rx/of (expand-all-parents ids objects))))))
@ -196,7 +202,7 @@
state)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)]
(->> stream
(rx/filter interrupt?)
@ -276,7 +282,7 @@
(us/verify ::shape-attrs attrs)
(ptk/reify ::add-shape
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -296,7 +302,9 @@
(assoc :name name)))]
(rx/concat
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(select-shapes (d/ordered-set id)))
(when (= :text (:type attrs))
(->> (rx/of (start-edition-mode id))
@ -305,7 +313,7 @@
(defn move-shapes-into-frame [frame-id shapes]
(ptk/reify ::move-shapes-into-frame
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
to-move-shapes (->> (cp/select-toplevel-shapes objects {:include-frames? false})
@ -329,14 +337,16 @@
:page-id page-id
:index index
:shapes [shape-id]})))]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
(defn delete-shapes
[ids]
(us/assert (s/coll-of ::us/uuid) ids)
(ptk/reify ::delete-shapes
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -460,8 +470,9 @@
;; (cljs.pprint/pprint rchanges)
;; (println "================ uchanges")
;; (cljs.pprint/pprint uchanges)
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
;; --- Add shape to Workspace
@ -474,7 +485,7 @@
[type frame-x frame-y data]
(ptk/reify ::create-and-add-shape
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [{:keys [width height]} data
[vbc-x vbc-y] (viewport-center state)
@ -494,7 +505,7 @@
[image {:keys [x y]}]
(ptk/reify ::image-uploaded
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [{:keys [name width height id mtype]} image
shape {:name name
:width width

View file

@ -40,7 +40,7 @@
(us/assert ::us/uuid frame-id)
(ptk/reify ::add-frame-grid
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
data (get-in state [:workspace-data :pages-index page-id])
params (or (get-in data [:options :saved-grids :square])
@ -56,29 +56,30 @@
[frame-id index]
(ptk/reify ::set-frame-grid
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rx/of (dch/update-shapes [frame-id] (fn [o] (update o :grids (fnil #(d/remove-at-index % index) []))))))))
(defn set-frame-grid
[frame-id index data]
(ptk/reify ::set-frame-grid
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rx/of (dch/update-shapes [frame-id] #(assoc-in % [:grids index] data))))))
(defn set-default-grid
[type params]
(ptk/reify ::set-default-grid
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [pid (:current-page-id state)
prev-value (get-in state [:workspace-data :pages-index pid :options :saved-grids type])]
(rx/of (dch/commit-changes [{:type :set-option
:page-id pid
:option [:saved-grids type]
:value params}]
[{:type :set-option
:page-id pid
:option [:saved-grids type]
:value prev-value}]
{:commit-local? true}))))))
(rx/of (dch/commit-changes
{:redo-changes [{:type :set-option
:page-id pid
:option [:saved-grids type]
:value params}]
:undo-changes [{:type :set-option
:page-id pid
:option [:saved-grids type]
:value prev-value}]
:origin it}))))))

View file

@ -100,7 +100,7 @@
(def group-selected
(ptk/reify ::group-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
@ -108,13 +108,15 @@
shapes (shapes-for-grouping objects selected)]
(when-not (empty? shapes)
(let [[group rchanges uchanges] (prepare-create-group page-id shapes "Group-" false)]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(dwc/select-shapes (d/ordered-set (:id group))))))))))
(def ungroup-selected
(ptk/reify ::ungroup-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
@ -124,12 +126,14 @@
(= (:type group) :group))
(let [[rchanges uchanges]
(prepare-remove-group page-id group objects)]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))))
(def mask-group
(ptk/reify ::mask-group
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
@ -178,13 +182,15 @@
:page-id page-id
:shapes [(:id group)]})]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(dwc/select-shapes (d/ordered-set (:id group))))))))))
(def unmask-group
(ptk/reify ::unmask-group
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)]
@ -211,7 +217,9 @@
:page-id page-id
:shapes [(:id group)]}]]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(dwc/select-shapes (d/ordered-set (:id group))))))))))

View file

@ -86,23 +86,26 @@
(us/assert ::cp/color color)
(ptk/reify ::add-color
ptk/WatchEvent
(watch [_ state s]
(watch [it state s]
(let [rchg {:type :add-color
:color color}
uchg {:type :del-color
:id id}]
(rx/of #(assoc-in % [:workspace-local :color-for-rename] id)
(dch/commit-changes [rchg] [uchg] {:commit-local? true})))))))
(dch/commit-changes {:redo-changes [rchg]
:undo-chages [uchg]
:origin it})))))))
(defn add-recent-color
[color]
(us/assert ::cp/recent-color color)
(ptk/reify ::add-recent-color
ptk/WatchEvent
(watch [_ state s]
(watch [it state s]
(let [rchg {:type :add-recent-color
:color color}]
(rx/of (dch/commit-changes [rchg] [] {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-chages []
:origin it}))))))
(def clear-color-for-rename
(ptk/reify ::clear-color-for-rename
@ -116,13 +119,15 @@
(us/assert ::us/uuid file-id)
(ptk/reify ::update-color
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [prev (get-in state [:workspace-data :colors id])
rchg {:type :mod-color
:color color}
uchg {:type :mod-color
:color prev}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-chages [uchg]
:origin it})
(sync-file (:current-file-id state) file-id))))))
(defn delete-color
@ -130,26 +135,30 @@
(us/assert ::us/uuid id)
(ptk/reify ::delete-color
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [prev (get-in state [:workspace-data :colors id])
rchg {:type :del-color
:id id}
uchg {:type :add-color
:color prev}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-chages [uchg]
:origin it}))))))
(defn add-media
[{:keys [id] :as media}]
(us/assert ::cp/media-object media)
(ptk/reify ::add-media
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [obj (select-keys media [:id :name :width :height :mtype])
rchg {:type :add-media
:object obj}
uchg {:type :del-media
:id id}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it}))))))
(defn rename-media
[id new-name]
@ -157,7 +166,7 @@
(us/assert ::us/string new-name)
(ptk/reify ::rename-media
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [object (get-in state [:workspace-data :media id])
[path name] (cp/parse-path-name new-name)
@ -171,20 +180,24 @@
:name (:name object)
:path (:path object)}}]]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
(defn delete-media
[{:keys [id] :as params}]
(us/assert ::us/uuid id)
(ptk/reify ::delete-media
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [prev (get-in state [:workspace-data :media id])
rchg {:type :del-media
:id id}
uchg {:type :add-media
:object prev}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it}))))))
(defn add-typography
([typography] (add-typography typography true))
@ -193,12 +206,14 @@
(us/assert ::cp/typography typography)
(ptk/reify ::add-typography
ptk/WatchEvent
(watch [_ state s]
(watch [it state s]
(let [rchg {:type :add-typography
:typography typography}
uchg {:type :del-typography
:id (:id typography)}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it})
#(cond-> %
edit?
(assoc-in [:workspace-local :rename-typography] (:id typography))))))))))
@ -209,13 +224,15 @@
(us/assert ::us/uuid file-id)
(ptk/reify ::update-typography
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [prev (get-in state [:workspace-data :typographies (:id typography)])
rchg {:type :mod-typography
:typography typography}
uchg {:type :mod-typography
:typography prev}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it})
(sync-file (:current-file-id state) file-id))))))
(defn delete-typography
@ -223,19 +240,21 @@
(us/assert ::us/uuid id)
(ptk/reify ::delete-typography
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [prev (get-in state [:workspace-data :typographies id])
rchg {:type :del-typography
:id id}
uchg {:type :add-typography
:typography prev}]
(rx/of (dch/commit-changes [rchg] [uchg] {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes [rchg]
:undo-changes [uchg]
:origin it}))))))
(def add-component
"Add a new component to current file library, from the currently selected shapes."
(ptk/reify ::add-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [file-id (:current-file-id state)
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -244,7 +263,9 @@
(let [[group rchanges uchanges]
(dwlh/generate-add-component selected objects page-id file-id)]
(when-not (empty? rchanges)
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(dwc/select-shapes (d/ordered-set (:id group))))))))))
(defn rename-component
@ -254,7 +275,7 @@
(us/assert ::us/string new-name)
(ptk/reify ::rename-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [[path name] (cp/parse-path-name new-name)
component (get-in state [:workspace-data :components id])
objects (get component :objects)
@ -275,14 +296,16 @@
:path (:path component)
:objects objects}]]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
(defn duplicate-component
"Create a new component copied from the one with the given id."
[{:keys [id] :as params}]
(ptk/reify ::duplicate-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [component (cp/get-component id
(:current-file-id state)
(dwlh/get-local-file state)
@ -303,7 +326,9 @@
uchanges [{:type :del-component
:id (:id new-shape)}]]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
(defn delete-component
"Delete the component with the given id, from the current file library."
@ -311,7 +336,7 @@
(us/assert ::us/uuid id)
(ptk/reify ::delete-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [component (get-in state [:workspace-data :components id])
rchanges [{:type :del-component
@ -323,7 +348,9 @@
:path (:path component)
:shapes (vals (:objects component))}]]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
(defn instantiate-component
"Create a new shape in the current page, from the component with the given id
@ -334,7 +361,7 @@
(us/assert ::us/point position)
(ptk/reify ::instantiate-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [local-library (dwlh/get-local-file state)
libraries (get state :workspace-libraries)
component (cp/get-component component-id file-id local-library libraries)
@ -400,7 +427,9 @@
:ignore-touched true})
new-shapes)]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(dwc/select-shapes (d/ordered-set (:id new-shape))))))))
(defn detach-component
@ -410,7 +439,7 @@
(us/assert ::us/uuid id)
(ptk/reify ::detach-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
shapes (cp/get-object-with-children id objects)
@ -463,14 +492,16 @@
:val (:touched obj)}]})
shapes)]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
(defn nav-to-component-file
[file-id]
(us/assert ::us/uuid file-id)
(ptk/reify ::nav-to-component-file
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [file (get-in state [:workspace-libraries file-id])
pparams {:project-id (:project-id file)
:file-id (:id file)}
@ -499,7 +530,7 @@
(us/assert ::us/uuid id)
(ptk/reify ::reset-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(log/info :msg "RESET-COMPONENT of shape" :id (str id))
(let [local-library (dwlh/get-local-file state)
libraries (dwlh/get-libraries state)
@ -516,7 +547,9 @@
rchanges
local-library))
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true}))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
(defn update-component
"Modify the component linked to the shape with the given id, in the
@ -531,7 +564,7 @@
(us/assert ::us/uuid id)
(ptk/reify ::update-component
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(log/info :msg "UPDATE-COMPONENT of shape" :id (str id))
(let [page-id (get state :current-page-id)
local-library (dwlh/get-local-file state)
@ -571,12 +604,14 @@
file))
(rx/of (when (seq local-rchanges)
(dch/commit-changes local-rchanges local-uchanges
{:commit-local? true
(dch/commit-changes {:redo-changes local-rchanges
:undo-changes local-uchanges
:origin it
:file-id (:id local-library)}))
(when (seq rchanges)
(dch/commit-changes rchanges uchanges
{:commit-local? true
(dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it
:file-id file-id})))))))
(declare sync-file-2nd-stage)
@ -597,7 +632,7 @@
state))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(log/info :msg "SYNC-FILE"
:file (dwlh/pretty-file file-id state)
:library (dwlh/pretty-file library-id state))
@ -625,8 +660,10 @@
(rx/concat
(rx/of (dm/hide-tag :sync-dialog))
(when rchanges
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true
:file-id file-id})))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it
: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.
@ -655,7 +692,7 @@
(us/assert ::us/uuid library-id)
(ptk/reify ::sync-file-2nd-stage
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(log/info :msg "SYNC-FILE (2nd stage)"
:file (dwlh/pretty-file file-id state)
:library (dwlh/pretty-file library-id state))
@ -668,8 +705,10 @@
(log/debug :msg "SYNC-FILE (2nd stage) finished" :js/rchanges (log-changes
rchanges
file))
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true
:file-id file-id})))))))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it
:file-id file-id})))))))
(def ignore-sync
(ptk/reify ::ignore-sync
@ -678,7 +717,7 @@
(assoc-in state [:workspace-file :ignore-sync-until] (dt/now)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rp/mutation :ignore-sync
{:file-id (get-in state [:workspace-file :id])
:date (dt/now)}))))
@ -688,7 +727,7 @@
(us/assert ::us/uuid file-id)
(ptk/reify ::notify-sync-file
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [libraries-need-sync (filter #(> (:modified-at %) (:synced-at %))
(vals (get state :workspace-libraries)))
do-update #(do (apply st/emit! (map (fn [library]

View file

@ -84,7 +84,7 @@
(assoc-in state (st/get-path state :content) content)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)
page-id (:current-page-id state)
id (get-in state [:workspace-local :edition])
@ -92,7 +92,9 @@
(if (some? old-content)
(let [shape (get-in state (st/get-path state))
[rch uch] (generate-path-changes objects page-id shape old-content (:content shape))]
(rx/of (dch/commit-changes rch uch)))
(rx/of (dch/commit-changes {:redo-changes rch
:undo-changes uch
:origin it})))
(rx/empty)))))))

View file

@ -47,7 +47,7 @@
(defn apply-content-modifiers []
(ptk/reify ::apply-content-modifiers
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)
id (st/get-path-id state)
@ -65,9 +65,13 @@
[rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)]
(if (empty? new-content)
(rx/of (dch/commit-changes rch uch {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rch
:undo-changes uch
:origin it})
dwc/clear-edition-mode)
(rx/of (dch/commit-changes rch uch {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rch
:undo-changes uch
:origin it})
(selection/update-selection point-change)
(fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers :moving-nodes :moving-handler))))))))
@ -133,7 +137,7 @@
[position shift?]
(ptk/reify ::start-move-path-point
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [id (get-in state [:workspace-local :edition])
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
selected? (contains? selected-points position)]
@ -147,7 +151,7 @@
[start-position]
(ptk/reify ::drag-selected-points
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [stopper (->> stream (rx/filter ms/mouse-up?))
id (get-in state [:workspace-local :edition])
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
@ -202,7 +206,7 @@
state)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [id (get-in state [:workspace-local :edition])
current-move (get-in state [:workspace-local :edit-path id :current-move])]
(if (= same-event current-move)
@ -236,7 +240,7 @@
[index prefix]
(ptk/reify ::start-move-handler
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [id (get-in state [:workspace-local :edition])
cx (d/prefix-keyword prefix :x)
cy (d/prefix-keyword prefix :y)
@ -292,7 +296,7 @@
(assoc-in [:workspace-local :edit-path id :edit-mode] :draw))))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [mode (get-in state [:workspace-local :edit-path id :edit-mode])]
(rx/concat
(rx/of (undo/start-path-undo))
@ -322,5 +326,5 @@
(update-in (st/get-path state :content) upt/split-segments #{from-p to-p} t))))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rx/of (changes/save-path-content {:preserve-move-to true})))))

View file

@ -25,7 +25,7 @@
([points tool-fn]
(ptk/reify ::process-path-tool
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)
id (st/get-path-id state)
page-id (:current-page-id state)
@ -37,7 +37,9 @@
(let [new-content (-> (tool-fn (:content shape) points)
(ups/close-subpaths))
[rch uch] (changes/generate-path-changes objects page-id shape (:content shape) new-content)]
(rx/of (dch/commit-changes rch uch {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rch
:undo-changes uch
:origin it})
(when (empty? new-content)
dwc/clear-edition-mode)))))))))

View file

@ -86,9 +86,11 @@
(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/map (fn [buf]
(->> (into [] (comp (map #(assoc % :id (uuid/next)))
(map #(assoc % :file-id file-id)))
buf)
(persist-changes file-id))))
(rx/tap on-saving)
(rx/take-until (rx/delay 100 stoper)))
(->> stream
@ -109,27 +111,25 @@
(on-saved))))))))
(defn persist-changes
[{:keys [file-id changes]}]
[file-id changes]
(us/verify ::us/uuid file-id)
(ptk/reify ::persist-changes
ptk/UpdateEvent
(update [_ state]
(let [conj (fnil conj [])
chng {:id (uuid/next)
:changes changes}]
(update-in state [:workspace-persistence :queue] conj chng)))
(let [conj (fnil conj [])
into* (fnil into [])]
(update-in state [:workspace-persistence :queue] into* changes)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [sid (:session-id state)
file (get state :workspace-file)
queue (get-in state [:workspace-persistence :queue] [])
xf-cat (comp (mapcat :changes))
params {:id (:id file)
:revn (:revn file)
:session-id sid
:changes (into [] xf-cat queue)}
:changes-with-metadata (into [] queue)}
ids (into #{} (map :id) queue)
@ -172,7 +172,7 @@
(us/verify ::us/uuid file-id)
(ptk/reify ::persist-synchronous-changes
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [sid (:session-id state)
file (get-in state [:workspace-libraries file-id])
@ -255,7 +255,7 @@
[project-id file-id]
(ptk/reify ::fetch-bundle
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(->> (rx/zip (rp/query :file {:id file-id})
(rp/query :team-users {:file-id file-id})
(rp/query :project {:id project-id})
@ -295,7 +295,7 @@
(assoc-in state [:workspace-file :is-shared] is-shared))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [params {:id id :is-shared is-shared}]
(->> (rp/mutation :set-file-shared params)
(rx/ignore))))))
@ -330,7 +330,7 @@
[file-id library-id]
(ptk/reify ::link-file-to-library
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [fetched #(assoc-in %2 [:workspace-libraries (:id %1)] %1)
params {:file-id file-id
:library-id library-id}]
@ -342,7 +342,7 @@
[file-id library-id]
(ptk/reify ::unlink-file-from-library
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [unlinked #(d/dissoc-in % [:workspace-libraries library-id])
params {:file-id file-id
:library-id library-id}]
@ -358,7 +358,7 @@
(us/verify ::us/uuid page-id)
(ptk/reify ::fetch-pages
ptk/WatchEvent
(watch [_ state s]
(watch [it state s]
(->> (rp/query :page {:id page-id})
(rx/map page-fetched)))))
@ -498,7 +498,7 @@
(us/assert ::process-media-objects params)
(ptk/reify ::process-media-objects
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(rx/concat
(rx/of (dm/show {:content (tr "media.loading")
:type :info
@ -545,7 +545,7 @@
(us/assert ::clone-media-objects-params params)
(ptk/reify ::clone-media-objects
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [{:keys [on-success on-error]
:or {on-success identity
on-error identity}} (meta params)

View file

@ -378,11 +378,12 @@
(def duplicate-selected
(ptk/reify ::duplicate-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
delta (gpt/point 0 0)
unames (dwc/retrieve-used-names objects)
rchanges (->> (prepare-duplicate-changes objects page-id unames selected delta)
@ -396,7 +397,9 @@
(map #(get-in % [:obj :id]))
(into (d/ordered-set)))]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(select-shapes selected))))))
(defn change-hover-state

View file

@ -387,7 +387,7 @@
[svg-data file-id position]
(ptk/reify ::svg-uploaded
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
;; Once the SVG is uploaded, we need to extract all the bitmap
;; images and upload them separatelly, then proceed to create
;; all shapes.
@ -414,7 +414,7 @@
[svg-data {:keys [x y] :as position}]
(ptk/reify ::create-svg-shapes
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(try
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -464,7 +464,9 @@
rchanges (conj rchanges reg-objects-action)]
(rx/of (dch/commit-changes rchanges uchanges {:commit-local? true})
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it})
(dwc/select-shapes (d/ordered-set root-id))))
(catch :default e

View file

@ -141,7 +141,7 @@
(assoc-in [:workspace-local :transform] :resize)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [initial-position @ms/mouse-position
stoper (rx/filter ms/mouse-up? stream)
layout (:workspace-layout state)
@ -175,7 +175,7 @@
(assoc-in [:workspace-local :transform] :rotate)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [stoper (rx/filter ms/mouse-up? stream)
group (gsh/selection-rect shapes)
group-center (gsh/center-selrect group)
@ -214,7 +214,7 @@
[]
(ptk/reify ::start-move-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [initial (deref ms/mouse-position)
selected (wsh/lookup-selected state)
stopper (rx/filter ms/mouse-up? stream)]
@ -237,7 +237,7 @@
(defn start-move-duplicate [from-position]
(ptk/reify ::start-move-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(->> stream
(rx/filter (ptk/type? ::dws/duplicate-selected))
(rx/first)
@ -246,7 +246,7 @@
(defn calculate-frame-for-move [ids]
(ptk/reify ::calculate-frame-for-move
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [position @ms/mouse-position
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -273,7 +273,9 @@
(when-not (empty? uch)
(rx/of dwu/pop-undo-into-transaction
(dch/commit-changes rch uch {:commit-local? true})
(dch/commit-changes {:redo-changes rch
:undo-changes uch
:origin it})
(dwu/commit-undo-transaction)
(dwc/expand-collapse frame-id)))))))
@ -287,7 +289,7 @@
(assoc-in [:workspace-local :transform] :move)))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
ids (if (nil? ids) (wsh/lookup-selected state) ids)
@ -368,7 +370,7 @@
state))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(if (= same-event (get-in state [:workspace-local :current-move-selected]))
(let [selected (wsh/lookup-selected state)
move-events (->> stream
@ -455,7 +457,7 @@
(defn increase-rotation [ids rotation]
(ptk/reify ::increase-rotation
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -471,7 +473,7 @@
(us/verify (s/coll-of uuid?) ids)
(ptk/reify ::apply-modifiers
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)
children-ids (->> ids (mapcat #(cp/get-children % objects)))
ids-with-children (d/concat [] children-ids ids)]
@ -517,7 +519,7 @@
#(reduce update-shape % ids))))
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
ids (d/concat [] ids (mapcat #(cp/get-children % objects) ids))]
@ -526,7 +528,7 @@
(defn flip-horizontal-selected []
(ptk/reify ::flip-horizontal-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state)
shapes (map #(get objects %) selected)
@ -543,7 +545,7 @@
(defn flip-vertical-selected []
(ptk/reify ::flip-vertical-selected
ptk/WatchEvent
(watch [_ state stream]
(watch [it state stream]
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state)
shapes (map #(get objects %) selected)

View file

@ -23,6 +23,21 @@
(defonce state (ptk/store {:resolve ptk/resolve}))
(defonce stream (ptk/input-stream state))
(defonce last-events
(let [buffer (atom #queue [])
remove #{:potok.core/undefined
:app.main.data.workspace.notifications/handle-pointer-update}]
(->> stream
(rx/filter ptk/event?)
(rx/map ptk/type)
(rx/filter (complement remove))
(rx/map str)
(rx/dedupe)
(rx/buffer 20 1)
(rx/subs #(reset! buffer %)))
buffer))
(when *assert*
(defonce debug-subscription
(->> stream
@ -47,6 +62,9 @@
(defn ^:export dump-state []
(logjs "state" @state))
(defn ^:export dump-buffer []
(logjs "state" @last-events))
(defn ^:export get-state [str-path]
(let [path (->> (str/split str-path " ")
(map d/read-string))]