mirror of
https://github.com/penpot/penpot.git
synced 2025-06-10 22:31:39 +02:00
🎉 Update components leaving touched attrs
This commit is contained in:
parent
5e73da4bca
commit
880091a4f7
6 changed files with 167 additions and 86 deletions
|
@ -213,6 +213,33 @@
|
||||||
:internal.shape/selrect
|
:internal.shape/selrect
|
||||||
:internal.shape/points]))
|
: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/def ::minimal-shape
|
||||||
(s/keys :req-un [::type ::name]
|
(s/keys :req-un [::type ::name]
|
||||||
:opt-un [::id]))
|
:opt-un [::id]))
|
||||||
|
@ -286,11 +313,16 @@
|
||||||
|
|
||||||
(s/def :internal.operations.set/attr keyword?)
|
(s/def :internal.operations.set/attr keyword?)
|
||||||
(s/def :internal.operations.set/val any?)
|
(s/def :internal.operations.set/val any?)
|
||||||
|
(s/def :internal.operations.set/touched
|
||||||
|
(s/nilable (s/every keyword? :kind set?)))
|
||||||
|
|
||||||
(defmethod operation-spec :set [_]
|
(defmethod operation-spec :set [_]
|
||||||
(s/keys :req-un [:internal.operations.set/attr
|
(s/keys :req-un [:internal.operations.set/attr
|
||||||
:internal.operations.set/val]))
|
:internal.operations.set/val]))
|
||||||
|
|
||||||
|
(defmethod operation-spec :set-touched [_]
|
||||||
|
(s/keys :req-un [:internal.operations.set/touched]))
|
||||||
|
|
||||||
(defmulti change-spec :type)
|
(defmulti change-spec :type)
|
||||||
|
|
||||||
(s/def :internal.changes.set-option/option any?)
|
(s/def :internal.changes.set-option/option any?)
|
||||||
|
@ -795,11 +827,29 @@
|
||||||
|
|
||||||
(defmethod process-operation :set
|
(defmethod process-operation :set
|
||||||
[shape op]
|
[shape op]
|
||||||
(let [attr (:attr op)
|
(let [attr (:attr op)
|
||||||
val (:val op)]
|
val (:val op)
|
||||||
(if (nil? val)
|
ignore (:ignore-touched op)
|
||||||
(dissoc shape attr)
|
shape-ref (:shape-ref shape)
|
||||||
(assoc shape attr val))))
|
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
|
(defmethod process-operation :default
|
||||||
[shape op]
|
[shape op]
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
|
|
||||||
updated-object (update-original-object object new-object)
|
updated-object (update-original-object object new-object)
|
||||||
|
|
||||||
updated-objects (if (= object updated-object)
|
updated-objects (if (identical? object updated-object)
|
||||||
updated-children
|
updated-children
|
||||||
(concat [updated-object] updated-children))]
|
(concat [updated-object] updated-children))]
|
||||||
|
|
||||||
|
|
|
@ -895,7 +895,7 @@
|
||||||
(let [curr (first moved)
|
(let [curr (first moved)
|
||||||
prev (get objects (:id curr))
|
prev (get objects (:id curr))
|
||||||
ops1 (dwc/generate-operations prev curr)
|
ops1 (dwc/generate-operations prev curr)
|
||||||
ops2 (dwc/generate-operations curr prev)]
|
ops2 (dwc/generate-operations curr prev true)]
|
||||||
(recur (next moved)
|
(recur (next moved)
|
||||||
(conj rchanges {:type :mod-obj
|
(conj rchanges {:type :mod-obj
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
|
@ -942,7 +942,7 @@
|
||||||
(let [curr (first moved)
|
(let [curr (first moved)
|
||||||
prev (get objects (:id curr))
|
prev (get objects (:id curr))
|
||||||
ops1 (dwc/generate-operations prev curr)
|
ops1 (dwc/generate-operations prev curr)
|
||||||
ops2 (dwc/generate-operations curr prev)]
|
ops2 (dwc/generate-operations curr prev true)]
|
||||||
(recur (next moved)
|
(recur (next moved)
|
||||||
(conj rchanges {:type :mod-obj
|
(conj rchanges {:type :mod-obj
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
|
|
|
@ -86,28 +86,33 @@
|
||||||
(rx/of (append-undo entry))))))))))
|
(rx/of (append-undo entry))))))))))
|
||||||
|
|
||||||
(defn generate-operations
|
(defn generate-operations
|
||||||
[ma mb]
|
([ma mb] (generate-operations ma mb false))
|
||||||
(let [ma-keys (set (keys ma))
|
([ma mb undo?]
|
||||||
mb-keys (set (keys mb))
|
(let [ops (let [ma-keys (set (keys ma))
|
||||||
added (set/difference mb-keys ma-keys)
|
mb-keys (set (keys mb))
|
||||||
removed (set/difference ma-keys mb-keys)
|
added (set/difference mb-keys ma-keys)
|
||||||
both (set/intersection ma-keys mb-keys)]
|
removed (set/difference ma-keys mb-keys)
|
||||||
(d/concat
|
both (set/intersection ma-keys mb-keys)]
|
||||||
(mapv #(array-map :type :set :attr % :val (get mb %)) added)
|
(d/concat
|
||||||
(mapv #(array-map :type :set :attr % :val nil) removed)
|
(mapv #(array-map :type :set :attr % :val (get mb %)) added)
|
||||||
(loop [items (seq both)
|
(mapv #(array-map :type :set :attr % :val nil) removed)
|
||||||
result []]
|
(loop [items (seq both)
|
||||||
(if items
|
result []]
|
||||||
(let [k (first items)
|
(if items
|
||||||
vma (get ma k)
|
(let [k (first items)
|
||||||
vmb (get mb k)]
|
vma (get ma k)
|
||||||
(if (= vma vmb)
|
vmb (get mb k)]
|
||||||
(recur (next items) result)
|
(if (= vma vmb)
|
||||||
(recur (next items)
|
(recur (next items) result)
|
||||||
(conj result {:type :set
|
(recur (next items)
|
||||||
:attr k
|
(conj result {:type :set
|
||||||
:val vmb}))))
|
:attr k
|
||||||
result)))))
|
:val vmb
|
||||||
|
:ignore-touched undo?}))))
|
||||||
|
result))))]
|
||||||
|
(if undo?
|
||||||
|
(conj ops {:type :set-touched :touched (:touched mb)})
|
||||||
|
ops))))
|
||||||
|
|
||||||
(defn generate-changes
|
(defn generate-changes
|
||||||
[page-id objects1 objects2]
|
[page-id objects1 objects2]
|
||||||
|
@ -415,7 +420,7 @@
|
||||||
obj1 (get objects id)
|
obj1 (get objects id)
|
||||||
obj2 (f obj1)
|
obj2 (f obj1)
|
||||||
rch-operations (generate-operations obj1 obj2)
|
rch-operations (generate-operations obj1 obj2)
|
||||||
uch-operations (generate-operations obj2 obj1)
|
uch-operations (generate-operations obj2 obj1 true)
|
||||||
rchg {:type :mod-obj
|
rchg {:type :mod-obj
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:operations rch-operations
|
:operations rch-operations
|
||||||
|
@ -456,7 +461,7 @@
|
||||||
obj1 (get objects id)
|
obj1 (get objects id)
|
||||||
obj2 (f obj1)
|
obj2 (f obj1)
|
||||||
rops (generate-operations obj1 obj2)
|
rops (generate-operations obj1 obj2)
|
||||||
uops (generate-operations obj2 obj1)
|
uops (generate-operations obj2 obj1 true)
|
||||||
rchg {:type :mod-obj
|
rchg {:type :mod-obj
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:operations rops
|
:operations rops
|
||||||
|
|
|
@ -366,7 +366,6 @@
|
||||||
(declare remove-component-and-ref)
|
(declare remove-component-and-ref)
|
||||||
(declare remove-ref)
|
(declare remove-ref)
|
||||||
(declare update-attrs)
|
(declare update-attrs)
|
||||||
(declare sync-attrs)
|
|
||||||
(declare calc-new-pos)
|
(declare calc-new-pos)
|
||||||
|
|
||||||
(defn reset-component
|
(defn reset-component
|
||||||
|
@ -388,7 +387,7 @@
|
||||||
(get-in state [:workspace-libraries file-id :data :components]))
|
(get-in state [:workspace-libraries file-id :data :components]))
|
||||||
|
|
||||||
[rchanges uchanges]
|
[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}))))))
|
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||||
|
|
||||||
|
@ -418,18 +417,37 @@
|
||||||
(some? (:shape-ref original-shape))
|
(some? (:shape-ref original-shape))
|
||||||
(assoc :id (:shape-ref original-shape))))
|
(assoc :id (:shape-ref original-shape))))
|
||||||
|
|
||||||
[new-shape new-shapes _]
|
touch-shape (fn [original-shape _]
|
||||||
(cph/clone-object root-shape nil objects update-new-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
|
:id component-id
|
||||||
:name (:name new-shape)
|
:name (:name new-shape)
|
||||||
:shapes new-shapes}]
|
: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
|
uchanges (concat
|
||||||
:id component-id
|
[{:type :mod-component
|
||||||
:name (:name component-obj)
|
:id component-id
|
||||||
:shapes (vals component-objs)}]]
|
: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}))))))
|
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||||
|
|
||||||
|
@ -520,13 +538,13 @@
|
||||||
(if (nil? shape)
|
(if (nil? shape)
|
||||||
[rchanges uchanges]
|
[rchanges uchanges]
|
||||||
(let [[shape-rchanges shape-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)
|
(recur (next shapes)
|
||||||
(concat rchanges shape-rchanges)
|
(concat rchanges shape-rchanges)
|
||||||
(concat uchanges shape-uchanges))))))))
|
(concat uchanges shape-uchanges))))))))
|
||||||
|
|
||||||
(defn- generate-sync-shape-and-children
|
(defn- generate-sync-shape-and-children
|
||||||
[root-shape page components]
|
[root-shape page components reset-touched?]
|
||||||
(let [objects (get page :objects)
|
(let [objects (get page :objects)
|
||||||
all-shapes (cph/get-object-with-children (:id root-shape) objects)
|
all-shapes (cph/get-object-with-children (:id root-shape) objects)
|
||||||
component (get components (:component-id root-shape))
|
component (get components (:component-id root-shape))
|
||||||
|
@ -538,19 +556,24 @@
|
||||||
(if (nil? shape)
|
(if (nil? shape)
|
||||||
[rchanges uchanges]
|
[rchanges uchanges]
|
||||||
(let [[shape-rchanges shape-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)
|
(recur (next shapes)
|
||||||
(concat rchanges shape-rchanges)
|
(concat rchanges shape-rchanges)
|
||||||
(concat uchanges shape-uchanges))))))))
|
(concat uchanges shape-uchanges))))))))
|
||||||
|
|
||||||
(defn- generate-sync-shape
|
(defn- generate-sync-shape
|
||||||
[shape root-shape root-component page component]
|
[shape root-shape root-component page component reset-touched?]
|
||||||
(if (nil? component)
|
(if (nil? component)
|
||||||
(remove-component-and-ref shape page)
|
(remove-component-and-ref shape page)
|
||||||
(let [component-shape (get (:objects component) (:shape-ref shape))]
|
(let [component-shape (get (:objects component) (:shape-ref shape))]
|
||||||
(if (nil? component-shape)
|
(if (nil? component-shape)
|
||||||
(remove-ref shape page)
|
(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
|
(defn- remove-component-and-ref
|
||||||
[shape page]
|
[shape page]
|
||||||
|
@ -565,7 +588,9 @@
|
||||||
:val nil}
|
:val nil}
|
||||||
{:type :set
|
{:type :set
|
||||||
:attr :shape-ref
|
:attr :shape-ref
|
||||||
:val nil}]}]
|
:val nil}
|
||||||
|
{:type :set-touched
|
||||||
|
:touched nil}]}]
|
||||||
[{:type :mod-obj
|
[{:type :mod-obj
|
||||||
:page-id (:id page)
|
:page-id (:id page)
|
||||||
:id (:id shape)
|
:id (:id shape)
|
||||||
|
@ -577,7 +602,9 @@
|
||||||
:val (:component-file shape)}
|
:val (:component-file shape)}
|
||||||
{:type :set
|
{:type :set
|
||||||
:attr :shape-ref
|
:attr :shape-ref
|
||||||
:val (:shape-ref shape)}]}]])
|
:val (:shape-ref shape)}
|
||||||
|
{:type :set-touched
|
||||||
|
:touched (:touched shape)}]}]])
|
||||||
|
|
||||||
(defn- remove-ref
|
(defn- remove-ref
|
||||||
[shape page]
|
[shape page]
|
||||||
|
@ -586,18 +613,22 @@
|
||||||
:id (:id shape)
|
:id (:id shape)
|
||||||
:operations [{:type :set
|
:operations [{:type :set
|
||||||
:attr :shape-ref
|
:attr :shape-ref
|
||||||
:val nil}]}]
|
:val nil}
|
||||||
|
{:type :set-touched
|
||||||
|
:touched nil}]}]
|
||||||
[{:type :mod-obj
|
[{:type :mod-obj
|
||||||
:page-id (:id page)
|
:page-id (:id page)
|
||||||
:id (:id shape)
|
:id (:id shape)
|
||||||
:operations [{:type :set
|
:operations [{:type :set
|
||||||
:attr :shape-ref
|
:attr :shape-ref
|
||||||
:val (:shape-ref shape)}]}]])
|
:val (:shape-ref shape)}
|
||||||
|
{:type :set-touched
|
||||||
|
:touched (:touched shape)}]}]])
|
||||||
|
|
||||||
(defn- update-attrs
|
(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)]
|
(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
|
roperations [{:type :set
|
||||||
:attr :x
|
:attr :x
|
||||||
:val (:x new-pos)}
|
:val (:x new-pos)}
|
||||||
|
@ -613,7 +644,19 @@
|
||||||
|
|
||||||
(let [attr (first attrs)]
|
(let [attr (first attrs)]
|
||||||
(if (nil? attr)
|
(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)
|
:page-id (:id page)
|
||||||
:id (:id shape)
|
:id (:id shape)
|
||||||
:operations roperations}]
|
:operations roperations}]
|
||||||
|
@ -628,41 +671,22 @@
|
||||||
uoperations)
|
uoperations)
|
||||||
(let [roperation {:type :set
|
(let [roperation {:type :set
|
||||||
:attr attr
|
:attr attr
|
||||||
:val (get component-shape attr)}
|
:val (get component-shape attr)
|
||||||
|
:ignore-touched true}
|
||||||
uoperation {:type :set
|
uoperation {:type :set
|
||||||
:attr attr
|
:attr attr
|
||||||
:val (get shape attr)}]
|
:val (get shape attr)
|
||||||
(recur (next attrs)
|
:ignore-touched true}
|
||||||
(conj roperations roperation)
|
|
||||||
(conj uoperations uoperation)))))))))
|
|
||||||
|
|
||||||
(def sync-attrs [:content
|
attr-group (get cp/sync-attrs attr)
|
||||||
:fill-color
|
touched (get shape :touched #{})]
|
||||||
:fill-color-ref-file
|
(if (or (not (touched attr-group)) reset-touched?)
|
||||||
:fill-color-ref-id
|
(recur (next attrs)
|
||||||
:fill-opacity
|
(conj roperations roperation)
|
||||||
:font-family
|
(conj uoperations uoperation))
|
||||||
:font-size
|
(recur (next attrs)
|
||||||
:font-style
|
roperations
|
||||||
:font-weight
|
uoperations)))))))))
|
||||||
: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])
|
|
||||||
|
|
||||||
(defn- calc-new-pos
|
(defn- calc-new-pos
|
||||||
[shape component-shape root-shape root-component]
|
[shape component-shape root-shape root-component]
|
||||||
|
|
|
@ -34,7 +34,9 @@
|
||||||
[:div.undo-entry-change {:key (str "change-" idx-change)}
|
[: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))))]
|
[:div.undo-entry-change-data (when type (str type)) " " (when id (str (get-in objects [id :name] (subs (str id) 0 8))))]
|
||||||
(when operations
|
(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 []
|
(mf/defc history-toolbox []
|
||||||
(let [locale (mf/deref i18n/locale)
|
(let [locale (mf/deref i18n/locale)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue