diff --git a/common/src/app/common/types/container.cljc b/common/src/app/common/types/container.cljc index 3a7f88c12..e7a91d621 100644 --- a/common/src/app/common/types/container.cljc +++ b/common/src/app/common/types/container.cljc @@ -538,6 +538,91 @@ [parent-id (get-frame parent-id)] (recur (:parent-id parent) objects children pasting? libraries)))))) +(defn reduce-shapes + [container initial & {:keys [shape-id + on-main-root-top + on-copy-root-top + on-main-root-nested + on-copy-root-nested + on-copy-not-root + on-main-not-root + on-not-component] + :or {shape-id uuid/zero}}] + + (letfn [(process-shape [shape-id container context acc] + (let [shape (ctst/get-shape container shape-id)] + (if (ctk/instance-head? shape) + (if (ctk/instance-root? shape) + (if (ctk/main-instance? shape) + (process-shape-main-root-top shape container context acc) + (process-shape-copy-root-top shape container context acc)) + (if (ctk/main-instance? shape) + (process-shape-main-root-nested container shape context acc) + (process-shape-copy-root-nested container shape context acc))) + (if (ctk/in-component-copy? shape) + (process-shape-copy-not-root shape container context acc) + (if (inside-component-main? (:objects container) shape) + (process-shape-main-not-root shape container context acc) + (process-shape-not-component shape container context acc)))))) + + (process-shape-main-root-top [shape container context acc] + (let [acc (cond->> acc + (some? on-main-root-top) + (on-main-root-top shape context))] + (reduce #(process-shape %2 container :main-top %1) + acc + (:shapes shape)))) + + (process-shape-copy-root-top [shape container context acc] + (let [acc (cond->> acc + (some? on-copy-root-top) + (on-copy-root-top shape context))] + (reduce #(process-shape %2 container :copy-top %1) + acc + (:shapes shape)))) + + (process-shape-main-root-nested [shape container context acc] + (let [acc (cond->> acc + (some? on-main-root-nested) + (on-main-root-nested shape context))] + (reduce #(process-shape %2 container :main-nested %1) + acc + (:shapes shape)))) + + (process-shape-copy-root-nested [shape container context acc] + (let [acc (cond->> acc + (some? on-copy-root-nested) + (on-copy-root-nested shape context))] + (reduce #(process-shape %2 container :copy-nested %1) + acc + (:shapes shape)))) + + (process-shape-copy-not-root [shape container context acc] + (let [acc (cond->> acc + (some? on-copy-not-root) + (on-copy-not-root shape context))] + (reduce #(process-shape %2 container :copy-any %1) + acc + (:shapes shape)))) + + (process-shape-main-not-root [shape container context acc] + (let [acc (cond->> acc + (some? on-main-not-root) + (on-main-not-root shape context))] + (reduce #(process-shape %2 container :main-any %1) + acc + (:shapes shape)))) + + (process-shape-not-component [shape container context acc] + (let [acc (cond->> acc + (some? on-not-component) + (on-not-component shape context))] + (reduce #(process-shape %2 container :not-component %1) + acc + (:shapes shape))))] + + (process-shape shape-id container :not-component initial))) + ;; --- SHAPE UPDATE (defn set-shape-attr diff --git a/common/test/common_tests/types/types_container_test.cljc b/common/test/common_tests/types/types_container_test.cljc new file mode 100644 index 000000000..727ec103b --- /dev/null +++ b/common/test/common_tests/types/types_container_test.cljc @@ -0,0 +1,42 @@ +;; 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) KALEIDOS INC + +(ns common-tests.types.types-container-test + (:require +;; [app.common.data :as d] +;; [app.common.test-helpers.components :as thc] +;; [app.common.test-helpers.compositions :as tho] + [app.common.test-helpers.files :as thf] + [app.common.test-helpers.ids-map :as thi] + [app.common.test-helpers.shapes :as ths] + [app.common.types.container :as ctn] +;; [app.common.text :as txt] +;; [app.common.types.colors-list :as ctcl] +;; [app.common.types.component :as ctk] +;; [app.common.types.components-list :as ctkl] +;; [app.common.types.file :as ctf] +;; [app.common.types.pages-list :as ctpl] +;; [app.common.types.typographies-list :as ctyl] + [clojure.test :as t])) + +(t/use-fixtures :each thi/test-fixture) + +(t/deftest test-reduce-shapes + (let [file (-> (thf/sample-file :file) + (ths/add-sample-shape :shape1)) + + on-not-component (fn [shape context acc] + (println "shape" (:id shape) (:name shape)) + (println "context" context) + acc) + + page (thf/current-page file) + + acc (ctn/reduce-shapes page :dummy + :shape-id (thi/id :shape1) + :on-not-component on-not-component)] + (t/is (= acc :dummy)))) + \ No newline at end of file diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index fd898824d..f4882e1a1 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -529,17 +529,46 @@ objs (assoc objs id new-shape)] (merge objs children))) + _ (js/console.log "old objects" (clj->js objects)) + id-map (as-> objects $ + (keys $) + (remove #(or (uuid/zero? %) + (ids-to-remove %) + (main-instances-ids %))) + (into {} (map #(vector % (uuid/next)) $))) + + _ (js/console.log "id-map" (clj->js id-map)) + _ (js/console.log "main-instances-ids" (str main-instances-ids)) + _ (js/console.log "ids-to-remove" (str ids-to-remove)) + remap-id (fn [id] (get id-map id id)) + + remap-shape + (fn [shape] + (cond-> shape + :always + (-> (update :id remap-id) + (update :parent-id remap-id) + (update :frame-id remap-id) + (update :shapes #(mapv remap-id %))) + + (some? (:shape-ref shape)) + (update :shape-ref remap-id))) + objects (reduce (fn [objs [id shape]] - (cond (contains? main-instances-ids id) - (add-component-copy objs id shape) - (contains? ids-to-remove id) - objs - :else - (assoc objs id shape))) + (let [new-id (remap-id id)] + (js/console.log " === reduce" (str id) (str new-id)) + (js/console.log " -> objs " (clj->js objs)) + (cond (contains? main-instances-ids id) + (add-component-copy objs id shape) + (contains? ids-to-remove id) + objs + :else + (assoc objs new-id (remap-shape shape))))) {} objects) + _ (js/console.log "new objects" (clj->js objects)) page (-> page (assoc :name name)