0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-11 23:31:21 -05:00

Move token change events to changes ns

This commit is contained in:
Florian Schroedl 2024-07-24 15:46:14 +02:00
parent 56e72b5247
commit b392c3ba65
5 changed files with 142 additions and 173 deletions

View file

@ -6,13 +6,14 @@
(ns app.main.ui.workspace.tokens.changes (ns app.main.ui.workspace.tokens.changes
(:require (:require
[app.common.types.token :as ctt]
[app.common.types.shape.radius :as ctsr] [app.common.types.shape.radius :as ctsr]
[app.common.types.token :as ctt]
[app.main.data.tokens :as dt] [app.main.data.tokens :as dt]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace :as udw] [app.main.data.workspace :as udw]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.shape-layout :as dwsl] [app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.transforms :as dwt]
[app.main.data.workspace.undo :as dwu]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.workspace.tokens.core :as wtc] [app.main.ui.workspace.tokens.core :as wtc]
[app.main.ui.workspace.tokens.style-dictionary :as sd] [app.main.ui.workspace.tokens.style-dictionary :as sd]
@ -24,6 +25,67 @@
;; Token Updates --------------------------------------------------------------- ;; Token Updates ---------------------------------------------------------------
(defn apply-token
"Apply `attributes` that match `token` for `shape-ids`.
Optionally remove attributes from `attributes-to-remove`,
this is useful for applying a single attribute from an attributes set
while removing other applied tokens from this set."
[{:keys [attributes attributes-to-remove token shape-ids on-update-shape] :as _props}]
(ptk/reify ::apply-token
ptk/WatchEvent
(watch [_ state _]
(->> (rx/from (sd/resolve-tokens+ (get-in state [:workspace-data :tokens])))
(rx/mapcat
(fn [sd-tokens]
(let [undo-id (js/Symbol)
resolved-value (-> (get sd-tokens (:id token))
(wtt/resolve-token-value))
tokenized-attributes (wtt/attributes-map attributes (:id token))]
(rx/of
(dwu/start-undo-transaction undo-id)
(dch/update-shapes shape-ids (fn [shape]
(cond-> shape
attributes-to-remove (update :applied-tokens #(apply (partial dissoc %) attributes-to-remove))
:always (update :applied-tokens merge tokenized-attributes))))
(when on-update-shape
(on-update-shape resolved-value shape-ids attributes))
(dwu/commit-undo-transaction undo-id)))))))))
(defn unapply-token
"Removes `attributes` that match `token` for `shape-ids`.
Doesn't update shape attributes."
[{:keys [attributes token shape-ids] :as _props}]
(ptk/reify ::unapply-token
ptk/WatchEvent
(watch [_ _ _]
(rx/of
(let [remove-token #(when % (wtt/remove-attributes-for-token-id attributes (:id token) %))]
(dch/update-shapes
shape-ids
(fn [shape]
(update shape :applied-tokens remove-token))))))))
(defn toggle-token
[{:keys [token-type-props token shapes] :as _props}]
(ptk/reify ::on-toggle-token
ptk/WatchEvent
(watch [_ _ _]
(let [{:keys [attributes on-update-shape]} token-type-props
unapply-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props))
shape-ids (map :id shapes)]
(if unapply-tokens?
(rx/of
(unapply-token {:attributes attributes
:token token
:shape-ids shape-ids}))
(rx/of
(apply-token {:attributes attributes
:token token
:shape-ids shape-ids
:on-update-shape on-update-shape})))))))
(defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}] (defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}]
(let [{:keys [attributes on-apply on-update-shape] (let [{:keys [attributes on-apply on-update-shape]
:or {on-apply dt/update-token-from-attributes}} token-type-props :or {on-apply dt/update-token-from-attributes}} token-type-props
@ -125,9 +187,9 @@
:attributes attributes) :attributes attributes)
:else token-type-props)] :else token-type-props)]
(wtc/on-apply-token {:token token (on-apply-token {:token token
:token-type-props updated-token-type-props :token-type-props updated-token-type-props
:selected-shapes selected-shapes}))) :selected-shapes selected-shapes})))
(defn update-layout-sizing-limits [value shape-ids attributes] (defn update-layout-sizing-limits [value shape-ids attributes]
(ptk/reify ::update-layout-sizing-limits (ptk/reify ::update-layout-sizing-limits

View file

@ -16,7 +16,6 @@
[app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.tokens.changes :as wtch] [app.main.ui.workspace.tokens.changes :as wtch]
[app.main.ui.workspace.tokens.core :as wtc]
[app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token :as wtt]
[app.main.ui.workspace.tokens.token-types :as wtty] [app.main.ui.workspace.tokens.token-types :as wtty]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -45,8 +44,8 @@
{:title title {:title title
:selected? selected? :selected? selected?
:action #(if selected? :action #(if selected?
(st/emit! (wtc/unapply-token props)) (st/emit! (wtch/unapply-token props))
(st/emit! (wtc/apply-token (assoc props :on-update-shape on-update-shape))))})) (st/emit! (wtch/apply-token (assoc props :on-update-shape on-update-shape))))}))
attributes))) attributes)))
(defn all-or-sepearate-actions [{:keys [attribute-labels on-update-shape-all on-update-shape]} (defn all-or-sepearate-actions [{:keys [attribute-labels on-update-shape-all on-update-shape]}
@ -59,8 +58,8 @@
{:title "All" {:title "All"
:selected? all-selected? :selected? all-selected?
:action #(if all-selected? :action #(if all-selected?
(st/emit! (wtc/unapply-token props)) (st/emit! (wtch/unapply-token props))
(st/emit! (wtc/apply-token (assoc props :on-update-shape (or on-update-shape-all on-update-shape)))))}) (st/emit! (wtch/apply-token (assoc props :on-update-shape (or on-update-shape-all on-update-shape)))))})
single-actions (map (fn [[attr title]] single-actions (map (fn [[attr title]]
(let [selected? (selected-pred attr)] (let [selected? (selected-pred attr)]
{:title title {:title title
@ -70,10 +69,10 @@
:shape-ids shape-ids} :shape-ids shape-ids}
event (cond event (cond
all-selected? (-> (assoc props :attributes-to-remove attributes) all-selected? (-> (assoc props :attributes-to-remove attributes)
(wtc/apply-token)) (wtch/apply-token))
selected? (wtc/unapply-token props) selected? (wtch/unapply-token props)
:else (-> (assoc props :on-update-shape on-update-shape) :else (-> (assoc props :on-update-shape on-update-shape)
(wtc/apply-token)))] (wtch/apply-token)))]
(st/emit! event))})) (st/emit! event))}))
attribute-labels)] attribute-labels)]
(concat [all-action] single-actions))) (concat [all-action] single-actions)))
@ -102,19 +101,19 @@
:token token :token token
:shape-ids shape-ids}] :shape-ids shape-ids}]
(if all-selected? (if all-selected?
(st/emit! (wtc/unapply-token props)) (st/emit! (wtch/unapply-token props))
(st/emit! (wtc/apply-token (assoc props :on-update-shape on-update-shape))))))} (st/emit! (wtch/apply-token (assoc props :on-update-shape on-update-shape))))))}
{:title "Horizontal" {:title "Horizontal"
:selected? horizontal-padding-selected? :selected? horizontal-padding-selected?
:action (fn [] :action (fn []
(let [props {:token token (let [props {:token token
:shape-ids shape-ids} :shape-ids shape-ids}
event (cond event (cond
all-selected? (wtc/apply-token (assoc props :attributes-to-remove vertical-attributes)) all-selected? (wtch/apply-token (assoc props :attributes-to-remove vertical-attributes))
horizontal-padding-selected? (wtc/apply-token (assoc props :attributes-to-remove horizontal-attributes)) horizontal-padding-selected? (wtch/apply-token (assoc props :attributes-to-remove horizontal-attributes))
:else (wtc/apply-token (assoc props :else (wtch/apply-token (assoc props
:attributes horizontal-attributes :attributes horizontal-attributes
:on-update-shape on-update-shape)))] :on-update-shape on-update-shape)))]
(st/emit! event)))} (st/emit! event)))}
{:title "Vertical" {:title "Vertical"
:selected? vertical-padding-selected? :selected? vertical-padding-selected?
@ -122,11 +121,11 @@
(let [props {:token token (let [props {:token token
:shape-ids shape-ids} :shape-ids shape-ids}
event (cond event (cond
all-selected? (wtc/apply-token (assoc props :attributes-to-remove vertical-attributes)) all-selected? (wtch/apply-token (assoc props :attributes-to-remove vertical-attributes))
vertical-padding-selected? (wtc/apply-token (assoc props :attributes-to-remove vertical-attributes)) vertical-padding-selected? (wtch/apply-token (assoc props :attributes-to-remove vertical-attributes))
:else (wtc/apply-token (assoc props :else (wtch/apply-token (assoc props
:attributes vertical-attributes :attributes vertical-attributes
:on-update-shape on-update-shape)))] :on-update-shape on-update-shape)))]
(st/emit! event)))}] (st/emit! event)))}]
single-padding-items (->> padding-attrs single-padding-items (->> padding-attrs
(map (fn [[attr title]] (map (fn [[attr title]]
@ -145,10 +144,10 @@
:shape-ids shape-ids} :shape-ids shape-ids}
event (cond event (cond
all-selected? (-> (assoc props :attributes-to-remove all-padding-attrs) all-selected? (-> (assoc props :attributes-to-remove all-padding-attrs)
(wtc/apply-token)) (wtch/apply-token))
selected? (wtc/unapply-token props) selected? (wtch/unapply-token props)
:else (-> (assoc props :on-update-shape on-update-shape) :else (-> (assoc props :on-update-shape on-update-shape)
(wtc/apply-token)))] (wtch/apply-token)))]
(st/emit! event))})))) (st/emit! event))}))))
gap-items (all-or-sepearate-actions {:attribute-labels {:column-gap "Column Gap" gap-items (all-or-sepearate-actions {:attribute-labels {:column-gap "Column Gap"
:row-gap "Row Gap"} :row-gap "Row Gap"}

View file

@ -6,25 +6,12 @@
(ns app.main.ui.workspace.tokens.core (ns app.main.ui.workspace.tokens.core
(:require (:require
[app.common.data :as d :refer [ordered-map]] [app.common.data :as d]
[app.common.types.shape.radius :as ctsr]
[app.common.types.token :as ctt]
[app.main.data.tokens :as dt]
[app.main.data.workspace :as udw]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.transforms :as dwt]
[app.main.data.workspace.undo :as dwu]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.workspace.tokens.style-dictionary :as sd]
[app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token :as wtt]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.webapi :as wapi] [app.util.webapi :as wapi]
[beicon.v2.core :as rx] [cuerdas.core :as str]))
[cuerdas.core :as str]
[potok.v2.core :as ptk]
[promesa.core :as p]))
;; Helpers --------------------------------------------------------------------- ;; Helpers ---------------------------------------------------------------------
@ -48,86 +35,6 @@
(cond-> (assoc item :label name) (cond-> (assoc item :label name)
(wtt/token-applied? item shape (or selected-attributes attributes)) (assoc :selected? true)))))) (wtt/token-applied? item shape (or selected-attributes attributes)) (assoc :selected? true))))))
;; Events ----------------------------------------------------------------------
(defn apply-token
"Apply `attributes` that match `token` for `shape-ids`.
Optionally remove attributes from `attributes-to-remove`,
this is useful for applying a single attribute from an attributes set
while removing other applied tokens from this set."
[{:keys [attributes attributes-to-remove token shape-ids on-update-shape] :as _props}]
(ptk/reify ::apply-token
ptk/WatchEvent
(watch [_ state _]
(->> (rx/from (sd/resolve-tokens+ (get-in state [:workspace-data :tokens])))
(rx/mapcat
(fn [sd-tokens]
(let [undo-id (js/Symbol)
resolved-value (-> (get sd-tokens (:id token))
(resolve-token-value))
tokenized-attributes (wtt/attributes-map attributes (:id token))]
(rx/of
(dwu/start-undo-transaction undo-id)
(dch/update-shapes shape-ids (fn [shape]
(cond-> shape
attributes-to-remove (update :applied-tokens #(apply (partial dissoc %) attributes-to-remove))
:always (update :applied-tokens merge tokenized-attributes))))
(when on-update-shape
(on-update-shape resolved-value shape-ids attributes))
(dwu/commit-undo-transaction undo-id)))))))))
(defn unapply-token
"Removes `attributes` that match `token` for `shape-ids`.
Doesn't update shape attributes."
[{:keys [attributes token shape-ids] :as _props}]
(ptk/reify ::unapply-token
ptk/WatchEvent
(watch [_ _ _]
(rx/of
(let [remove-token #(when % (wtt/remove-attributes-for-token-id attributes (:id token) %))]
(dch/update-shapes
shape-ids
(fn [shape]
(update shape :applied-tokens remove-token))))))))
(defn toggle-token
[{:keys [token-type-props token shapes] :as _props}]
(ptk/reify ::on-toggle-token
ptk/WatchEvent
(watch [_ _ _]
(let [{:keys [attributes on-update-shape]} token-type-props
unapply-tokens? (wtt/shapes-token-applied? token shapes (:attributes token-type-props))
shape-ids (map :id shapes)]
(if unapply-tokens?
(rx/of
(unapply-token {:attributes attributes
:token token
:shape-ids shape-ids}))
(rx/of
(apply-token {:attributes attributes
:token token
:shape-ids shape-ids
:on-update-shape on-update-shape})))))))
(defn on-apply-token [{:keys [token token-type-props selected-shapes] :as _props}]
(let [{:keys [attributes on-apply on-update-shape]
:or {on-apply dt/update-token-from-attributes}} token-type-props
shape-ids (->> selected-shapes
(eduction
(remove #(wtt/shapes-token-applied? token % attributes))
(map :id)))]
(p/let [sd-tokens (sd/resolve-workspace-tokens+ {:debug? true})]
(let [resolved-token (get sd-tokens (:id token))
resolved-token-value (resolve-token-value resolved-token)]
(doseq [shape selected-shapes]
(st/emit! (on-apply {:token-id (:id token)
:shape-id (:id shape)
:attributes attributes}))
(on-update-shape resolved-token-value shape-ids attributes))))))
;; JSON export functions ------------------------------------------------------- ;; JSON export functions -------------------------------------------------------
(defn encode-tokens (defn encode-tokens

View file

@ -14,6 +14,7 @@
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.assets.common :as cmm] [app.main.ui.workspace.sidebar.assets.common :as cmm]
[app.main.ui.workspace.tokens.changes :as wtch]
[app.main.ui.workspace.tokens.core :as wtc] [app.main.ui.workspace.tokens.core :as wtc]
[app.main.ui.workspace.tokens.style-dictionary :as sd] [app.main.ui.workspace.tokens.style-dictionary :as sd]
[app.main.ui.workspace.tokens.token :as wtt] [app.main.ui.workspace.tokens.token :as wtt]
@ -100,9 +101,9 @@
(dom/stop-propagation event) (dom/stop-propagation event)
(when (seq selected-shapes) (when (seq selected-shapes)
(st/emit! (st/emit!
(wtc/toggle-token {:token token (wtch/toggle-token {:token token
:shapes selected-shapes :shapes selected-shapes
:token-type-props token-type-props}))))) :token-type-props token-type-props})))))
tokens-count (count tokens)] tokens-count (count tokens)]
[:div {:on-click on-toggle-open-click} [:div {:on-click on-toggle-open-click}
[:& cmm/asset-section {:icon (mf/fnc icon-wrapper [_] [:& cmm/asset-section {:icon (mf/fnc icon-wrapper [_]

View file

@ -34,14 +34,14 @@
(let [file (setup-file) (let [file (setup-file)
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
events [(wtc/apply-token {:shape-ids [(:id rect-1)] events [(wtch/apply-token {:shape-ids [(:id rect-1)]
:attributes #{:rx :ry} :attributes #{:rx :ry}
:token (toht/get-token file :token-1) :token (toht/get-token file :token-1)
:on-update-shape wtch/update-shape-radius-all}) :on-update-shape wtch/update-shape-radius-all})
(wtc/apply-token {:shape-ids [(:id rect-1)] (wtch/apply-token {:shape-ids [(:id rect-1)]
:attributes #{:rx :ry} :attributes #{:rx :ry}
:token (toht/get-token file :token-2) :token (toht/get-token file :token-2)
:on-update-shape wtch/update-shape-radius-all})]] :on-update-shape wtch/update-shape-radius-all})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -62,18 +62,18 @@
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
events [;; Apply `:token-1` to all border radius attributes events [;; Apply `:token-1` to all border radius attributes
(wtc/apply-token {:attributes #{:rx :ry :r1 :r2 :r3 :r4} (wtch/apply-token {:attributes #{:rx :ry :r1 :r2 :r3 :r4}
:token (toht/get-token file :token-1) :token (toht/get-token file :token-1)
:shape-ids [(:id rect-1)] :shape-ids [(:id rect-1)]
:on-update-shape wtch/update-shape-radius-all}) :on-update-shape wtch/update-shape-radius-all})
;; Apply single `:r1` attribute to same shape ;; Apply single `:r1` attribute to same shape
;; while removing other attributes from the border-radius set ;; while removing other attributes from the border-radius set
;; but keep `:r4` for testing purposes ;; but keep `:r4` for testing purposes
(wtc/apply-token {:attributes #{:r1} (wtch/apply-token {:attributes #{:r1}
:attributes-to-remove #{:rx :ry :r1 :r2 :r3} :attributes-to-remove #{:rx :ry :r1 :r2 :r3}
:token (toht/get-token file :token-2) :token (toht/get-token file :token-2)
:shape-ids [(:id rect-1)] :shape-ids [(:id rect-1)]
:on-update-shape wtch/update-shape-radius-all})]] :on-update-shape wtch/update-shape-radius-all})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -95,10 +95,10 @@
(let [file (setup-file) (let [file (setup-file)
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
events [(wtc/apply-token {:shape-ids [(:id rect-1)] events [(wtch/apply-token {:shape-ids [(:id rect-1)]
:attributes #{:rx :ry} :attributes #{:rx :ry}
:token (toht/get-token file :token-2) :token (toht/get-token file :token-2)
:on-update-shape wtch/update-shape-radius-all})]] :on-update-shape wtch/update-shape-radius-all})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -121,10 +121,10 @@
:type :dimensions})) :type :dimensions}))
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
events [(wtc/apply-token {:shape-ids [(:id rect-1)] events [(wtch/apply-token {:shape-ids [(:id rect-1)]
:attributes #{:width :height} :attributes #{:width :height}
:token (toht/get-token file :token-target) :token (toht/get-token file :token-target)
:on-update-shape wtch/update-shape-dimensions})]] :on-update-shape wtch/update-shape-dimensions})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -147,10 +147,10 @@
:type :sizing})) :type :sizing}))
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
events [(wtc/apply-token {:shape-ids [(:id rect-1)] events [(wtch/apply-token {:shape-ids [(:id rect-1)]
:attributes #{:width :height} :attributes #{:width :height}
:token (toht/get-token file :token-target) :token (toht/get-token file :token-target)
:on-update-shape wtch/update-shape-dimensions})]] :on-update-shape wtch/update-shape-dimensions})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -173,10 +173,10 @@
:type :opacity})) :type :opacity}))
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
events [(wtc/apply-token {:shape-ids [(:id rect-1)] events [(wtch/apply-token {:shape-ids [(:id rect-1)]
:attributes #{:opacity} :attributes #{:opacity}
:token (toht/get-token file :token-target) :token (toht/get-token file :token-target)
:on-update-shape wtch/update-opacity})]] :on-update-shape wtch/update-opacity})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -198,10 +198,10 @@
:type :rotation})) :type :rotation}))
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
events [(wtc/apply-token {:shape-ids [(:id rect-1)] events [(wtch/apply-token {:shape-ids [(:id rect-1)]
:attributes #{:rotation} :attributes #{:rotation}
:token (toht/get-token file :token-target) :token (toht/get-token file :token-target)
:on-update-shape wtch/update-rotation})]] :on-update-shape wtch/update-rotation})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -220,10 +220,10 @@
store (ths/setup-store file) store (ths/setup-store file)
rect-1 (cths/get-shape file :rect-1) rect-1 (cths/get-shape file :rect-1)
rect-2 (cths/get-shape file :rect-2) rect-2 (cths/get-shape file :rect-2)
events [(wtc/toggle-token {:shapes [rect-1 rect-2] events [(wtch/toggle-token {:shapes [rect-1 rect-2]
:token-type-props {:attributes #{:rx :ry} :token-type-props {:attributes #{:rx :ry}
:on-update-shape wtch/update-shape-radius-all} :on-update-shape wtch/update-shape-radius-all}
:token (toht/get-token file :token-2)})]] :token (toht/get-token file :token-2)})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -253,9 +253,9 @@
rect-without-token (cths/get-shape file :rect-2) rect-without-token (cths/get-shape file :rect-2)
rect-with-other-token (cths/get-shape file :rect-3) rect-with-other-token (cths/get-shape file :rect-3)
events [(wtc/toggle-token {:shapes [rect-with-token rect-without-token rect-with-other-token] events [(wtch/toggle-token {:shapes [rect-with-token rect-without-token rect-with-other-token]
:token (toht/get-token file :token-1) :token (toht/get-token file :token-1)
:token-type-props {:attributes #{:rx :ry}}})]] :token-type-props {:attributes #{:rx :ry}}})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]
@ -287,9 +287,9 @@
rect-without-token (cths/get-shape file :rect-2) rect-without-token (cths/get-shape file :rect-2)
rect-with-other-token-2 (cths/get-shape file :rect-3) rect-with-other-token-2 (cths/get-shape file :rect-3)
events [(wtc/toggle-token {:shapes [rect-with-other-token-1 rect-without-token rect-with-other-token-2] events [(wtch/toggle-token {:shapes [rect-with-other-token-1 rect-without-token rect-with-other-token-2]
:token (toht/get-token file :token-1) :token (toht/get-token file :token-1)
:token-type-props {:attributes #{:rx :ry}}})]] :token-type-props {:attributes #{:rx :ry}}})]]
(tohs/run-store-async (tohs/run-store-async
store done events store done events
(fn [new-state] (fn [new-state]