♻️ Ensure a correct usage of concat/into operations.

This commit is contained in:
Andrey Antukh 2021-11-30 19:02:27 +01:00 committed by Alonso Torres
parent b897f202dd
commit 6a7600fd52
42 changed files with 461 additions and 383 deletions

View file

@ -6,7 +6,6 @@
(ns app.util.emails (ns app.util.emails
(:require (:require
[app.common.data :as d]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.spec :as us] [app.common.spec :as us]
[app.util.template :as tmpl] [app.util.template :as tmpl]
@ -199,7 +198,7 @@
(ex/raise :type :internal (ex/raise :type :internal
:code :missing-email-templates)) :code :missing-email-templates))
{:subject subj {:subject subj
:body (d/concat :body (into
[{:type "text/plain" [{:type "text/plain"
:content text}] :content text}]
(when html (when html

View file

@ -37,7 +37,7 @@
;; --- Development Stuff ;; --- Development Stuff
(defn- run-tests (defn- run-tests
([] (run-tests #"^app.common.tests.*")) ([] (run-tests #"^app.common.*-test$"))
([o] ([o]
(repl/refresh) (repl/refresh)
(cond (cond

View file

@ -6,7 +6,7 @@
(ns app.common.data (ns app.common.data
"Data manipulation and query helper functions." "Data manipulation and query helper functions."
(:refer-clojure :exclude [concat read-string hash-map merge name]) (:refer-clojure :exclude [read-string hash-map merge name])
#?(:cljs #?(:cljs
(:require-macros [app.common.data])) (:require-macros [app.common.data]))
(:require (:require
@ -60,19 +60,37 @@
m) m)
(dissoc m k))) (dissoc m k)))
(defn concat (defn- transient-concat
[& colls] [c1 colls]
(loop [result (transient (first colls)) (loop [result (transient c1)
colls (next colls)] colls colls]
(if colls (if colls
(recur (reduce conj! result (first colls)) (recur (reduce conj! result (first colls))
(next colls)) (next colls))
(persistent! result)))) (persistent! result))))
(defn concat-set
([] #{})
([c1]
(if (set? c1) c1 (into #{} c1)))
([c1 & more]
(if (set? c1)
(transient-concat c1 more)
(transient-concat #{} (cons c1 more)))))
(defn concat-vec
([] [])
([c1]
(if (vector? c1) c1 (into [] c1)))
([c1 & more]
(if (vector? c1)
(transient-concat c1 more)
(transient-concat [] (cons c1 more)))))
(defn preconj (defn preconj
[coll elem] [coll elem]
(assert (vector? coll)) (assert (vector? coll))
(concat [elem] coll)) (into [elem] coll))
(defn enumerate (defn enumerate
([items] (enumerate items 0)) ([items] (enumerate items 0))
@ -144,10 +162,15 @@
(reduce #(dissoc! %1 %2) (transient data) keys)))) (reduce #(dissoc! %1 %2) (transient data) keys))))
(defn remove-at-index (defn remove-at-index
"Takes a vector and returns a vector with an element in the
specified index removed."
[v index] [v index]
(vec (core/concat ;; The subvec function returns a SubVector type that is an vector
(subvec v 0 index) ;; but does not have transient impl, because of this, we need to
(subvec v (inc index))))) ;; pass an explicit vector as first argument.
(concat-vec []
(subvec v 0 index)
(subvec v (inc index))))
(defn zip [col1 col2] (defn zip [col1 col2]
(map vector col1 col2)) (map vector col1 col2))
@ -435,16 +458,16 @@
(defn with-next (defn with-next
"Given a collection will return a new collection where each element "Given a collection will return a new collection where each element
is paired with the next item in the collection is paired with the next item in the collection
(with-next (range 5)) => [[0 1] [1 2] [2 3] [3 4] [4 nil]" (with-next (range 5)) => [[0 1] [1 2] [2 3] [3 4] [4 nil]]"
[coll] [coll]
(map vector (map vector
coll coll
(concat [] (rest coll) [nil]))) (concat (rest coll) [nil])))
(defn with-prev (defn with-prev
"Given a collection will return a new collection where each element "Given a collection will return a new collection where each element
is paired with the previous item in the collection is paired with the previous item in the collection
(with-prev (range 5)) => [[0 nil] [1 0] [2 1] [3 2] [4 3]" (with-prev (range 5)) => [[0 nil] [1 0] [2 1] [3 2] [4 3]]"
[coll] [coll]
(map vector (map vector
coll coll
@ -453,12 +476,12 @@
(defn with-prev-next (defn with-prev-next
"Given a collection will return a new collection where every item is paired "Given a collection will return a new collection where every item is paired
with the previous and the next item of a collection with the previous and the next item of a collection
(with-prev-next (range 5)) => [[0 nil 1] [1 0 2] [2 1 3] [3 2 4] [4 3 nil]" (with-prev-next (range 5)) => [[0 nil 1] [1 0 2] [2 1 3] [3 2 4] [4 3 nil]]"
[coll] [coll]
(map vector (map vector
coll coll
(concat [nil] coll) (concat [nil] coll)
(concat [] (rest coll) [nil]))) (concat (rest coll) [nil])))
(defn prefix-keyword (defn prefix-keyword
"Given a keyword and a prefix will return a new keyword with the prefix attached "Given a keyword and a prefix will return a new keyword with the prefix attached

View file

@ -6,7 +6,6 @@
(ns app.common.geom.align (ns app.common.geom.align
(:require (:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[clojure.spec.alpha :as s])) [clojure.spec.alpha :as s]))
@ -16,11 +15,15 @@
(declare calc-align-pos) (declare calc-align-pos)
;; TODO: revisit on how to reuse code and dont have this function
;; duplicated because the implementation right now differs from the
;; original function.
;; Duplicated from pages/helpers to remove cyclic dependencies ;; Duplicated from pages/helpers to remove cyclic dependencies
(defn- get-children [id objects] (defn- get-children [id objects]
(let [shapes (vec (get-in objects [id :shapes]))] (let [shapes (vec (get-in objects [id :shapes]))]
(if shapes (if shapes
(d/concat shapes (mapcat #(get-children % objects) shapes)) (into shapes (mapcat #(get-children % objects)) shapes)
[]))) [])))
(defn- recursive-move (defn- recursive-move

View file

@ -100,7 +100,7 @@
(defn curve-tangent (defn curve-tangent
"Retrieve the tangent vector to the curve in the point `t`" "Retrieve the tangent vector to the curve in the point `t`"
[[start end h1 h2] t] [[start end h1 h2] t]
(let [coords [[(:x start) (:x h1) (:x h2) (:x end)] (let [coords [[(:x start) (:x h1) (:x h2) (:x end)]
[(:y start) (:y h1) (:y h2) (:y end)]] [(:y start) (:y h1) (:y h2) (:y end)]]
@ -316,15 +316,13 @@
:line-to [prev-point (command->point command)] :line-to [prev-point (command->point command)]
;; We return the bezier extremities ;; We return the bezier extremities
:curve-to (d/concat :curve-to (into [prev-point (command->point command)]
[prev-point (let [curve [prev-point
(command->point command)] (command->point command)
(let [curve [prev-point (command->point command :c1)
(command->point command) (command->point command :c2)]]
(command->point command :c1) (->> (curve-extremities curve)
(command->point command :c2)]] (map #(curve-values curve %)))))
(->> (curve-extremities curve)
(mapv #(curve-values curve %)))))
[]) [])
selrect (gpr/points->selrect points)] selrect (gpr/points->selrect points)]
(-> selrect (-> selrect
@ -342,20 +340,19 @@
(command->point command)] (command->point command)]
;; We return the bezier extremities ;; We return the bezier extremities
:curve-to (d/concat :curve-to (into [(command->point prev)
[(command->point prev) (command->point command)]
(command->point command)] (let [curve [(command->point prev)
(let [curve [(command->point prev) (command->point command)
(command->point command) (command->point command :c1)
(command->point command :c1) (command->point command :c2)]]
(command->point command :c2)]] (->> (curve-extremities curve)
(->> (curve-extremities curve) (map #(curve-values curve %)))))
(mapv #(curve-values curve %)))))
[])) []))
extremities (mapcat calc-extremities extremities (mapcat calc-extremities
content content
(d/concat [nil] content)) (concat [nil] content))
selrect (gpr/points->selrect extremities)] selrect (gpr/points->selrect extremities)]
@ -410,14 +407,16 @@
(let [initial (first segments) (let [initial (first segments)
lines (rest segments)] lines (rest segments)]
(d/concat [{:command :move-to (d/concat-vec
:params (select-keys initial [:x :y])}] [{:command :move-to
(->> lines :params (select-keys initial [:x :y])}]
(mapv #(hash-map :command :line-to
:params (select-keys % [:x :y]))))
(when closed? (->> lines
[{:command :close-path}]))))) (map #(hash-map :command :line-to
:params (select-keys % [:x :y]))))
(when closed?
[{:command :close-path}])))))
(defonce num-segments 10) (defonce num-segments 10)
@ -770,7 +769,7 @@
ts-3 (check-range c1-half c1-to c2-from c2-half) ts-3 (check-range c1-half c1-to c2-from c2-half)
ts-4 (check-range c1-half c1-to c2-half c2-to)] ts-4 (check-range c1-half c1-to c2-half c2-to)]
(d/concat [] ts-1 ts-2 ts-3 ts-4))))))) (d/concat-vec ts-1 ts-2 ts-3 ts-4)))))))
(remove-close-ts [{cp1 :p1 cp2 :p2}] (remove-close-ts [{cp1 :p1 cp2 :p2}]
(fn [{:keys [p1 p2]}] (fn [{:keys [p1 p2]}]

View file

@ -214,7 +214,7 @@
not-mask-shapes (without-obj shapes mask-id) not-mask-shapes (without-obj shapes mask-id)
new-index (if (nil? index) nil (max (dec index) 0)) new-index (if (nil? index) nil (max (dec index) 0))
new-shapes (insert-items other-ids new-index not-mask-shapes)] new-shapes (insert-items other-ids new-index not-mask-shapes)]
(d/concat [mask-id] new-shapes)))) (into [mask-id] new-shapes))))
(add-to-parent [parent index shapes] (add-to-parent [parent index shapes]
(let [parent (-> parent (let [parent (-> parent

View file

@ -98,7 +98,7 @@
(let [old-obj (get objects id) (let [old-obj (get objects id)
new-obj (update-fn old-obj) new-obj (update-fn old-obj)
attrs (or attrs (d/concat #{} (keys old-obj) (keys new-obj))) attrs (or attrs (d/concat-set (keys old-obj) (keys new-obj)))
{rops :rops uops :uops} {rops :rops uops :uops}
(reduce #(generate-operation %1 %2 old-obj new-obj ignore-geometry?) (reduce #(generate-operation %1 %2 old-obj new-obj ignore-geometry?)

View file

@ -103,7 +103,6 @@
"Retrieve all children ids recursively for a given object. The "Retrieve all children ids recursively for a given object. The
children's order will be breadth first." children's order will be breadth first."
[id objects] [id objects]
(loop [result (transient []) (loop [result (transient [])
pending (transient []) pending (transient [])
next id] next id]
@ -221,8 +220,8 @@
(pos? (count after'))) (pos? (count after')))
(let [before' (conj before' (first after')) (let [before' (conj before' (first after'))
after' (into [] (rest after'))] after' (into [] (rest after'))]
(d/concat [] before' ids after')) (d/concat-vec before' ids after'))
(d/concat [] before' ids after')))) (d/concat-vec before' ids after'))))
(defn append-at-the-end (defn append-at-the-end
[prev-ids ids] [prev-ids ids]
@ -238,24 +237,25 @@
([objects {:keys [include-frames? include-frame-children?] ([objects {:keys [include-frames? include-frame-children?]
:or {include-frames? false :or {include-frames? false
include-frame-children? true}}] include-frame-children? true}}]
(let [lookup #(get objects %)
root (lookup uuid/zero) (let [lookup #(get objects %)
root (lookup uuid/zero)
root-children (:shapes root) root-children (:shapes root)
lookup-shapes lookup-shapes
(fn [result id] (fn [result id]
(if (nil? id) (if (nil? id)
result result
(let [obj (lookup id) (let [obj (lookup id)
typ (:type obj) typ (:type obj)
children (:shapes obj)] children (:shapes obj)]
(cond-> result (cond-> result
(or (not= :frame typ) include-frames?) (or (not= :frame typ) include-frames?)
(d/concat [obj]) (conj obj)
(and (= :frame typ) include-frame-children?) (and (= :frame typ) include-frame-children?)
(d/concat (map lookup children))))))] (into (map lookup) children)))))]
(reduce lookup-shapes [] root-children)))) (reduce lookup-shapes [] root-children))))
@ -304,15 +304,13 @@
(some? (:shapes object)) (some? (:shapes object))
(assoc :shapes (mapv :id new-direct-children))) (assoc :shapes (mapv :id new-direct-children)))
new-object (update-new-object new-object object) new-object (update-new-object new-object object)
new-objects (into [new-object] new-children)
new-objects (d/concat [new-object] new-children)
updated-object (update-original-object object new-object)
updated-object (update-original-object object new-object)
updated-objects (if (identical? object updated-object) updated-objects (if (identical? object updated-object)
updated-children updated-children
(d/concat [updated-object] updated-children))] (into [updated-object] updated-children))]
[new-object new-objects updated-objects]) [new-object new-objects updated-objects])
@ -325,9 +323,9 @@
(recur (recur
(next child-ids) (next child-ids)
(d/concat new-direct-children [new-child]) (into new-direct-children [new-child])
(d/concat new-children new-child-objects) (into new-children new-child-objects)
(d/concat updated-children updated-child-objects)))))))) (into updated-children updated-child-objects))))))))
(defn indexed-shapes (defn indexed-shapes
"Retrieves a list with the indexes for each element in the layer tree. "Retrieves a list with the indexes for each element in the layer tree.

View file

@ -12,28 +12,25 @@
[clojure.set :as set])) [clojure.set :as set]))
(defn calculate-frame-z-index [z-index frame-id objects] (defn calculate-frame-z-index [z-index frame-id objects]
(let [is-frame? (fn [id] (= :frame (get-in objects [id :type]))) (let [is-frame? (fn [id] (= :frame (get-in objects [id :type])))
frame-shapes (->> objects (vals) (filterv #(= (:frame-id %) frame-id))) frame-shapes (->> objects (vals) (filterv #(= (:frame-id %) frame-id)))
children (or (get-in objects [frame-id :shapes]) [])] children (or (get-in objects [frame-id :shapes]) [])]
(if (empty? children) (if (empty? children)
z-index z-index
(loop [current (peek children) (loop [current (peek children)
pending (pop children) pending (pop children)
current-idx (count frame-shapes) current-idx (count frame-shapes)
z-index z-index] z-index z-index]
(let [children (get-in objects [current :shapes]) (let [children (get-in objects [current :shapes])
is-frame? (is-frame? current) is-frame? (is-frame? current)
pending (if (not is-frame?) pending (if (not is-frame?)
(d/concat pending children) (d/concat-vec pending children)
pending)] pending)]
(if (empty? pending) (if (empty? pending)
(-> z-index (assoc z-index current current-idx)
(assoc current current-idx))
(recur (peek pending) (recur (peek pending)
(pop pending) (pop pending)
(dec current-idx) (dec current-idx)

View file

@ -213,26 +213,25 @@
;; Pick all segments in content-a that are not inside content-b ;; Pick all segments in content-a that are not inside content-b
;; Pick all segments in content-b that are not inside content-a ;; Pick all segments in content-b that are not inside content-a
(let [content (let [content
(d/concat (concat
[]
(->> content-a-split (filter #(not (contains-segment? % content-b)))) (->> content-a-split (filter #(not (contains-segment? % content-b))))
(->> content-b-split (filter #(not (contains-segment? % content-a))))) (->> content-b-split (filter #(not (contains-segment? % content-a)))))
;; Overlapping segments should be added when they are part of the border ;; Overlapping segments should be added when they are part of the border
border-content border-content
(->> content-b-split (->> content-b-split
(filterv #(and (contains-segment? % content-a) (filter #(and (contains-segment? % content-a)
(overlap-segment? % content-a-split) (overlap-segment? % content-a-split)
(not (inside-segment? % content)))))] (not (inside-segment? % content)))))]
(d/concat content border-content))) ;; Ensure that the output is always a vector
(d/concat-vec content border-content)))
(defn create-difference [content-a content-a-split content-b content-b-split] (defn create-difference [content-a content-a-split content-b content-b-split]
;; Pick all segments in content-a that are not inside content-b ;; Pick all segments in content-a that are not inside content-b
;; Pick all segments in content b that are inside content-a ;; Pick all segments in content b that are inside content-a
;; removing overlapping ;; removing overlapping
(d/concat (d/concat-vec
[]
(->> content-a-split (filter #(not (contains-segment? % content-b)))) (->> content-a-split (filter #(not (contains-segment? % content-b))))
;; Reverse second content so we can have holes inside other shapes ;; Reverse second content so we can have holes inside other shapes
@ -243,15 +242,14 @@
(defn create-intersection [content-a content-a-split content-b content-b-split] (defn create-intersection [content-a content-a-split content-b content-b-split]
;; Pick all segments in content-a that are inside content-b ;; Pick all segments in content-a that are inside content-b
;; Pick all segments in content-b that are inside content-a ;; Pick all segments in content-b that are inside content-a
(d/concat (d/concat-vec
[]
(->> content-a-split (filter #(contains-segment? % content-b))) (->> content-a-split (filter #(contains-segment? % content-b)))
(->> content-b-split (filter #(contains-segment? % content-a))))) (->> content-b-split (filter #(contains-segment? % content-a)))))
(defn create-exclusion [content-a content-b] (defn create-exclusion [content-a content-b]
;; Pick all segments ;; Pick all segments
(d/concat [] content-a content-b)) (d/concat-vec content-a content-b))
(defn fix-move-to (defn fix-move-to

View file

@ -31,23 +31,22 @@
:blur]) :blur])
(def style-properties (def style-properties
(d/concat (into style-group-properties
style-group-properties [:fill-color
[:fill-color :fill-opacity
:fill-opacity :fill-color-gradient
:fill-color-gradient :fill-color-ref-file
:fill-color-ref-file :fill-color-ref-id
:fill-color-ref-id :fill-image
:fill-image :stroke-color
:stroke-color :stroke-color-ref-file
:stroke-color-ref-file :stroke-color-ref-id
:stroke-color-ref-id :stroke-opacity
:stroke-opacity :stroke-style
:stroke-style :stroke-width
:stroke-width :stroke-alignment
:stroke-alignment :stroke-cap-start
:stroke-cap-start :stroke-cap-end]))
:stroke-cap-end]))
(defn make-corner-arc (defn make-corner-arc
"Creates a curvle corner for border radius" "Creates a curvle corner for border radius"

View file

@ -90,7 +90,7 @@
[subpath other] [subpath other]
(assert (pt= (:to subpath) (:from other))) (assert (pt= (:to subpath) (:from other)))
(-> subpath (-> subpath
(update :data d/concat (rest (:data other))) (update :data d/concat-vec (rest (:data other)))
(assoc :to (:to other)))) (assoc :to (:to other))))
(defn- merge-paths (defn- merge-paths

View file

@ -0,0 +1,58 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
(ns app.common.data-test
(:require
[app.common.data :as d]
[clojure.test :as t]))
(t/deftest concat-vec
(t/is (= [1 2 3]
(d/concat-vec [1] #{2} [3])))
(t/is (= [1 2]
(d/concat-vec '(1) [2])))
(t/is (= [1]
(d/concat-vec [1])))
(t/is (= [] (d/concat-vec))))
(t/deftest concat-set
(t/is (= #{} (d/concat-set)))
(t/is (= #{1 2}
(d/concat-set [1] [2]))))
(t/deftest remove-at-index
(t/is (= [1 2 3 4]
(d/remove-at-index [1 2 3 4 5] 4)))
(t/is (= [1 2 3 4]
(d/remove-at-index [5 1 2 3 4] 0)))
(t/is (= [1 2 3 4]
(d/remove-at-index [1 5 2 3 4] 1)))
)
(t/deftest with-next
(t/is (= [[0 1] [1 2] [2 3] [3 4] [4 nil]]
(d/with-next (range 5)))))
(t/deftest with-prev
(t/is (= [[0 nil] [1 0] [2 1] [3 2] [4 3]]
(d/with-prev (range 5)))))
(t/deftest with-prev-next
(t/is (= [[0 nil 1] [1 0 2] [2 1 3] [3 2 4] [4 3 nil]]
(d/with-prev-next (range 5)))))
(t/deftest join
(t/is (= [[1 :a] [1 :b] [2 :a] [2 :b] [3 :a] [3 :b]]
(d/join [1 2 3] [:a :b])))
(t/is (= [1 10 100 2 20 200 3 30 300]
(d/join [1 2 3] [1 10 100] *))))

View file

@ -201,7 +201,7 @@
(recur (->> (get svgdata "elements") (recur (->> (get svgdata "elements")
(filter #(= (get % "name") "g")) (filter #(= (get % "name") "g"))
(map (partial set-path-color id color mapping)) (map (partial set-path-color id color mapping))
(update result "elements" d/concat)) (update result "elements" into))
(rest layers)) (rest layers))
;; Now we have the result containing the svgdata of a ;; Now we have the result containing the svgdata of a
@ -232,8 +232,8 @@
elements (cond->> elements elements (cond->> elements
(not (empty? gradient-defs)) (not (empty? gradient-defs))
(d/concat [{"type" "element" "name" "defs" "attributes" {} (into [{"type" "element" "name" "defs" "attributes" {}
"elements" gradient-defs}]))] "elements" gradient-defs}]))]
(-> result (-> result
(assoc "name" "g") (assoc "name" "g")

View file

@ -547,7 +547,7 @@
(disj flags flag) (disj flags flag)
(conj flags flag))) (conj flags flag)))
stored stored
(into #{} flags))))))) (d/concat-set flags)))))))
;; --- Set element options mode ;; --- Set element options mode
@ -785,8 +785,7 @@
groups-to-delete) groups-to-delete)
u-del-change u-del-change
(d/concat (concat
[]
;; Create the groups ;; Create the groups
(map (fn [group-id] (map (fn [group-id]
(let [group (get objects group-id)] (let [group (get objects group-id)]
@ -937,25 +936,25 @@
:page-id page-id :page-id page-id
:shapes (vec parents)}] :shapes (vec parents)}]
rchanges (d/concat [] rchanges (d/concat-vec
r-mov-change r-mov-change
r-del-change r-del-change
r-mask-change r-mask-change
r-detach-change r-detach-change
r-deroot-change r-deroot-change
r-reroot-change r-reroot-change
r-unconstraint-change r-unconstraint-change
r-reg-change) r-reg-change)
uchanges (d/concat [] uchanges (d/concat-vec
u-del-change u-del-change
u-reroot-change u-reroot-change
u-deroot-change u-deroot-change
u-detach-change u-detach-change
u-mask-change u-mask-change
u-mov-change u-mov-change
u-unconstraint-change u-unconstraint-change
u-reg-change)] u-reg-change)]
[rchanges uchanges])) [rchanges uchanges]))
(defn relocate-shapes (defn relocate-shapes
@ -971,18 +970,15 @@
objects (wsh/lookup-page-objects state page-id) objects (wsh/lookup-page-objects state page-id)
;; Ignore any shape whose parent is also intented to be moved ;; Ignore any shape whose parent is also intented to be moved
ids (cp/clean-loops objects ids) ids (cp/clean-loops objects ids)
;; If we try to move a parent into a child we remove it ;; If we try to move a parent into a child we remove it
ids (filter #(not (cp/is-parent? objects parent-id %)) ids) ids (filter #(not (cp/is-parent? objects parent-id %)) ids)
parents (into #{parent-id} (map #(cp/get-parent % objects)) ids)
parents (reduce (fn [result id]
(conj result (cp/get-parent id objects)))
#{parent-id} ids)
groups-to-delete groups-to-delete
(loop [current-id (first parents) (loop [current-id (first parents)
to-check (rest parents) to-check (rest parents)
removed-id? (set ids) removed-id? (set ids)
result #{}] result #{}]
@ -996,7 +992,7 @@
(empty? (remove removed-id? (:shapes group)))) (empty? (remove removed-id? (:shapes group))))
;; Adds group to the remove and check its parent ;; Adds group to the remove and check its parent
(let [to-check (d/concat [] to-check [(cp/get-parent current-id objects)]) ] (let [to-check (concat to-check [(cp/get-parent current-id objects)])]
(recur (first to-check) (recur (first to-check)
(rest to-check) (rest to-check)
(conj removed-id? current-id) (conj removed-id? current-id)
@ -1023,6 +1019,10 @@
#{} #{}
ids) ids)
;; TODO: Probably implementing this using loop/recur will
;; be more efficient than using reduce and continuos data
;; desturcturing.
;; Sets the correct components metadata for the moved shapes ;; Sets the correct components metadata for the moved shapes
;; `shapes-to-detach` Detach from a component instance a shape that was inside a component and is moved outside ;; `shapes-to-detach` Detach from a component instance a shape that was inside a component and is moved outside
;; `shapes-to-deroot` Removes the root flag from a component instance moved inside another component ;; `shapes-to-deroot` Removes the root flag from a component instance moved inside another component
@ -1204,7 +1204,7 @@
(boolean? hidden) (assoc :hidden hidden))) (boolean? hidden) (assoc :hidden hidden)))
objects (wsh/lookup-page-objects state) objects (wsh/lookup-page-objects state)
ids (d/concat [id] (cp/get-children id objects))] ids (into [id] (cp/get-children id objects))]
(rx/of (dch/update-shapes ids update-fn)))))) (rx/of (dch/update-shapes ids update-fn))))))

View file

@ -50,7 +50,7 @@
(let [old-obj (get objects id) (let [old-obj (get objects id)
new-obj (update-fn old-obj) new-obj (update-fn old-obj)
attrs (or attrs (d/concat #{} (keys old-obj) (keys new-obj))) attrs (or attrs (d/concat-set (keys old-obj) (keys new-obj)))
{rops :rops uops :uops} {rops :rops uops :uops}
(reduce #(generate-operation %1 %2 old-obj new-obj ignore-geometry?) (reduce #(generate-operation %1 %2 old-obj new-obj ignore-geometry?)

View file

@ -9,6 +9,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.common.spec :as us]
[app.main.data.workspace.changes :as dch] [app.main.data.workspace.changes :as dch]
[app.main.data.workspace.common :as dwc] [app.main.data.workspace.common :as dwc]
[app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.state-helpers :as wsh]
@ -51,7 +52,7 @@
(empty? (remove removed-id? (:shapes group)))) (empty? (remove removed-id? (:shapes group))))
;; Adds group to the remove and check its parent ;; Adds group to the remove and check its parent
(let [to-check (d/concat [] to-check [(cp/get-parent current-id objects)]) ] (let [to-check (concat to-check [(cp/get-parent current-id objects)]) ]
(recur (first to-check) (recur (first to-check)
(rest to-check) (rest to-check)
(conj removed-id? current-id) (conj removed-id? current-id)
@ -131,6 +132,7 @@
uchanges (->> ids-to-delete uchanges (->> ids-to-delete
(reduce add-deleted-group uchanges))] (reduce add-deleted-group uchanges))]
[group rchanges uchanges])) [group rchanges uchanges]))
(defn prepare-remove-group (defn prepare-remove-group
@ -138,10 +140,13 @@
(let [shapes (:shapes group) (let [shapes (:shapes group)
parent-id (cp/get-parent (:id group) objects) parent-id (cp/get-parent (:id group) objects)
parent (get objects parent-id) parent (get objects parent-id)
index-in-parent (->> (:shapes parent)
(map-indexed vector) index-in-parent
(filter #(#{(:id group)} (second %))) (->> (:shapes parent)
(ffirst)) (map-indexed vector)
(filter #(#{(:id group)} (second %)))
(ffirst))
rchanges [{:type :mov-objects rchanges [{:type :mov-objects
:page-id page-id :page-id page-id
:parent-id parent-id :parent-id parent-id
@ -244,61 +249,67 @@
[(first shapes) [] []] [(first shapes) [] []]
(prepare-create-group objects page-id shapes "Group-1" true)) (prepare-create-group objects page-id shapes "Group-1" true))
;; Assertions just for documentation purposes
_ (us/assert vector? rchanges)
_ (us/assert vector? uchanges)
children (map #(get objects %) (:shapes group)) children (map #(get objects %) (:shapes group))
rchanges (d/concat rchanges rchanges (d/concat-vec
(for [child children] rchanges
{:type :mod-obj (for [child children]
:page-id page-id {:type :mod-obj
:id (:id child) :page-id page-id
:operations [{:type :set :id (:id child)
:attr :constraints-h :operations [{:type :set
:val :scale} :attr :constraints-h
{:type :set :val :scale}
:attr :constraints-v {:type :set
:val :scale}]}) :attr :constraints-v
[{:type :mod-obj :val :scale}]})
:page-id page-id [{:type :mod-obj
:id (:id group) :page-id page-id
:operations [{:type :set :id (:id group)
:attr :masked-group? :operations [{:type :set
:val true} :attr :masked-group?
{:type :set :val true}
:attr :selrect {:type :set
:val (-> shapes first :selrect)} :attr :selrect
{:type :set :val (-> shapes first :selrect)}
:attr :points {:type :set
:val (-> shapes first :points)} :attr :points
{:type :set :val (-> shapes first :points)}
:attr :transform {:type :set
:val (-> shapes first :transform)} :attr :transform
{:type :set :val (-> shapes first :transform)}
:attr :transform-inverse {:type :set
:val (-> shapes first :transform-inverse)}]} :attr :transform-inverse
{:type :reg-objects :val (-> shapes first :transform-inverse)}]}
:page-id page-id {:type :reg-objects
:shapes [(:id group)]}]) :page-id page-id
:shapes [(:id group)]}])
uchanges (d/concat uchanges uchanges (d/concat-vec
(for [child children] uchanges
{:type :mod-obj (for [child children]
:page-id page-id {:type :mod-obj
:id (:id child) :page-id page-id
:operations [{:type :set :id (:id child)
:attr :constraints-h :operations [{:type :set
:val (:constraints-h child)} :attr :constraints-h
{:type :set :val (:constraints-h child)}
:attr :constraints-v {:type :set
:val (:constraints-v child)}]}) :attr :constraints-v
[{:type :mod-obj :val (:constraints-v child)}]})
:page-id page-id [{:type :mod-obj
:id (:id group) :page-id page-id
:operations [{:type :set :id (:id group)
:attr :masked-group? :operations [{:type :set
:val nil}]} :attr :masked-group?
{:type :reg-objects :val nil}]}
:page-id page-id {:type :reg-objects
:shapes [(:id group)]}])] :page-id page-id
:shapes [(:id group)]}])]
(rx/of (dch/commit-changes {:redo-changes rchanges (rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges :undo-changes uchanges

View file

@ -666,14 +666,14 @@
(dwlh/generate-sync-file file-id :typographies library-id state)] (dwlh/generate-sync-file file-id :typographies library-id state)]
xf-fcat (comp (remove nil?) (map first) (mapcat identity)) xf-fcat (comp (remove nil?) (map first) (mapcat identity))
rchanges (d/concat [] rchanges (d/concat-vec
(sequence xf-fcat library-changes) (sequence xf-fcat library-changes)
(sequence xf-fcat file-changes)) (sequence xf-fcat file-changes))
xf-scat (comp (remove nil?) (map second) (mapcat identity)) xf-scat (comp (remove nil?) (map second) (mapcat identity))
uchanges (d/concat [] uchanges (d/concat-vec
(sequence xf-scat library-changes) (sequence xf-scat library-changes)
(sequence xf-scat file-changes))] (sequence xf-scat file-changes))]
(log/debug :msg "SYNC-FILE finished" :js/rchanges (log-changes (log/debug :msg "SYNC-FILE finished" :js/rchanges (log-changes
rchanges rchanges
@ -720,8 +720,8 @@
(let [file (dwlh/get-file state file-id) (let [file (dwlh/get-file state file-id)
[rchanges1 uchanges1] (dwlh/generate-sync-file file-id :components library-id state) [rchanges1 uchanges1] (dwlh/generate-sync-file file-id :components library-id state)
[rchanges2 uchanges2] (dwlh/generate-sync-library file-id :components library-id state) [rchanges2 uchanges2] (dwlh/generate-sync-library file-id :components library-id state)
rchanges (d/concat rchanges1 rchanges2) rchanges (d/concat-vec rchanges1 rchanges2)
uchanges (d/concat uchanges1 uchanges2)] uchanges (d/concat-vec uchanges1 uchanges2)]
(when rchanges (when rchanges
(log/debug :msg "SYNC-FILE (2nd stage) finished" :js/rchanges (log-changes (log/debug :msg "SYNC-FILE (2nd stage) finished" :js/rchanges (log-changes
rchanges rchanges

View file

@ -54,8 +54,8 @@
(defn concat-changes (defn concat-changes
[[rchanges1 uchanges1] [rchanges2 uchanges2]] [[rchanges1 uchanges1] [rchanges2 uchanges2]]
[(d/concat rchanges1 rchanges2) [(d/concat-vec rchanges1 rchanges2)
(d/concat uchanges1 uchanges2)]) (d/concat-vec uchanges1 uchanges2)])
(defn get-local-file (defn get-local-file
[state] [state]
@ -134,6 +134,10 @@
[(first shapes) [] []] [(first shapes) [] []]
(dwg/prepare-create-group objects page-id shapes "Component-1" true)) (dwg/prepare-create-group objects page-id shapes "Component-1" true))
;; Asserts for documentation purposes
_ (us/assert vector? rchanges)
_ (us/assert vector? uchanges)
[new-shape new-shapes updated-shapes] [new-shape new-shapes updated-shapes]
(make-component-shape group objects file-id) (make-component-shape group objects file-id)
@ -288,8 +292,8 @@
state state
(cp/make-container page :page))] (cp/make-container page :page))]
(recur (next pages) (recur (next pages)
(d/concat rchanges page-rchanges) (into rchanges page-rchanges)
(d/concat uchanges page-uchanges))) (into uchanges page-uchanges)))
[rchanges uchanges])))) [rchanges uchanges]))))
(defn generate-sync-library (defn generate-sync-library
@ -315,8 +319,8 @@
(cp/make-container local-component (cp/make-container local-component
:component))] :component))]
(recur (next local-components) (recur (next local-components)
(d/concat rchanges comp-rchanges) (into rchanges comp-rchanges)
(d/concat uchanges comp-uchanges))) (into uchanges comp-uchanges)))
[rchanges uchanges])))) [rchanges uchanges]))))
(defn- generate-sync-container (defn- generate-sync-container
@ -341,8 +345,8 @@
container container
shape)] shape)]
(recur (next shapes) (recur (next shapes)
(d/concat rchanges shape-rchanges) (into rchanges shape-rchanges)
(d/concat uchanges shape-uchanges))) (into uchanges shape-uchanges)))
[rchanges uchanges])))) [rchanges uchanges]))))
(defn- has-asset-reference-fn (defn- has-asset-reference-fn
@ -438,7 +442,7 @@
:fill-color-ref-id nil :fill-color-ref-id nil
:fill-color-ref-file nil)))] :fill-color-ref-file nil)))]
(generate-sync-text-shape shape container update-node)) (generate-sync-text-shape shape container update-node))
(loop [attrs (seq color-sync-attrs) (loop [attrs (seq color-sync-attrs)
roperations [] roperations []
uoperations []] uoperations []]
(let [[attr-ref-id attr-ref-file color-attr attr] (first attrs)] (let [[attr-ref-id attr-ref-file color-attr attr] (first attrs)]
@ -490,8 +494,8 @@
:val (get shape attr-ref-file) :val (get shape attr-ref-file)
:ignore-touched true}])] :ignore-touched true}])]
(recur (next attrs) (recur (next attrs)
(concat roperations roperations') (into roperations roperations')
(concat uoperations uoperations')))))))))) (into uoperations uoperations'))))))))))
(defmethod generate-sync-shape :typographies (defmethod generate-sync-shape :typographies
[_ library-id state container shape] [_ library-id state container shape]
@ -734,8 +738,8 @@
moved moved
false)] false)]
[(d/concat rchanges child-rchanges) [(d/concat-vec rchanges child-rchanges)
(d/concat uchanges child-uchanges)]))) (d/concat-vec uchanges child-uchanges)])))
(defn generate-sync-shape-inverse (defn generate-sync-shape-inverse
"Generate changes to update the component a shape is linked to, from "Generate changes to update the component a shape is linked to, from
@ -862,8 +866,8 @@
rchanges (mapv check-local rchanges) rchanges (mapv check-local rchanges)
uchanges (mapv check-local uchanges)] uchanges (mapv check-local uchanges)]
[(d/concat rchanges child-rchanges) [(d/concat-vec rchanges child-rchanges)
(d/concat uchanges child-uchanges)]))) (d/concat-vec uchanges child-uchanges)])))
; ---- Operation generation helpers ---- ; ---- Operation generation helpers ----
@ -963,33 +967,32 @@
update-new-shape update-new-shape
update-original-shape) update-original-shape)
rchanges (d/concat rchanges (d/concat-vec
(mapv (fn [shape'] (map (fn [shape']
(make-change (make-change
container container
(as-> {:type :add-obj (as-> {:type :add-obj
:id (:id shape') :id (:id shape')
:parent-id (:parent-id shape') :parent-id (:parent-id shape')
:index index :index index
:ignore-touched true :ignore-touched true
:obj shape'} $ :obj shape'} $
(cond-> $ (cond-> $
(:frame-id shape') (:frame-id shape')
(assoc :frame-id (:frame-id shape')))))) (assoc :frame-id (:frame-id shape'))))))
new-shapes) new-shapes)
[(make-change [(make-change
container container
{:type :reg-objects {:type :reg-objects
:shapes all-parents})]) :shapes all-parents})])
uchanges (d/concat uchanges (mapv (fn [shape']
(mapv (fn [shape'] (make-change
(make-change container
container {:type :del-obj
{:type :del-obj :id (:id shape')
:id (:id shape') :ignore-touched true}))
:ignore-touched true})) new-shapes)]
new-shapes))]
(if (and (cp/touched-group? parent-shape :shapes-group) omit-touched?) (if (and (cp/touched-group? parent-shape :shapes-group) omit-touched?)
empty-changes empty-changes
@ -1024,47 +1027,46 @@
update-new-shape update-new-shape
update-original-shape) update-original-shape)
rchanges (d/concat rchanges (d/concat-vec
(mapv (fn [shape'] (map (fn [shape']
{:type :add-obj {:type :add-obj
:id (:id shape') :id (:id shape')
:component-id (:id component) :component-id (:id component)
:parent-id (:parent-id shape') :parent-id (:parent-id shape')
:index index :index index
:ignore-touched true :ignore-touched true
:obj shape'}) :obj shape'})
new-shapes) new-shapes)
[{:type :reg-objects [{:type :reg-objects
:component-id (:id component) :component-id (:id component)
:shapes all-parents}] :shapes all-parents}]
(mapv (fn [shape'] (map (fn [shape']
{: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 :component-id :attr :component-id
:val (:component-id shape')} :val (:component-id shape')}
{:type :set {:type :set
:attr :component-file :attr :component-file
:val (:component-file shape')} :val (:component-file shape')}
{:type :set {:type :set
:attr :component-root? :attr :component-root?
:val (:component-root? shape')} :val (:component-root? shape')}
{:type :set {:type :set
:attr :shape-ref :attr :shape-ref
:val (:shape-ref shape')} :val (:shape-ref shape')}
{:type :set {:type :set
:attr :touched :attr :touched
:val (:touched shape')}]}) :val (:touched shape')}]})
updated-shapes)) updated-shapes))
uchanges (d/concat uchanges (mapv (fn [shape']
(mapv (fn [shape'] {:type :del-obj
{:type :del-obj :id (:id shape')
:id (:id shape') :page-id (:id page)
:page-id (:id page) :ignore-touched true})
:ignore-touched true}) new-shapes)]
new-shapes))]
[rchanges uchanges])) [rchanges uchanges]))
@ -1102,13 +1104,13 @@
(:frame-id shape') (:frame-id shape')
(assoc :frame-id (:frame-id shape'))))))) (assoc :frame-id (:frame-id shape')))))))
uchanges (d/concat uchanges (d/concat-vec
[(add-change (:id shape))] [(add-change (:id shape))]
(map add-change children) (map add-change children)
[(make-change [(make-change
container container
{:type :reg-objects {:type :reg-objects
:shapes (vec parents)})])] :shapes (vec parents)})])]
(if (and (cp/touched-group? parent :shapes-group) omit-touched?) (if (and (cp/touched-group? parent :shapes-group) omit-touched?)
empty-changes empty-changes

View file

@ -6,7 +6,6 @@
(ns app.main.data.workspace.path.state (ns app.main.data.workspace.path.state
(:require (:require
[app.common.data :as d]
[app.common.path.shapes-to-path :as upsp])) [app.common.path.shapes-to-path :as upsp]))
(defn get-path-id (defn get-path-id
@ -19,11 +18,10 @@
[state & ks] [state & ks]
(let [edit-id (get-in state [:workspace-local :edition]) (let [edit-id (get-in state [:workspace-local :edition])
page-id (:current-page-id state)] page-id (:current-page-id state)]
(d/concat (into (if edit-id
(if edit-id [:workspace-data :pages-index page-id :objects edit-id]
[:workspace-data :pages-index page-id :objects edit-id] [:workspace-drawing :object])
[:workspace-drawing :object]) ks)))
ks)))
(defn get-path (defn get-path
"Retrieves the location of the path object and additionally can pass "Retrieves the location of the path object and additionally can pass

View file

@ -409,8 +409,10 @@
:shapes [shape-id]}] :shapes [shape-id]}]
;; Careful! the undo changes are concatenated reversed (we undo in reverse order ;; Careful! the undo changes are concatenated reversed (we undo in reverse order
changes [(d/concat rchs rch1 rch2) (d/concat uch1 uchs)] changes [(d/concat-vec rchs rch1 rch2)
unames (conj unames (:name shape)) (d/concat-vec uch1 uchs)]
unames (conj unames (:name shape))
reducer-fn (partial add-svg-child-changes page-id objects selected frame-id shape-id svg-data)] reducer-fn (partial add-svg-child-changes page-id objects selected frame-id shape-id svg-data)]
(reduce reducer-fn [unames changes] (d/enumerate children))) (reduce reducer-fn [unames changes] (d/enumerate children)))

View file

@ -25,7 +25,6 @@
[cljs.spec.alpha :as s] [cljs.spec.alpha :as s]
[potok.core :as ptk])) [potok.core :as ptk]))
;; -- Helpers -------------------------------------------------------- ;; -- Helpers --------------------------------------------------------
;; For each of the 8 handlers gives the multiplier for resize ;; For each of the 8 handlers gives the multiplier for resize
@ -123,8 +122,7 @@
(let [modifiers (or modifiers (get-in state [:workspace-local :modifiers] {})) (let [modifiers (or modifiers (get-in state [:workspace-local :modifiers] {}))
page-id (:current-page-id state) page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id) objects (wsh/lookup-page-objects state page-id)
ids (into #{} (remove #(get-in objects [% :blocked] false)) ids)]
ids (->> ids (into #{} (remove #(get-in objects [% :blocked] false))))]
(reduce (fn [state id] (reduce (fn [state id]
(update state :workspace-modifiers (update state :workspace-modifiers
@ -148,20 +146,19 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [objects (wsh/lookup-page-objects state) (let [objects (wsh/lookup-page-objects state)
id->obj #(get objects %) shapes (->> shapes
get-children (fn [shape] (map id->obj (cp/get-children (:id shape) objects))) (remove #(get % :blocked false))
(mapcat (fn [shape]
shapes (->> shapes (into [] (remove #(get % :blocked false)))) (->> (cp/get-children (:id shape) objects)
(map #(get objects %)))))
shapes (->> shapes (mapcat get-children) (concat shapes)) (concat shapes))
update-shape update-shape
(fn [modifiers shape] (fn [modifiers shape]
(let [rotate-modifiers (gsh/rotation-modifiers shape center angle)] (let [rotate-modifiers (gsh/rotation-modifiers shape center angle)]
(assoc-in modifiers [(:id shape) :modifiers] rotate-modifiers)))] (assoc-in modifiers [(:id shape) :modifiers] rotate-modifiers)))]
(-> state
(update :workspace-modifiers (update state :workspace-modifiers #(reduce update-shape % shapes)))))))
#(reduce update-shape % shapes))))))))
(defn- apply-modifiers (defn- apply-modifiers
[ids] [ids]
@ -169,11 +166,11 @@
(ptk/reify ::apply-modifiers (ptk/reify ::apply-modifiers
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [objects (wsh/lookup-page-objects state) (let [objects (wsh/lookup-page-objects state)
children-ids (->> ids (mapcat #(cp/get-children % objects))) children-ids (->> ids (mapcat #(cp/get-children % objects)))
ids-with-children (d/concat [] children-ids ids) ids-with-children (d/concat-vec children-ids ids)
object-modifiers (get state :workspace-modifiers) object-modifiers (get state :workspace-modifiers)
ignore-tree (d/mapm #(get-in %2 [:modifiers :ignore-geometry?]) object-modifiers)] ignore-tree (d/mapm #(get-in %2 [:modifiers :ignore-geometry?]) object-modifiers)]
(rx/of (dwu/start-undo-transaction) (rx/of (dwu/start-undo-transaction)
(dch/update-shapes (dch/update-shapes
@ -423,7 +420,10 @@
(watch [_ state _] (watch [_ state _]
(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)
ids (d/concat [] ids (mapcat #(cp/get-children % objects) ids))]
;; TODO: looks completly redundant operation because
;; apply-modifiers already finds all children.
ids (d/concat-vec ids (mapcat #(cp/get-children % objects) ids))]
(rx/of (apply-modifiers ids)))))) (rx/of (apply-modifiers ids))))))

View file

@ -168,9 +168,8 @@
(map between-snap)) (map between-snap))
;; Search the minimum snap ;; Search the minimum snap
snap-list (-> [] (d/concat lt-snap) (d/concat gt-snap) (d/concat between-snap)) snap-list (d/concat-vec lt-snap gt-snap between-snap)
min-snap (reduce best-snap ##Inf snap-list)]
min-snap (reduce best-snap ##Inf snap-list)]
(if (mth/finite? min-snap) [0 min-snap] nil))) (if (mth/finite? min-snap) [0 min-snap] nil)))
@ -291,8 +290,7 @@
(set (keys other)))] (set (keys other)))]
(into {} (into {}
(map (fn [key] (map (fn [key]
[key [key (d/concat-vec (get matches key []) (get other key []))]))
(d/concat [] (get matches key []) (get other key []))]))
keys)))] keys)))]
(-> matches (-> matches

View file

@ -192,7 +192,7 @@
h-lines (->> (calculate-distance-lines (:x1 from) (:x2 from) (:x1 to) (:x2 to)) h-lines (->> (calculate-distance-lines (:x1 from) (:x2 from) (:x1 to) (:x2 to))
(map (fn [[start end]] [start fixed-y end fixed-y]))) (map (fn [[start end]] [start fixed-y end fixed-y])))
lines (d/concat [] v-lines h-lines) lines (d/concat-vec v-lines h-lines)
distance-line-stroke (/ distance-line-stroke zoom)] distance-line-stroke (/ distance-line-stroke zoom)]

View file

@ -6,7 +6,6 @@
(ns app.main.ui.settings.options (ns app.main.ui.settings.options
(:require (:require
[app.common.data :as d]
[app.common.spec :as us] [app.common.spec :as us]
[app.main.data.messages :as dm] [app.main.data.messages :as dm]
[app.main.data.users :as du] [app.main.data.users :as du]
@ -49,8 +48,8 @@
[:h2 (t locale "labels.language")] [:h2 (t locale "labels.language")]
[:div.fields-row [:div.fields-row
[:& fm/select {:options (d/concat [{:label "Auto (browser)" :value ""}] [:& fm/select {:options (into [{:label "Auto (browser)" :value ""}]
i18n/supported-locales) i18n/supported-locales)
:label (t locale "dashboard.select-ui-language") :label (t locale "dashboard.select-ui-language")
:default "" :default ""
:name :lang}]] :name :lang}]]

View file

@ -149,8 +149,7 @@
(defn shape->filters (defn shape->filters
[shape] [shape]
(d/concat (d/concat-vec
[]
[{:id "BackgroundImageFix" :type :image-fix}] [{:id "BackgroundImageFix" :type :image-fix}]
;; Background blur won't work in current SVG specification ;; Background blur won't work in current SVG specification

View file

@ -53,7 +53,7 @@
(fn [index] (fn [index]
(swap! exports (fn [exports] (swap! exports (fn [exports]
(let [[before after] (split-at index exports)] (let [[before after] (split-at index exports)]
(d/concat [] before (rest after))))))) (d/concat-vec before (rest after)))))))
on-scale-change on-scale-change
(mf/use-callback (mf/use-callback

View file

@ -36,7 +36,7 @@
update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)] update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)]
(->> (cp/get-children frame-id objects) (->> (cp/get-children frame-id objects)
(d/concat [frame-id]) (into [frame-id])
(reduce update-fn objects))))) (reduce update-fn objects)))))

View file

@ -7,7 +7,6 @@
(ns app.main.ui.viewer.shapes (ns app.main.ui.viewer.shapes
"The main container for a frame in viewer mode" "The main container for a frame in viewer mode"
(:require (:require
[app.common.data :as d]
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom] [app.common.geom.shapes :as geom]
@ -396,7 +395,7 @@
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier) update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)
frame-id (:id frame) frame-id (:id frame)
modifier-ids (d/concat [frame-id] (cp/get-children frame-id objects)) modifier-ids (into [frame-id] (cp/get-children frame-id objects))
objects (reduce update-fn objects modifier-ids) objects (reduce update-fn objects modifier-ids)
frame (assoc-in frame [:modifiers :displacement] modifier) frame (assoc-in frame [:modifiers :displacement] modifier)

View file

@ -6,7 +6,6 @@
(ns app.main.ui.workspace.shapes.path.editor (ns app.main.ui.workspace.shapes.path.editor
(:require (:require
[app.common.data :as d]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as gsp] [app.common.geom.shapes.path :as gsp]
[app.common.path.commands :as upc] [app.common.path.commands :as upc]
@ -166,9 +165,9 @@
:zoom zoom}]]) :zoom zoom}]])
(mf/defc path-snap [{:keys [selected points zoom]}] (mf/defc path-snap [{:keys [selected points zoom]}]
(let [ranges (mf/use-memo (mf/deps selected points) #(snap/create-ranges points selected)) (let [ranges (mf/use-memo (mf/deps selected points) #(snap/create-ranges points selected))
snap-matches (snap/get-snap-delta-match selected ranges (/ 1 zoom)) snap-matches (snap/get-snap-delta-match selected ranges (/ 1 zoom))
matches (d/concat [] (second (:x snap-matches)) (second (:y snap-matches)))] matches (concat (second (:x snap-matches)) (second (:y snap-matches)))]
[:g.snap-paths [:g.snap-paths
(for [[from to] matches] (for [[from to] matches]

View file

@ -75,7 +75,7 @@
(mf/deps shape) (mf/deps shape)
(fn [index] (fn [index]
(let [[before after] (split-at index exports) (let [[before after] (split-at index exports)
exports (d/concat [] before (rest after))] exports (d/concat-vec before (rest after))]
(st/emit! (udw/update-shape (:id shape) (st/emit! (udw/update-shape (:id shape)
{:exports exports}))))) {:exports exports})))))

View file

@ -68,17 +68,19 @@
(def root-attrs text-valign-attrs) (def root-attrs text-valign-attrs)
(def paragraph-attrs (def paragraph-attrs
(d/concat text-align-attrs (d/concat-vec
text-direction-attrs)) text-align-attrs
text-direction-attrs))
(def text-attrs (def text-attrs
(d/concat text-typography-attrs (d/concat-vec
text-font-attrs text-typography-attrs
text-spacing-attrs text-font-attrs
text-decoration-attrs text-spacing-attrs
text-transform-attrs)) text-decoration-attrs
text-transform-attrs))
(def attrs (d/concat #{} shape-attrs root-attrs paragraph-attrs text-attrs)) (def attrs (d/concat-set shape-attrs root-attrs paragraph-attrs text-attrs))
(mf/defc text-align-options (mf/defc text-align-options
[{:keys [values on-change on-blur] :as props}] [{:keys [values on-change on-blur] :as props}]
@ -270,10 +272,10 @@
on-convert-to-typography on-convert-to-typography
(fn [_] (fn [_]
(let [set-values (-> (d/without-nils values) (let [set-values (-> (d/without-nils values)
(select-keys (select-keys
(d/concat text-font-attrs (d/concat-vec text-font-attrs
text-spacing-attrs text-spacing-attrs
text-transform-attrs))) text-transform-attrs)))
typography (merge txt/default-typography set-values) typography (merge txt/default-typography set-values)
typography (generate-typography-name typography) typography (generate-typography-name typography)
id (uuid/next)] id (uuid/next)]

View file

@ -183,7 +183,7 @@
(attrs/get-attrs-multi (txt/node-seq content) attrs))))] (attrs/get-attrs-multi (txt/node-seq content) attrs))))]
:children (let [children (->> (:shapes shape []) (map #(get objects %))) :children (let [children (->> (:shapes shape []) (map #(get objects %)))
[new-ids new-values] (get-attrs children objects attr-type)] [new-ids new-values] (get-attrs children objects attr-type)]
[(d/concat ids new-ids) (merge-attrs values new-values)]) [(into ids new-ids) (merge-attrs values new-values)])
[])))] [])))]
(reduce extract-attrs [[] []] shapes))) (reduce extract-attrs [[] []] shapes)))

View file

@ -6,7 +6,6 @@
(ns app.main.ui.workspace.viewport.hooks (ns app.main.ui.workspace.viewport.hooks
(:require (:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.main.data.shortcuts :as dsc] [app.main.data.shortcuts :as dsc]
@ -162,10 +161,9 @@
remove-xfm (mapcat #(cp/get-parents % objects)) remove-xfm (mapcat #(cp/get-parents % objects))
remove-id? (cond-> (into #{} remove-xfm selected) remove-id? (cond-> (into #{} remove-xfm selected)
@ctrl? @ctrl?
(d/concat (filterv is-group? ids))) (into (filter is-group?) ids))
ids (->> ids (filterv (comp not remove-id?)))
ids (filterv (comp not remove-id?) ids)
hover-shape (get objects (first ids))] hover-shape (get objects (first ids))]
(reset! hover hover-shape) (reset! hover hover-shape)

View file

@ -163,12 +163,12 @@
show-candidate? #(check-in-set % distances) show-candidate? #(check-in-set % distances)
;; Checks the distances between elements for distances that match the set of distances ;; Checks the distances between elements for distances that match the set of distances
distance-coincidences (d/concat (get-shapes-match show-candidate? lt-shapes) distance-coincidences (d/concat-vec
(get-shapes-match show-candidate? gt-shapes)) (get-shapes-match show-candidate? lt-shapes)
(get-shapes-match show-candidate? gt-shapes))
;; Stores the distance candidates to be shown ;; Stores the distance candidates to be shown
distance-candidates (d/concat distance-candidates (d/concat-set
#{}
(map first distance-coincidences) (map first distance-coincidences)
(filter #(check-in-set % lt-distances) gt-distances) (filter #(check-in-set % lt-distances) gt-distances)
(filter #(check-in-set % gt-distances) lt-distances)) (filter #(check-in-set % gt-distances) lt-distances))
@ -194,7 +194,7 @@
(filter #(show-distance? (distance-to-selrect %))) (filter #(show-distance? (distance-to-selrect %)))
(map #(vector selrect (:selrect %)))) (map #(vector selrect (:selrect %))))
segments-to-display (d/concat #{} other-shapes-segments selection-segments)] segments-to-display (d/concat-set other-shapes-segments selection-segments)]
segments-to-display)) segments-to-display))
(mf/defc shape-distance (mf/defc shape-distance

View file

@ -121,7 +121,7 @@
(rx/switch-map #(rx/combine-latest (get-snap :x %) (rx/switch-map #(rx/combine-latest (get-snap :x %)
(get-snap :y %))) (get-snap :y %)))
(rx/map (fn [result] (rx/map (fn [result]
(apply d/concat (seq result)))) (apply d/concat-vec (seq result))))
(rx/subs #(let [rs (filter (fn [[_ snaps _]] (> (count snaps) 0)) %)] (rx/subs #(let [rs (filter (fn [[_ snaps _]] (> (count snaps) 0)) %)]
(reset! state rs))))] (reset! state rs))))]

View file

@ -60,14 +60,14 @@
param-list (extract-params cmd [[:x :number] param-list (extract-params cmd [[:x :number]
[:y :number]])] [:y :number]])]
(d/concat [{:command :move-to (into [{:command :move-to
:relative relative :relative relative
:params (first param-list)}] :params (first param-list)}]
(for [params (rest param-list)] (for [params (rest param-list)]
{:command :line-to {:command :line-to
:relative relative :relative relative
:params params})))) :params params}))))
(defmethod parse-command "Z" [_] (defmethod parse-command "Z" [_]
[{:command :close-path}]) [{:command :close-path}])
@ -259,7 +259,7 @@
(update :params merge (quadratic->curve prev-pos (gpt/point params) (upg/calculate-opposite-handler prev-pos prev-qc))))) (update :params merge (quadratic->curve prev-pos (gpt/point params) (upg/calculate-opposite-handler prev-pos prev-qc)))))
result (if (= :elliptical-arc (:command command)) result (if (= :elliptical-arc (:command command))
(d/concat result (arc->beziers prev-pos command)) (into result (arc->beziers prev-pos command))
(conj result command)) (conj result command))
next-cc (case (:command orig-command) next-cc (case (:command orig-command)

View file

@ -304,7 +304,7 @@
[content points] [content points]
(let [segments-set (into #{} (let [segments-set (into #{}
(map (fn [{:keys [start end]}] [start end])) (juxt :start :end)
(get-segments content points)) (get-segments content points))
create-line-command (fn [point other] create-line-command (fn [point other]
@ -318,7 +318,7 @@
(flatten) (flatten)
(into []))] (into []))]
(d/concat content new-content))) (into content new-content)))
(defn separate-nodes (defn separate-nodes

View file

@ -630,8 +630,7 @@
(defn find-node-references [node] (defn find-node-references [node]
(let [current (->> (find-attr-references (:attrs node)) (into #{})) (let [current (->> (find-attr-references (:attrs node)) (into #{}))
children (->> (:content node) (map find-node-references) (flatten) (into #{}))] children (->> (:content node) (map find-node-references) (flatten) (into #{}))]
(-> (d/concat current children) (vec (into current children))))
(vec))))
(defn find-def-references [defs references] (defn find-def-references [defs references]
(loop [result (into #{} references) (loop [result (into #{} references)
@ -653,7 +652,7 @@
(let [node (get defs to-check) (let [node (get defs to-check)
new-refs (find-node-references node) new-refs (find-node-references node)
pending (concat pending new-refs)] pending (concat pending new-refs)]
(recur (d/concat result new-refs) (recur (into result new-refs)
(conj checked? to-check) (conj checked? to-check)
(first pending) (first pending)
(rest pending)))))) (rest pending))))))

View file

@ -292,7 +292,7 @@
:file-id (:component-file shape)}) :file-id (:component-file shape)})
(= :text (:type shape)) (= :text (:type shape))
(d/concat (get-text-refs (:content shape)))))] (into (get-text-refs (:content shape)))))]
(->> (get-in file [:data :pages-index]) (->> (get-in file [:data :pages-index])
(vals) (vals)

View file

@ -66,7 +66,7 @@
changed-ids (into #{} changed-ids (into #{}
(comp (filter #(not= % uuid/zero)) (comp (filter #(not= % uuid/zero))
(filter changes?) (filter changes?)
(mapcat #(d/concat [%] (cp/get-children % new-objects)))) (mapcat #(into [%] (cp/get-children % new-objects))))
(set/union (set (keys old-objects)) (set/union (set (keys old-objects))
(set (keys new-objects)))) (set (keys new-objects))))

View file

@ -22,13 +22,11 @@
(let [points (when-not (:hidden shape) (snap/shape-snap-points shape)) (let [points (when-not (:hidden shape) (snap/shape-snap-points shape))
shape-data (->> points (mapv #(vector % (:id shape))))] shape-data (->> points (mapv #(vector % (:id shape))))]
(if (= (:id shape) frame-id) (if (= (:id shape) frame-id)
(d/concat (into shape-data
shape-data
;; The grid points are only added by the "root" of the coord-dat
(->> (gg/grid-snap-points shape coord)
(map #(vector % :layout))))
;; The grid points are only added by the "root" of the coord-dat
(->> (gg/grid-snap-points shape coord)
(map #(vector % :layout))))
shape-data)))) shape-data))))
(defn- add-coord-data (defn- add-coord-data