0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-10 14:51:37 -05:00

🎉 Update components leaving touched attrs

This commit is contained in:
Andrés Moya 2020-09-23 14:27:35 +02:00 committed by Andrey Antukh
parent 5e73da4bca
commit 880091a4f7
6 changed files with 167 additions and 86 deletions

View file

@ -213,6 +213,33 @@
:internal.shape/selrect
:internal.shape/points]))
(def sync-attrs {:fill-color :fill-group
:fill-color-ref-file :fill-group
:fill-color-ref-id :fill-group
:fill-opacity :fill-group
:content :text-content-group
:font-family :text-font-group
:font-size :text-font-group
:font-style :text-font-group
:font-weight :text-font-group
:letter-spacing :text-display-group
:line-height :text-display-group
:text-align :text-display-group
:stroke-color :stroke-group
:stroke-color-ref-file :stroke-group
:stroke-color-ref-id :stroke-group
:stroke-opacity :stroke-group
:stroke-style :stroke-group
:stroke-width :stroke-group
:stroke-alignment :stroke-group
:width :size-group
:height :size-group
:proportion :size-group
:rx :radius-group
:ry :radius-group
:points :points-group
:transform :transform-group})
(s/def ::minimal-shape
(s/keys :req-un [::type ::name]
:opt-un [::id]))
@ -286,11 +313,16 @@
(s/def :internal.operations.set/attr keyword?)
(s/def :internal.operations.set/val any?)
(s/def :internal.operations.set/touched
(s/nilable (s/every keyword? :kind set?)))
(defmethod operation-spec :set [_]
(s/keys :req-un [:internal.operations.set/attr
:internal.operations.set/val]))
(defmethod operation-spec :set-touched [_]
(s/keys :req-un [:internal.operations.set/touched]))
(defmulti change-spec :type)
(s/def :internal.changes.set-option/option any?)
@ -795,11 +827,29 @@
(defmethod process-operation :set
[shape op]
(let [attr (:attr op)
val (:val op)]
(if (nil? val)
(dissoc shape attr)
(assoc shape attr val))))
(let [attr (:attr op)
val (:val op)
ignore (:ignore-touched op)
shape-ref (:shape-ref shape)
group (get sync-attrs attr)]
(cond-> shape
(nil? val)
(dissoc attr)
(some? val)
(assoc attr val)
(and shape-ref group (not ignore))
(update :touched #(conj (or % #{}) group)))))
(defmethod process-operation :set-touched
[shape op]
(let [touched (:touched op)
shape-ref (:shape-ref shape)]
(if (or (nil? shape-ref) (nil? touched) (empty? touched))
(dissoc shape :touched)
(assoc shape :touched touched))))
(defmethod process-operation :default
[shape op]

View file

@ -186,7 +186,7 @@
updated-object (update-original-object object new-object)
updated-objects (if (= object updated-object)
updated-objects (if (identical? object updated-object)
updated-children
(concat [updated-object] updated-children))]

View file

@ -895,7 +895,7 @@
(let [curr (first moved)
prev (get objects (:id curr))
ops1 (dwc/generate-operations prev curr)
ops2 (dwc/generate-operations curr prev)]
ops2 (dwc/generate-operations curr prev true)]
(recur (next moved)
(conj rchanges {:type :mod-obj
:page-id page-id
@ -942,7 +942,7 @@
(let [curr (first moved)
prev (get objects (:id curr))
ops1 (dwc/generate-operations prev curr)
ops2 (dwc/generate-operations curr prev)]
ops2 (dwc/generate-operations curr prev true)]
(recur (next moved)
(conj rchanges {:type :mod-obj
:page-id page-id

View file

@ -86,28 +86,33 @@
(rx/of (append-undo entry))))))))))
(defn generate-operations
[ma mb]
(let [ma-keys (set (keys ma))
mb-keys (set (keys mb))
added (set/difference mb-keys ma-keys)
removed (set/difference ma-keys mb-keys)
both (set/intersection ma-keys mb-keys)]
(d/concat
(mapv #(array-map :type :set :attr % :val (get mb %)) added)
(mapv #(array-map :type :set :attr % :val nil) removed)
(loop [items (seq both)
result []]
(if items
(let [k (first items)
vma (get ma k)
vmb (get mb k)]
(if (= vma vmb)
(recur (next items) result)
(recur (next items)
(conj result {:type :set
:attr k
:val vmb}))))
result)))))
([ma mb] (generate-operations ma mb false))
([ma mb undo?]
(let [ops (let [ma-keys (set (keys ma))
mb-keys (set (keys mb))
added (set/difference mb-keys ma-keys)
removed (set/difference ma-keys mb-keys)
both (set/intersection ma-keys mb-keys)]
(d/concat
(mapv #(array-map :type :set :attr % :val (get mb %)) added)
(mapv #(array-map :type :set :attr % :val nil) removed)
(loop [items (seq both)
result []]
(if items
(let [k (first items)
vma (get ma k)
vmb (get mb k)]
(if (= vma vmb)
(recur (next items) result)
(recur (next items)
(conj result {:type :set
:attr k
:val vmb
:ignore-touched undo?}))))
result))))]
(if undo?
(conj ops {:type :set-touched :touched (:touched mb)})
ops))))
(defn generate-changes
[page-id objects1 objects2]
@ -415,7 +420,7 @@
obj1 (get objects id)
obj2 (f obj1)
rch-operations (generate-operations obj1 obj2)
uch-operations (generate-operations obj2 obj1)
uch-operations (generate-operations obj2 obj1 true)
rchg {:type :mod-obj
:page-id page-id
:operations rch-operations
@ -456,7 +461,7 @@
obj1 (get objects id)
obj2 (f obj1)
rops (generate-operations obj1 obj2)
uops (generate-operations obj2 obj1)
uops (generate-operations obj2 obj1 true)
rchg {:type :mod-obj
:page-id page-id
:operations rops

View file

@ -366,7 +366,6 @@
(declare remove-component-and-ref)
(declare remove-ref)
(declare update-attrs)
(declare sync-attrs)
(declare calc-new-pos)
(defn reset-component
@ -388,7 +387,7 @@
(get-in state [:workspace-libraries file-id :data :components]))
[rchanges uchanges]
(generate-sync-shape-and-children root-shape page components)]
(generate-sync-shape-and-children root-shape page components true)]
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
@ -418,18 +417,37 @@
(some? (:shape-ref original-shape))
(assoc :id (:shape-ref original-shape))))
[new-shape new-shapes _]
(cph/clone-object root-shape nil objects update-new-shape)
touch-shape (fn [original-shape _]
(into {} original-shape))
rchanges [{:type :mod-component
[new-shape new-shapes original-shapes]
(cph/clone-object root-shape nil objects update-new-shape touch-shape)
rchanges (concat
[{:type :mod-component
:id component-id
:name (:name new-shape)
:shapes new-shapes}]
(map (fn [shape]
{:type :mod-obj
:page-id page-id
:id (:id shape)
:operations [{:type :set-touched
:touched nil}]})
original-shapes))
uchanges [{:type :mod-component
:id component-id
:name (:name component-obj)
:shapes (vals component-objs)}]]
uchanges (concat
[{:type :mod-component
:id component-id
:name (:name component-obj)
:shapes (vals component-objs)}]
(map (fn [shape]
{:type :mod-obj
:page-id page-id
:id (:id shape)
:operations [{:type :set-touched
:touched (:touched shape)}]})
original-shapes))]
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
@ -520,13 +538,13 @@
(if (nil? shape)
[rchanges uchanges]
(let [[shape-rchanges shape-uchanges]
(generate-sync-shape-and-children shape page components)]
(generate-sync-shape-and-children shape page components false)]
(recur (next shapes)
(concat rchanges shape-rchanges)
(concat uchanges shape-uchanges))))))))
(defn- generate-sync-shape-and-children
[root-shape page components]
[root-shape page components reset-touched?]
(let [objects (get page :objects)
all-shapes (cph/get-object-with-children (:id root-shape) objects)
component (get components (:component-id root-shape))
@ -538,19 +556,24 @@
(if (nil? shape)
[rchanges uchanges]
(let [[shape-rchanges shape-uchanges]
(generate-sync-shape shape root-shape root-component page component)]
(generate-sync-shape shape root-shape root-component page component reset-touched?)]
(recur (next shapes)
(concat rchanges shape-rchanges)
(concat uchanges shape-uchanges))))))))
(defn- generate-sync-shape
[shape root-shape root-component page component]
[shape root-shape root-component page component reset-touched?]
(if (nil? component)
(remove-component-and-ref shape page)
(let [component-shape (get (:objects component) (:shape-ref shape))]
(if (nil? component-shape)
(remove-ref shape page)
(update-attrs shape component-shape root-shape root-component page)))))
(update-attrs shape
component-shape
root-shape
root-component
page
reset-touched?)))))
(defn- remove-component-and-ref
[shape page]
@ -565,7 +588,9 @@
:val nil}
{:type :set
:attr :shape-ref
:val nil}]}]
:val nil}
{:type :set-touched
:touched nil}]}]
[{:type :mod-obj
:page-id (:id page)
:id (:id shape)
@ -577,7 +602,9 @@
:val (:component-file shape)}
{:type :set
:attr :shape-ref
:val (:shape-ref shape)}]}]])
:val (:shape-ref shape)}
{:type :set-touched
:touched (:touched shape)}]}]])
(defn- remove-ref
[shape page]
@ -586,18 +613,22 @@
:id (:id shape)
:operations [{:type :set
:attr :shape-ref
:val nil}]}]
:val nil}
{:type :set-touched
:touched nil}]}]
[{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations [{:type :set
:attr :shape-ref
:val (:shape-ref shape)}]}]])
:val (:shape-ref shape)}
{:type :set-touched
:touched (:touched shape)}]}]])
(defn- update-attrs
[shape component-shape root-shape root-component page]
[shape component-shape root-shape root-component page reset-touched?]
(let [new-pos (calc-new-pos shape component-shape root-shape root-component)]
(loop [attrs (seq sync-attrs)
(loop [attrs (seq (keys cp/sync-attrs))
roperations [{:type :set
:attr :x
:val (:x new-pos)}
@ -613,7 +644,19 @@
(let [attr (first attrs)]
(if (nil? attr)
(let [rchanges [{:type :mod-obj
(let [roperations (if reset-touched?
(conj roperations
{:type :set-touched
:touched nil})
roperations)
uoperations (if reset-touched?
(conj uoperations
{:type :set-touched
:touched (:touched shape)})
uoperations)
rchanges [{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations roperations}]
@ -628,41 +671,22 @@
uoperations)
(let [roperation {:type :set
:attr attr
:val (get component-shape attr)}
:val (get component-shape attr)
:ignore-touched true}
uoperation {:type :set
:attr attr
:val (get shape attr)}]
(recur (next attrs)
(conj roperations roperation)
(conj uoperations uoperation)))))))))
:val (get shape attr)
:ignore-touched true}
(def sync-attrs [:content
:fill-color
:fill-color-ref-file
:fill-color-ref-id
:fill-opacity
:font-family
:font-size
:font-style
:font-weight
:letter-spacing
:line-height
:proportion
:rx
:ry
:stroke-color
:stroke-color-ref-file
:stroke-color-ref-id
:stroke-opacity
:stroke-style
:stroke-width
:stroke-alignment
:text-align
:width
:height
:interactions
:points
:transform])
attr-group (get cp/sync-attrs attr)
touched (get shape :touched #{})]
(if (or (not (touched attr-group)) reset-touched?)
(recur (next attrs)
(conj roperations roperation)
(conj uoperations uoperation))
(recur (next attrs)
roperations
uoperations)))))))))
(defn- calc-new-pos
[shape component-shape root-shape root-component]

View file

@ -34,7 +34,9 @@
[:div.undo-entry-change {:key (str "change-" idx-change)}
[:div.undo-entry-change-data (when type (str type)) " " (when id (str (get-in objects [id :name] (subs (str id) 0 8))))]
(when operations
[:div.undo-entry-change-data (str/join ", " (map (comp name :attr) operations))])])]))
[:div.undo-entry-change-data (str/join ", "
(map (comp name :attr)
(filter #(= (:type %) :set) operations)))])])]))
(mf/defc history-toolbox []
(let [locale (mf/deref i18n/locale)