Adds synchronization for typography

This commit is contained in:
alonso.torres 2020-09-30 18:46:10 +02:00 committed by Hirunatan
parent 718a676fa8
commit 7248b168fa
3 changed files with 167 additions and 96 deletions

View file

@ -452,9 +452,10 @@
(watch [_ state stream] (watch [_ state stream]
(let [[rchanges1 uchanges1] (dwlh/generate-sync-file-components state file-id) (let [[rchanges1 uchanges1] (dwlh/generate-sync-file-components state file-id)
[rchanges2 uchanges2] (dwlh/generate-sync-library-components state file-id) [rchanges2 uchanges2] (dwlh/generate-sync-library-components state file-id)
[rchanges3 uchanges3] (dwlh/generate-sync-file-colors state file-id) [rchanges3 uchanges3] (dwlh/generate-sync-file :colors file-id state)
rchanges (d/concat rchanges1 rchanges2 rchanges3) [rchanges4 uchanges4] (dwlh/generate-sync-file :typography file-id state)
uchanges (d/concat uchanges1 uchanges2 uchanges3)] rchanges (d/concat rchanges1 rchanges2 rchanges3 rchanges4)
uchanges (d/concat uchanges1 uchanges2 uchanges3 uchanges4)]
(rx/concat (rx/concat
(rx/of (dm/hide-tag :sync-dialog)) (rx/of (dm/hide-tag :sync-dialog))
(when rchanges (when rchanges

View file

@ -9,25 +9,167 @@
(ns app.main.data.workspace.libraries-helpers (ns app.main.data.workspace.libraries-helpers
(:require (:require
[cljs.spec.alpha :as s]
[app.common.spec :as us]
[app.common.data :as d] [app.common.data :as d]
[app.common.pages-helpers :as cph] [app.common.pages-helpers :as cph]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.pages :as cp])) [app.common.pages :as cp]
[app.util.text :as ut]))
(defonce empty-changes [[] []])
(declare generate-sync-page)
(declare generate-sync-shape)
(declare generate-sync-file-components)
(declare generate-sync-page-components)
(declare generate-sync-library-components)
(declare generate-sync-component-components) (declare generate-sync-component-components)
(declare generate-sync-shape-and-children-components) (declare generate-sync-shape-and-children-components)
(declare generate-sync-shape-components) (declare generate-sync-shape-components)
(declare generate-sync-file-colors)
(declare generate-sync-page-colors)
(declare generate-sync-shape-colors)
(declare remove-component-and-ref) (declare remove-component-and-ref)
(declare remove-ref) (declare remove-ref)
(declare update-attrs) (declare update-attrs)
(declare calc-new-pos) (declare calc-new-pos)
(defn generate-sync-file
"Generic method that given a type of asset will iterate through the file pages
and call synchronize"
[asset-type library-id state]
(s/assert #{:colors :components :typography} asset-type)
(s/assert (s/nilable ::us/uuid) library-id)
(let [library-items
(if (nil? library-id)
(get-in state [:workspace-data asset-type])
(get-in state [:workspace-libraries library-id :data asset-type]))]
(if (empty? library-items)
empty-changes
(loop [pages (vals (get-in state [:workspace-data :pages-index]))
rchanges []
uchanges []]
(if-let [page (first pages)]
(let [[page-rchanges page-uchanges]
(generate-sync-page asset-type library-id library-items page)]
(recur (next pages)
(d/concat rchanges page-rchanges)
(d/concat uchanges page-uchanges)))
[rchanges uchanges])))))
(defn has-asset-reference-fn
[asset-type library-id]
(case asset-type
:components
(fn [shape] (and (some? (:component-id shape))
(= (:component-file shape) library-id)))
:colors
(fn [shape] (some
#(let [attr (name %)
attr-ref-id (keyword (str attr "-ref-id"))
attr-ref-file (keyword (str attr "-ref-file"))]
(and (get shape attr-ref-id)
(= library-id (get shape attr-ref-file))))
cp/color-sync-attrs))
:typography
(fn [shape]
(and (= (:type shape) :text)
(->> shape
:content
;; Check if any node in the content has a reference for the library
(ut/some-node
#(and (some? (:typography-ref-id %))
(= library-id (:typography-ref-file %)))))))))
(defn generate-sync-page
[asset-type library-id library-items page]
(let [has-asset-reference? (has-asset-reference-fn asset-type library-id)
linked-shapes (cph/select-objects has-asset-reference? page)]
(loop [shapes (seq linked-shapes)
rchanges []
uchanges []]
(if-let [shape (first shapes)]
(let [[shape-rchanges shape-uchanges]
(generate-sync-shape asset-type library-id library-items page shape)]
(recur (next shapes)
(d/concat rchanges shape-rchanges)
(d/concat uchanges shape-uchanges)))
[rchanges uchanges]))))
(defmulti generate-sync-shape (fn [type _ _ _ _ _] type))
(defmethod generate-sync-shape :components
[_ library-id library-items page shape]
(let [root-shape shape
objects (:objects page)
components library-items
page-id nil
component-id (:id page)
reset-touched? false]
(generate-sync-shape-and-children-components root-shape objects components page-id component-id reset-touched?)))
(defmethod generate-sync-shape :colors
[_ library-id library-items page shape]
(loop [attrs (seq cp/color-sync-attrs)
roperations []
uoperations []]
(let [attr (first attrs)]
(if (nil? attr)
(if (empty? roperations)
empty-changes
(let [rchanges [{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations roperations}]
uchanges [{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations uoperations}]]
[rchanges uchanges]))
(let [attr-ref-id (keyword (str (name attr) "-ref-id"))]
(if-not (contains? shape attr-ref-id)
(recur (next attrs)
roperations
uoperations)
(let [color (get library-items (get shape attr-ref-id))
roperation {:type :set
:attr attr
:val (:value color)
:ignore-touched true}
uoperation {:type :set
:attr attr
:val (get shape attr)
:ignore-touched true}]
(recur (next attrs)
(conj roperations roperation)
(conj uoperations uoperation)))))))))
(defmethod generate-sync-shape :typography
[_ library-id library-items page shape]
(let [update-node (fn [node]
(if-let [typography (get library-items (:typography-ref-id node))]
(merge node (d/without-keys typography [:name :id]))
node))
old-content (:content shape)
new-content (ut/map-node update-node old-content)
rchanges [{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations [{:type :set
:attr :content
:val new-content}]}]
lchanges [{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations [{:type :set
:attr :content
:val old-content}]}]]
(if (= new-content old-content)
empty-changes
[rchanges lchanges])))
;; ---- Create a new component ---- ;; ---- Create a new component ----
(defn make-component-shape (defn make-component-shape
@ -59,6 +201,8 @@
;; ---- Synchronize shapes with components ;; ---- Synchronize shapes with components
(declare generate-sync-page-components)
(defn generate-sync-file-components (defn generate-sync-file-components
"Generate changes to synchronize all shapes in current file that are linked "Generate changes to synchronize all shapes in current file that are linked
to some component in the given library. All attributes of the components to some component in the given library. All attributes of the components
@ -121,7 +265,7 @@
(get-in state [:workspace-data :components]) (get-in state [:workspace-data :components])
(get-in state [:workspace-libraries library-id :data :components]))] (get-in state [:workspace-libraries library-id :data :components]))]
(if (nil? components) (if (nil? components)
[[] []] empty-changes
(loop [local-components (seq (vals (get-in state [:workspace-data :components]))) (loop [local-components (seq (vals (get-in state [:workspace-data :components])))
rchanges [] rchanges []
uchanges []] uchanges []]
@ -348,88 +492,3 @@
new-pos)) new-pos))
;; ---- Synchronize shapes with colors
(defn generate-sync-file-colors
"Generate changes to synchronize all shapes in current file that have
any color linked to some color in the given library."
[state library-id]
(let [colors
(if (nil? library-id)
(get-in state [:workspace-data :colors])
(get-in state [:workspace-libraries library-id :data :colors]))]
(when (some? colors)
(loop [pages (seq (vals (get-in state [:workspace-data :pages-index])))
rchanges []
uchanges []]
(let [page (first pages)]
(if (nil? page)
[rchanges uchanges]
(let [[page-rchanges page-uchanges]
(generate-sync-page-colors library-id page colors)]
(recur (next pages)
(d/concat rchanges page-rchanges)
(d/concat uchanges page-uchanges)))))))))
(defn generate-sync-page-colors
"Generate changes to synchronize all shapes in a particular page."
[library-id page colors]
(let [linked-color? (fn [shape]
(some
#(let [attr (name %)
attr-ref-id (keyword (str attr "-ref-id"))
attr-ref-file (keyword (str attr "-ref-file"))]
(and (get shape attr-ref-id)
(= library-id (get shape attr-ref-file))))
cp/color-sync-attrs))
linked-shapes (cph/select-objects linked-color? page)]
(loop [shapes (seq linked-shapes)
rchanges []
uchanges []]
(let [shape (first shapes)]
(if (nil? shape)
[rchanges uchanges]
(let [[shape-rchanges shape-uchanges]
(generate-sync-shape-colors shape page colors)]
(recur (next shapes)
(d/concat rchanges shape-rchanges)
(d/concat uchanges shape-uchanges))))))))
(defn generate-sync-shape-colors
"Generate changes to synchronize colors of one shape."
[shape page colors]
(loop [attrs (seq cp/color-sync-attrs)
roperations []
uoperations []]
(let [attr (first attrs)]
(if (nil? attr)
(if (empty? roperations)
[[] []]
(let [rchanges [{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations roperations}]
uchanges [{:type :mod-obj
:page-id (:id page)
:id (:id shape)
:operations uoperations}]]
[rchanges uchanges]))
(let [attr-ref-id (keyword (str (name attr) "-ref-id"))]
(if-not (contains? shape attr-ref-id)
(recur (next attrs)
roperations
uoperations)
(let [color (get colors (get shape attr-ref-id))
roperation {:type :set
:attr attr
:val (:value color)
:ignore-touched true}
uoperation {:type :set
:attr attr
:val (get shape attr)
:ignore-touched true}]
(recur (next attrs)
(conj roperations roperation)
(conj uoperations uoperation)))))))))

View file

@ -0,0 +1,11 @@
(ns app.util.text)
(defn some-node
[predicate node]
(or (predicate node)
(some #(some-node predicate %) (:children node))))
(defn map-node
[map-fn node]
(cond-> (map-fn node)
(:children node) (update :children (fn [children] (mapv #(map-node map-fn %) children)))))