♻️ Refactor delete-shapes event.

Properly handle parent deletion + performance.
This commit is contained in:
Andrey Antukh 2021-06-10 13:01:28 +02:00 committed by Alonso Torres
parent 6988ae83c9
commit 371c78b1d3

View file

@ -341,26 +341,18 @@
:undo-changes uchanges :undo-changes uchanges
:origin it})))))) :origin it}))))))
(s/def ::set-of-uuid
(s/every ::us/uuid :kind set?))
(defn delete-shapes (defn delete-shapes
[ids] [ids]
(us/assert (s/coll-of ::us/uuid) ids) (us/assert ::set-of-uuid ids)
(ptk/reify ::delete-shapes (ptk/reify ::delete-shapes
ptk/WatchEvent ptk/WatchEvent
(watch [it state stream] (watch [it state stream]
(let [page-id (:current-page-id state) (let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id) objects (wsh/lookup-page-objects state page-id)
get-empty-parents
(fn [parents]
(->> parents
(map (fn [id]
(let [obj (get objects id)]
(when (and (= :group (:type obj))
(= 1 (count (:shapes obj))))
obj))))
(take-while (complement nil?))
(map :id)))
groups-to-unmask groups-to-unmask
(reduce (fn [group-ids id] (reduce (fn [group-ids id]
;; When the shape to delete is the mask of a masked group, ;; When the shape to delete is the mask of a masked group,
@ -381,90 +373,117 @@
(some ids (map :destination interactions)))) (some ids (map :destination interactions))))
(vals objects)) (vals objects))
rchanges empty-parents-xform
(d/concat (comp
(reduce (fn [res id] (map (fn [id] (get objects id)))
(let [children (cp/get-children id objects) (map (fn [{:keys [shapes type] :as obj}]
parents (cp/get-parents id objects) (when (and (= :group type)
del-change #(array-map (zero? (count (remove #(contains? ids %) shapes))))
:type :del-obj obj)))
:page-id page-id (take-while some?)
:id %)] (map :id))
(d/concat res
(map del-change (reverse children))
[(del-change id)]
(map del-change (get-empty-parents parents))
[{:type :reg-objects
:page-id page-id
:shapes (vec parents)}])))
[]
ids)
(map #(array-map
:type :mod-obj
:page-id page-id
:id %
:operations [{:type :set
:attr :masked-group?
:val false}])
groups-to-unmask)
(map #(array-map
:type :mod-obj
:page-id page-id
:id (:id %)
:operations [{:type :set
:attr :interactions
:val (vec (remove (fn [interaction]
(contains? ids (:destination interaction)))
(:interactions %)))}])
interacting-shapes))
all-parents
(reduce (fn [res id]
(into res (cp/get-parents id objects)))
(d/ordered-set)
ids)
all-children
(reduce (fn [res id]
(into res (cp/get-children id objects)))
(d/ordered-set)
ids)
empty-parents
(into (d/ordered-set) empty-parents-xform all-parents)
mk-del-obj-xf
(map (fn [id]
{:type :del-obj
:page-id page-id
:id id}))
mk-add-obj-xf
(map (fn [id]
(let [item (get objects id)]
{:type :add-obj
:id (:id item)
:page-id page-id
:index (cp/position-on-parent id objects)
:frame-id (:frame-id item)
:parent-id (:parent-id item)
:obj item})))
mk-mod-touched-xf
(map (fn [id]
(let [parent (get objects id)]
{:type :mod-obj
:page-id page-id
:id (:id parent)
:operations [{:type :set-touched
:touched (:touched parent)}]})))
mk-mod-int-del-xf
(map (fn [obj]
{:type :mod-obj
:page-id page-id
:id (:id obj)
:operations [{:type :set
:attr :interactions
:val (vec (remove (fn [interaction]
(contains? ids (:destination interaction)))
(:interactions obj)))}]}))
mk-mod-int-add-xf
(map (fn [obj]
{:type :mod-obj
:page-id page-id
:id (:id obj)
:operations [{:type :set
:attr :interactions
:val (:interactions obj)}]}))
mk-mod-unmask-xf
(map (fn [id]
{:type :mod-obj
:page-id page-id
:id id
:operations [{:type :set
:attr :masked-group?
:val false}]}))
mk-mod-mask-xf
(map (fn [id]
{:type :mod-obj
:page-id page-id
:id id
:operations [{:type :set
:attr :masked-group?
:val true}]}))
rchanges
(-> []
(into mk-del-obj-xf all-children)
(into mk-del-obj-xf ids)
(into mk-del-obj-xf empty-parents)
(conj {:type :reg-objects
:page-id page-id
:shapes (vec all-parents)})
(into mk-mod-unmask-xf groups-to-unmask)
(into mk-mod-int-del-xf interacting-shapes))
uchanges uchanges
(d/concat (-> []
(reduce (fn [res id] (into mk-add-obj-xf (reverse empty-parents))
(let [children (cp/get-children id objects) (into mk-add-obj-xf (reverse ids))
parents (cp/get-parents id objects) (into mk-add-obj-xf (reverse all-children))
parent (get objects (first parents)) (conj {:type :reg-objects
add-change (fn [id] :page-id page-id
(let [item (get objects id)] :shapes (vec all-parents)})
{:type :add-obj (into mk-mod-touched-xf (reverse all-parents))
:id (:id item) (into mk-mod-mask-xf groups-to-unmask)
:page-id page-id (into mk-mod-int-add-xf interacting-shapes))
:index (cp/position-on-parent id objects) ]
:frame-id (:frame-id item)
:parent-id (:parent-id item)
:obj item}))]
(d/concat res
(map add-change (reverse (get-empty-parents parents)))
[(add-change id)]
(map add-change children)
[{:type :reg-objects
:page-id page-id
:shapes (vec parents)}]
(when (some? parent)
[{:type :mod-obj
:page-id page-id
:id (:id parent)
:operations [{:type :set-touched
:touched (:touched parent)}]}]))))
[]
ids)
(map #(array-map
:type :mod-obj
:page-id page-id
:id %
:operations [{:type :set
:attr :masked-group?
:val true}])
groups-to-unmask)
(map #(array-map
:type :mod-obj
:page-id page-id
:id (:id %)
:operations [{:type :set
:attr :interactions
:val (:interactions %)}])
interacting-shapes))]
;; (println "================ rchanges") ;; (println "================ rchanges")
;; (cljs.pprint/pprint rchanges) ;; (cljs.pprint/pprint rchanges)