From ab421ac3f949a52fcc1f567ab87b752bcf220e79 Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Mon, 16 Jan 2023 11:43:42 +0100 Subject: [PATCH 01/40] :bug: Fix undo corner case in multiplayer --- common/src/app/common/pages/changes.cljc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/app/common/pages/changes.cljc b/common/src/app/common/pages/changes.cljc index b7a81a136..334edefb1 100644 --- a/common/src/app/common/pages/changes.cljc +++ b/common/src/app/common/pages/changes.cljc @@ -265,7 +265,8 @@ (move-objects [objects] (let [valid? (every? (partial is-valid-move? objects) shapes) parent (get objects parent-id) - index (if (nil? after-shape) index (inc (d/index-of (:shapes parent) after-shape))) + after-shape-index (d/index-of (:shapes parent) after-shape) + index (if (nil? after-shape-index) index (inc after-shape-index)) frame-id (if (= :frame (:type parent)) (:id parent) (:frame-id parent))] From a3a2ab1ecded9f77ace2ef462790224c1fe8d947 Mon Sep 17 00:00:00 2001 From: Aitor Date: Mon, 16 Jan 2023 13:47:30 +0100 Subject: [PATCH 02/40] :bug: Fix mouse wheel on viewer inspector --- CHANGES.md | 1 + frontend/src/app/main/ui/viewer/inspect.cljs | 25 ++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 50f6ceb1d..9a93fecde 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -44,6 +44,7 @@ - Fix max height in library dialog [Github #2335](https://github.com/penpot/penpot/issues/2335) - Fix undo ungroup (shift+g) scrambles positions [Taiga #4674](https://tree.taiga.io/project/penpot/issue/4674) - Fix justified text is stretched [Github #2539](https://github.com/penpot/penpot/issues/2539) +- Fix mousewheel on viewer inspector [Taiga #4221](https://tree.taiga.io/project/penpot/issue/4221) ## 1.16.2-beta diff --git a/frontend/src/app/main/ui/viewer/inspect.cljs b/frontend/src/app/main/ui/viewer/inspect.cljs index 2f2353acd..8f78cc5bc 100644 --- a/frontend/src/app/main/ui/viewer/inspect.cljs +++ b/frontend/src/app/main/ui/viewer/inspect.cljs @@ -36,7 +36,8 @@ (mf/defc viewport [{:keys [local file page frame index viewer-pagination size]}] - (let [on-mouse-wheel + (let [inspect-svg-container-ref (mf/use-ref nil) + on-mouse-wheel (fn [event] (when (kbd/mod? event) (dom/prevent-default event) @@ -45,14 +46,30 @@ (.-deltaX ^js event))] (if (pos? delta) (st/emit! dv/decrease-zoom) - (st/emit! dv/increase-zoom))))) + (st/emit! dv/increase-zoom)))) + (when-not (kbd/mod? event) + (let [event (.getBrowserEvent ^js event) + shift? (kbd/shift? event) + inspect-svg-container (mf/ref-val inspect-svg-container-ref) + delta (+ (.-deltaY ^js event) + (.-deltaX ^js event)) + scroll-pos (if shift? + (dom/get-h-scroll-pos inspect-svg-container) + (dom/get-scroll-pos inspect-svg-container)) + new-scroll-pos (+ scroll-pos delta)] + (do + (dom/prevent-default event) + (dom/stop-propagation event) + (if shift? + (dom/set-h-scroll-pos! inspect-svg-container new-scroll-pos) + (dom/set-scroll-pos! inspect-svg-container new-scroll-pos)))))) on-mount (fn [] ;; bind with passive=false to allow the event to be cancelled ;; https://stackoverflow.com/a/57582286/3219895 (let [key1 (events/listen goog/global EventType.WHEEL - on-mouse-wheel #js {"passive" false})] + on-mouse-wheel #js {"passive" false "capture" true})] (fn [] (events/unlistenByKey key1))))] @@ -69,7 +86,7 @@ :page page}] [:div.inspect-svg-wrapper {:on-click (handle-select-frame frame)} [:& viewer-pagination {:index index :num-frames (count (:frames page)) :left-bar true :right-bar true}] - [:div.inspect-svg-container + [:div.inspect-svg-container {:ref inspect-svg-container-ref} [:& render-frame-svg {:frame frame :page page :local local :size size}]]] [:& right-sidebar {:frame frame From ff6f0b27445b953cb6604ae5177832f16dd12da7 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 16 Jan 2023 17:33:28 +0100 Subject: [PATCH 03/40] :bug: Fix debugging util --- frontend/src/app/main/data/workspace/thumbnails.cljs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/app/main/data/workspace/thumbnails.cljs b/frontend/src/app/main/data/workspace/thumbnails.cljs index 63e288f3c..bcbf8c0bc 100644 --- a/frontend/src/app/main/data/workspace/thumbnails.cljs +++ b/frontend/src/app/main/data/workspace/thumbnails.cljs @@ -85,8 +85,7 @@ (rx/merge ;; Update the local copy of the thumbnails so we don't need to request it again (rx/of #(update % :workspace-thumbnails assoc object-id data)) - (->> (rx/timer 5000) - (rx/flat-map #(rp/cmd! :upsert-file-object-thumbnail params)) + (->> (rx/flat-map #(rp/cmd! :upsert-file-object-thumbnail params)) (rx/catch #(rx/empty)) (rx/ignore)))) From 0ae42be8519b458beefff8c98246a5b94f52622a Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 16 Jan 2023 17:42:17 +0100 Subject: [PATCH 04/40] :bug: Fix pipeline for thumbnails --- frontend/src/app/main/data/workspace/thumbnails.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/data/workspace/thumbnails.cljs b/frontend/src/app/main/data/workspace/thumbnails.cljs index bcbf8c0bc..6149fd4d4 100644 --- a/frontend/src/app/main/data/workspace/thumbnails.cljs +++ b/frontend/src/app/main/data/workspace/thumbnails.cljs @@ -85,7 +85,7 @@ (rx/merge ;; Update the local copy of the thumbnails so we don't need to request it again (rx/of #(update % :workspace-thumbnails assoc object-id data)) - (->> (rx/flat-map #(rp/cmd! :upsert-file-object-thumbnail params)) + (->> (rp/cmd! :upsert-file-object-thumbnail params) (rx/catch #(rx/empty)) (rx/ignore)))) From 6fb97e54a980996adf1cfb671f1ee3eb48e57c39 Mon Sep 17 00:00:00 2001 From: Eva Date: Mon, 16 Jan 2023 14:19:23 +0100 Subject: [PATCH 05/40] :bug: Fix context menu when two elements where selected --- .../app/main/ui/workspace/context_menu.cljs | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index d80eba18a..ac119cefe 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -372,27 +372,25 @@ has-frame? (->> shapes (d/seek cph/frame-shape?)) is-frame? (and single? has-frame?) is-flex-container? (and is-frame? (= :flex (:layout (first shapes)))) - has-group? (->> shapes (d/seek cph/group-shape?)) - is-group? (and single? has-group?) ids (->> shapes (map :id)) add-flex #(st/emit! (if is-frame? (dwsl/create-layout-from-id ids :flex) (dwsl/create-layout-from-selection :flex))) remove-flex #(st/emit! (dwsl/remove-layout ids))] - (cond - (or single? (and is-frame? (not is-flex-container?)) is-group?) - [:* - [:& menu-separator] - [:& menu-entry {:title (tr "workspace.shape.menu.add-flex") - :shortcut (sc/get-tooltip :toggle-layout-flex) - :on-click add-flex}]] - is-flex-container? - [:* - [:& menu-separator] - [:& menu-entry {:title (tr "workspace.shape.menu.remove-flex") - :shortcut (sc/get-tooltip :toggle-layout-flex) - :on-click remove-flex}]]))) + [:* + (when (not is-flex-container?) + [:div + [:& menu-separator] + [:& menu-entry {:title (tr "workspace.shape.menu.add-flex") + :shortcut (sc/get-tooltip :toggle-layout-flex) + :on-click add-flex}]]) + (when is-flex-container? + [:div + [:& menu-separator] + [:& menu-entry {:title (tr "workspace.shape.menu.remove-flex") + :shortcut (sc/get-tooltip :toggle-layout-flex) + :on-click remove-flex}]])])) (mf/defc context-menu-component [{:keys [shapes]}] From 8892cebb6fe4dcaa0ea6acbaa04275d0d73e6a97 Mon Sep 17 00:00:00 2001 From: Eva Date: Mon, 16 Jan 2023 14:19:54 +0100 Subject: [PATCH 06/40] :bug: Fix create layout flex around component --- frontend/src/app/main/data/workspace/shape_layout.cljs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index e7a3427f3..9035c8fef 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -12,6 +12,7 @@ [app.common.geom.shapes :as gsh] [app.common.math :as mth] [app.common.pages.helpers :as cph] + [app.common.types.component :as ctc] [app.common.types.modifiers :as ctm] [app.common.types.shape-tree :as ctt] [app.common.types.shape.layout :as ctl] @@ -153,9 +154,11 @@ selected-shapes (map (d/getf objects) selected) single? (= (count selected-shapes) 1) has-group? (->> selected-shapes (d/seek cph/group-shape?)) - is-group? (and single? has-group?)] + is-group? (and single? has-group?) + has_component? (some true? (map ctc/instance-root? selected-shapes)) + is_component? (and single? has_component?)] - (if is-group? + (if (and (not is_component?) is-group?) (let [new-shape-id (uuid/next) parent-id (:parent-id (first selected-shapes)) shapes-ids (:shapes (first selected-shapes)) From fb060cb8065c2d7cf238b96a38d653f2e40097af Mon Sep 17 00:00:00 2001 From: Eva Date: Mon, 16 Jan 2023 14:36:29 +0100 Subject: [PATCH 07/40] :bug: Fix padding values and add tooltip --- frontend/src/app/main/data/workspace/shape_layout.cljs | 6 +++--- frontend/src/app/main/ui/formats.cljs | 2 +- .../app/main/ui/viewer/inspect/attributes/layout_flex.cljs | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 9035c8fef..d16e28850 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -155,10 +155,10 @@ single? (= (count selected-shapes) 1) has-group? (->> selected-shapes (d/seek cph/group-shape?)) is-group? (and single? has-group?) - has_component? (some true? (map ctc/instance-root? selected-shapes)) - is_component? (and single? has_component?)] + has-component? (some true? (map ctc/instance-root? selected-shapes)) + is-component? (and single? has-component?)] - (if (and (not is_component?) is-group?) + (if (and (not is-component?) is-group?) (let [new-shape-id (uuid/next) parent-id (:parent-id (first selected-shapes)) shapes-ids (:shapes (first selected-shapes)) diff --git a/frontend/src/app/main/ui/formats.cljs b/frontend/src/app/main/ui/formats.cljs index 8bbeca1f9..f972bda81 100644 --- a/frontend/src/app/main/ui/formats.cljs +++ b/frontend/src/app/main/ui/formats.cljs @@ -52,7 +52,7 @@ {:p1 p1} (= 4 (count (set values))) - {:p1 p1 :p2 p2 :p3 p3} + {:p1 p1 :p2 p2 :p3 p3 :p4 p4} (and (= p1 p3) (= p2 p4)) {:p1 p1 :p3 p3} diff --git a/frontend/src/app/main/ui/viewer/inspect/attributes/layout_flex.cljs b/frontend/src/app/main/ui/viewer/inspect/attributes/layout_flex.cljs index d7a89682e..1cc404df8 100644 --- a/frontend/src/app/main/ui/viewer/inspect/attributes/layout_flex.cljs +++ b/frontend/src/app/main/ui/viewer/inspect/attributes/layout_flex.cljs @@ -68,6 +68,7 @@ [{:keys [padding type]}] (let [values (fm/format-padding-margin-shorthand (vals padding))] [:div.attributes-value + {:title (str (str/join "px " (vals values)) "px")} (for [[k v] values] [:span.items {:key (str type "-" k "-" v)} v "px"])])) From 523539e40318d6c6aa22c9e25fde0d20fd81ae95 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 16 Jan 2023 14:08:58 +0100 Subject: [PATCH 08/40] :bug: Properly handle storage features on binfile import --- backend/src/app/rpc/commands/binfile.clj | 72 ++++++++++++++++-------- backend/src/app/rpc/commands/files.clj | 9 ++- 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/backend/src/app/rpc/commands/binfile.clj b/backend/src/app/rpc/commands/binfile.clj index bd7eb1b61..98587428c 100644 --- a/backend/src/app/rpc/commands/binfile.clj +++ b/backend/src/app/rpc/commands/binfile.clj @@ -9,6 +9,7 @@ (:require [app.common.data :as d] [app.common.exceptions :as ex] + [app.common.files.features :as ffeat] [app.common.logging :as l] [app.common.pages.migrations :as pmg] [app.common.spec :as us] @@ -28,6 +29,7 @@ [app.tasks.file-gc] [app.util.blob :as blob] [app.util.fressian :as fres] + [app.util.objects-map :as omap] [app.util.pointer-map :as pmap] [app.util.services :as sv] [app.util.time :as dt] @@ -609,12 +611,23 @@ (vswap! *state* update :index update-index files) (vswap! *state* assoc :version version :files files))) +(defn- postprocess-file + [data] + (let [omap-wrap ffeat/*wrap-with-objects-map-fn* + pmap-wrap ffeat/*wrap-with-pointer-map-fn*] + (-> data + (update :pages-index update-vals #(update % :objects omap-wrap)) + (update :pages-index update-vals pmap-wrap) + (update :components update-vals #(update % :objects omap-wrap)) + (update :components pmap-wrap)))) + (defmethod read-section :v1/files [{:keys [conn ::input ::migrate? ::project-id ::timestamp ::overwrite?]}] (doseq [expected-file-id (-> *state* deref :files)] - (let [file (read-obj! input) - media' (read-obj! input) - file-id (:id file)] + (let [file (read-obj! input) + media' (read-obj! input) + file-id (:id file) + features files/default-features] (when (not= file-id expected-file-id) (ex/raise :type :validation @@ -629,33 +642,42 @@ (l/debug :hint "update media references" ::l/async false) (vswap! *state* update :media into (map #(update % :id lookup-index)) media') - (l/debug :hint "processing file" :file-id file-id ::l/async false) + (l/debug :hint "processing file" :file-id file-id ::features features ::l/async false) - (let [file-id' (lookup-index file-id) - data (-> (:data file) - (assoc :id file-id') - (cond-> migrate? (pmg/migrate-data)) - (update :pages-index relink-shapes) - (update :components relink-shapes) - (update :media relink-media)) + (binding [ffeat/*current* features + ffeat/*wrap-with-objects-map-fn* (if (features "storage/objects-map") omap/wrap identity) + ffeat/*wrap-with-pointer-map-fn* (if (features "storage/pointer-map") pmap/wrap identity) + pmap/*tracked* (atom {})] - params {:id file-id' - :project-id project-id - :name (:name file) - :revn (:revn file) - :is-shared (:is-shared file) - :data (blob/encode data) - :created-at timestamp - :modified-at timestamp}] + (let [file-id' (lookup-index file-id) + data (-> (:data file) + (assoc :id file-id') + (cond-> migrate? (pmg/migrate-data)) + (update :pages-index relink-shapes) + (update :components relink-shapes) + (update :media relink-media) + (postprocess-file)) - (l/debug :hint "create file" :id file-id' ::l/async false) + params {:id file-id' + :project-id project-id + :features (db/create-array conn "text" features) + :name (:name file) + :revn (:revn file) + :is-shared (:is-shared file) + :data (blob/encode data) + :created-at timestamp + :modified-at timestamp}] - (if overwrite? - (create-or-update-file conn params) - (db/insert! conn :file params)) + (l/debug :hint "create file" :id file-id' ::l/async false) - (when overwrite? - (db/delete! conn :file-thumbnail {:file-id file-id'})))))) + (if overwrite? + (create-or-update-file conn params) + (db/insert! conn :file params)) + + (files/persist-pointers! conn file-id') + + (when overwrite? + (db/delete! conn :file-thumbnail {:file-id file-id'}))))))) (defmethod read-section :v1/rels [{:keys [conn ::input ::timestamp]}] diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index 5d6895c72..eae11e360 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -15,6 +15,7 @@ [app.common.spec :as us] [app.common.types.file :as ctf] [app.common.types.shape-tree :as ctt] + [app.config :as cf] [app.db :as db] [app.db.sql :as sql] [app.loggers.audit :as-alias audit] @@ -43,7 +44,13 @@ "storage/pointer-map" "components/v2"}) -(def default-features #{}) +(def default-features + (cond-> #{} + (contains? cf/flags :fdata-storage-pointer-map) + (conj "storage/pointer-map") + + (contains? cf/flags :fdata-storage-objects-map) + (conj "storage/objects-map"))) ;; --- SPECS From 03b3b441b58e780ec2bbf07f2b23254dfe0cdc2a Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 17 Jan 2023 11:47:49 +0100 Subject: [PATCH 09/40] :bug: Fix create mask inside layout --- frontend/src/app/main/data/workspace/groups.cljs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/data/workspace/groups.cljs b/frontend/src/app/main/data/workspace/groups.cljs index 77cf227a7..e5cad6899 100644 --- a/frontend/src/app/main/data/workspace/groups.cljs +++ b/frontend/src/app/main/data/workspace/groups.cljs @@ -237,10 +237,14 @@ :points (:points first-shape) :transform (:transform first-shape) :transform-inverse (:transform-inverse first-shape)))) - (pcb/resize-parents [(:id group)]))] + (pcb/resize-parents [(:id group)])) + undo-id (js/Symbol)] - (rx/of (dch/commit-changes changes) - (dws/select-shapes (d/ordered-set (:id group)))))))))) + (rx/of (dwu/start-undo-transaction undo-id) + (dch/commit-changes changes) + (dws/select-shapes (d/ordered-set (:id group))) + (ptk/data-event :layout/update [(:id group)]) + (dwu/commit-undo-transaction undo-id)))))))) (def unmask-group (ptk/reify ::unmask-group From b2d8f807f95c591b4667e98c2eec497ab5935ff6 Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 17 Jan 2023 11:48:18 +0100 Subject: [PATCH 10/40] :bug: Fix alignment inside dropdown --- .../main/partials/sidebar-element-options.scss | 17 +++++++++++++---- .../app/main/ui/components/editable_select.cljs | 4 ++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/frontend/resources/styles/main/partials/sidebar-element-options.scss b/frontend/resources/styles/main/partials/sidebar-element-options.scss index 32228a0a4..0b8815707 100644 --- a/frontend/resources/styles/main/partials/sidebar-element-options.scss +++ b/frontend/resources/styles/main/partials/sidebar-element-options.scss @@ -348,11 +348,23 @@ cursor: pointer; font-size: $fs14; display: flex; + justify-content: start; padding: $size-2; span { color: $color-gray-20; - margin-left: auto; + display: flex; + justify-content: start; + align-items: center; + &:not(:first-child) { + margin-left: 10px; + } + } + + .check-icon { + min-width: 25px; + color: $color-gray-20; + justify-content: center; } &.dropdown-separator:not(:last-child) { @@ -375,11 +387,8 @@ & li.checked-element { padding-left: 0; - display: flex; - justify-content: space-around; & span { - margin: 0; color: $color-black; } diff --git a/frontend/src/app/main/ui/components/editable_select.cljs b/frontend/src/app/main/ui/components/editable_select.cljs index 4c1b0d6ed..32c43aff2 100644 --- a/frontend/src/app/main/ui/components/editable_select.cljs +++ b/frontend/src/app/main/ui/components/editable_select.cljs @@ -172,5 +172,5 @@ {:key (str (:id @state) "-" index) :class (when (= (str value) (-> @state :current-value)) "is-selected") :on-click (select-item value)} - [:span.checked-element-value label] - [:span.check-icon i/tick]])))]]])) + [:span.check-icon i/tick] + [:span.checked-element-value label]])))]]])) From f6ff80a3d4efcb53b2ab78eae430f44f0eadd5b3 Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 17 Jan 2023 20:31:34 +0100 Subject: [PATCH 11/40] :bug: Fix Apply library colors to gradient points --- .../app/main/ui/workspace/colorpicker.cljs | 44 +++++++++++++++++-- .../ui/workspace/colorpicker/libraries.cljs | 4 +- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/colorpicker.cljs b/frontend/src/app/main/ui/workspace/colorpicker.cljs index 6fd51c630..3f6f3a72b 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker.cljs @@ -88,9 +88,44 @@ on-select-library-color (mf/use-fn - (fn [color] - (st/emit! (dc/update-colorpicker color)) - (on-change color))) + (fn [state color] + (let [type-origin (:type state) + editig-stop-origin (:editing-stop state) + is-gradient? (some? (:gradient color)) + change-to (fn [new-color] + (st/emit! (dc/update-colorpicker new-color)) + (on-change new-color)) + clean-stop (fn [stops index color] + (-> (nth stops index) + (merge color) + (assoc :offset index) + (dissoc :r) + (dissoc :g) + (dissoc :b) + (dissoc :alpha) + (dissoc :s) + (dissoc :h) + (dissoc :v) + (dissoc :hex))) + set-new-gradient (fn [state color index] + (let [old-stops (:stops state) + old-gradient (:gradient state) + new-gradient (-> old-gradient + (cond-> (= index 0) (assoc :stops [(clean-stop old-stops 0 color) (nth old-stops 1)])) + (cond-> (= index 1) (assoc :stops [(nth old-stops 0) (clean-stop old-stops 1 color)])) + (dissoc :shape-id))] + (change-to {:gradient new-gradient})))] + ;; If we have any kind of gradient and: + ;; Click on a solid color -> This color is applied to the selected offset + ;; Click on a color with transparency -> The same to solid color will happend + ;; Click on any kind of gradient -> The color changes completly to new gradient + + ;; If we have a non gradient color the new color is applied without any change + (if (or (= :radial-gradient type-origin) (= :linear-gradient type-origin)) + (if is-gradient? + (change-to color) + (set-new-gradient state color editig-stop-origin)) + (change-to color))))) on-add-library-color (mf/use-fn @@ -230,7 +265,8 @@ :on-change handle-change-color}] [:& libraries - {:current-color current-color + {:state state + :current-color current-color :disable-gradient disable-gradient :disable-opacity disable-opacity :on-select-color on-select-library-color diff --git a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs index 7a10381ca..447c6b1b3 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs @@ -18,7 +18,7 @@ [rumext.v2 :as mf])) (mf/defc libraries - [{:keys [on-select-color on-add-library-color disable-gradient disable-opacity]}] + [{:keys [state on-select-color on-add-library-color disable-gradient disable-opacity]}] (let [selected (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent) current-colors (mf/use-state []) @@ -88,4 +88,4 @@ [:& color-bullet {:key (dm/str "color-" idx) :color color - :on-click on-select-color}])]])) + :on-click (partial on-select-color state)}])]])) From d14f4c5c4a9ab33f189c649ec9bf6c307f572237 Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 17 Jan 2023 20:44:46 +0100 Subject: [PATCH 12/40] :bug: Fix open color palette from colorpicker --- .../app/main/ui/workspace/colorpicker/libraries.cljs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs index 447c6b1b3..f5612f3fc 100644 --- a/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/colorpicker/libraries.cljs @@ -7,14 +7,18 @@ (ns app.main.ui.workspace.colorpicker.libraries (:require [app.common.data.macros :as dm] + [app.main.data.events :as ev] + [app.main.data.workspace :as dw] [app.main.data.workspace.colors :as mdc] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.color-bullet :refer [color-bullet]] [app.main.ui.hooks :as h] + [app.main.ui.hooks.resize :as r] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] + [app.util.timers :as ts] [rumext.v2 :as mf])) (mf/defc libraries @@ -81,7 +85,12 @@ i/plus]) [:div.color-bullet.button {:style {:background-color "var(--color-white)"} - :on-click #(st/emit! (mdc/show-palette @selected))} + :on-click(fn [] + (r/set-resize-type! :bottom) + (dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down") + (ts/schedule 300 #(st/emit! (dw/remove-layout-flag :textpalette) + (-> (dw/toggle-layout-flag :colorpalette) + (vary-meta assoc ::ev/origin "workspace-colorpicker")))))} i/palette] (for [[idx color] (map-indexed vector @current-colors)] From 24f45fafbf09abbd75a2aa301db5c54bce76c754 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 17 Jan 2023 12:21:29 +0100 Subject: [PATCH 13/40] :bug: Fix problem with disappearing frame titles --- frontend/src/app/main/ui/workspace/viewport/widgets.cljs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index e57d68256..087dfd205 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -22,6 +22,7 @@ [app.main.ui.workspace.viewport.path-actions :refer [path-actions]] [app.main.ui.workspace.viewport.utils :as vwu] [app.util.dom :as dom] + [app.util.timers :as ts] [debug :refer [debug?]] [rumext.v2 :as mf])) @@ -86,7 +87,8 @@ (mf/defc frame-title - {::mf/wrap [mf/memo]} + {::mf/wrap [mf/memo + #(mf/deferred % ts/raf)]} [{:keys [frame selected? zoom show-artboard-names? on-frame-enter on-frame-leave on-frame-select]}] (let [workspace-read-only? (mf/use-ctx ctx/workspace-read-only?) on-mouse-down From 0d96b5b7989eea0a6052bbe27da16eff0d99983f Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 17 Jan 2023 16:30:51 +0100 Subject: [PATCH 14/40] :bug: Fix problems with mask elements modifiers when moving child --- .../shapes/frame/dynamic_modifiers.cljs | 66 +++++++++++++------ 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs index 84a023e7b..a3c2081a0 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs @@ -11,6 +11,7 @@ [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] + [app.common.pages.helpers :as cph] [app.common.types.modifiers :as ctm] [app.main.store :as st] [app.main.ui.hooks :as hooks] @@ -30,14 +31,14 @@ (defn get-nodes "Retrieve the DOM nodes to apply the matrix transformation" - [base-node {:keys [id type masked-group?] :as shape}] + [base-node {:keys [id parent-id] :as shape}] (when (some? base-node) - (let [shape-node (get-shape-node base-node id) - - frame? (= :frame type) - group? (= :group type) - text? (= :text type) - mask? (and group? masked-group?)] + (let [shape-node (get-shape-node base-node id) + parent-node (get-shape-node base-node parent-id) + frame? (cph/frame-shape? shape) + group? (cph/group-shape? shape) + text? (cph/text-shape? shape) + masking-child? (:masking-child? (meta shape))] (cond frame? [shape-node @@ -48,9 +49,10 @@ ;; For groups we don't want to transform the whole group but only ;; its filters/masks - mask? - [(dom/query shape-node ".mask-clip-path") - (dom/query shape-node ".mask-shape")] + masking-child? + [shape-node + (dom/query parent-node ".mask-clip-path") + (dom/query parent-node ".mask-shape")] group? (let [shape-defs (dom/query shape-node "defs")] @@ -74,10 +76,12 @@ (-> (dom/get-attribute node "data-old-width") d/parse-double) (-> (dom/get-attribute node "data-old-height") d/parse-double)) (gsh/transform-selrect modifiers))] - (dom/set-attribute! node "x" x) - (dom/set-attribute! node "y" y) - (dom/set-attribute! node "width" width) - (dom/set-attribute! node "height" height))) + + (when (and (some? x) (some? y) (some? width) (some? height)) + (dom/set-attribute! node "x" x) + (dom/set-attribute! node "y" y) + (dom/set-attribute! node "width" width) + (dom/set-attribute! node "height" height)))) (defn start-transform! [base-node shapes] @@ -169,6 +173,11 @@ (or (= (dom/get-tag-name node) "mask") (= (dom/get-tag-name node) "filter")) (do + (dom/set-attribute! node "x" (dom/get-attribute node "data-old-x")) + (dom/set-attribute! node "y" (dom/get-attribute node "data-old-y")) + (dom/set-attribute! node "width" (dom/get-attribute node "data-old-width")) + (dom/set-attribute! node "height" (dom/get-attribute node "data-old-height")) + (dom/remove-attribute! node "data-old-x") (dom/remove-attribute! node "data-old-y") (dom/remove-attribute! node "data-old-width") @@ -190,6 +199,18 @@ (-> modifiers (ctm/resize scalev (-> shape' :points first) (:transform shape') (:transform-inverse shape'))))) +(defn add-masking-child? + "Adds to the object the information about if the current shape is a masking child. We use the metadata + to not adding new parameters to the object." + [objects] + (fn [{:keys [id parent-id] :as shape}] + (let [parent (get objects parent-id) + masking-child? (and (cph/mask-shape? parent) (= id (first (:shapes parent))))] + + (cond-> shape + masking-child? + (with-meta {:masking-child? true}))))) + (defn use-dynamic-modifiers [objects node modifiers] @@ -198,11 +219,15 @@ (mf/deps modifiers) (fn [] (when (some? modifiers) - (d/mapm (fn [id {modifiers :modifiers}] + (d/mapm (fn [id {current-modifiers :modifiers}] (let [shape (get objects id) - adapt-text? (and (= :text (:type shape)) (not (ctm/only-move? modifiers))) - modifiers (cond-> modifiers adapt-text? (adapt-text-modifiers shape))] - (ctm/modifiers->transform modifiers))) + adapt-text? (and (= :text (:type shape)) (not (ctm/only-move? current-modifiers))) + + current-modifiers + (cond-> current-modifiers + adapt-text? + (adapt-text-modifiers shape))] + (ctm/modifiers->transform current-modifiers))) modifiers)))) add-children (mf/use-memo (mf/deps modifiers) #(ctm/added-children-frames modifiers)) @@ -215,7 +240,7 @@ (fn [] (->> (keys transforms) (filter #(some? (get transforms %))) - (mapv (d/getf objects))))) + (mapv (comp (add-masking-child? objects) (d/getf objects)))))) prev-shapes (mf/use-var nil) prev-modifiers (mf/use-var nil) @@ -252,7 +277,6 @@ (mf/use-layout-effect (mf/deps transforms) (fn [] - (let [curr-shapes-set (into #{} (map :id) shapes) prev-shapes-set (into #{} (map :id) @prev-shapes) @@ -266,7 +290,7 @@ (update-transform! node shapes transforms modifiers)) (when (d/not-empty? removed-shapes) - (remove-transform! node @prev-shapes))) + (remove-transform! node removed-shapes))) (reset! prev-modifiers modifiers) (reset! prev-transforms transforms) From c18d3c66a8f2a358cc0ced042a5c2cb067559ce8 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 17 Jan 2023 23:20:54 +0100 Subject: [PATCH 15/40] :sparkles: Changes to snap to pixel --- common/src/app/common/geom/point.cljc | 8 +++---- .../src/app/common/geom/shapes/modifiers.cljc | 21 ++++++++++++------- .../common/geom/shapes/pixel_precision.cljc | 20 +++++++++--------- common/src/app/common/math.cljc | 17 ++++++++------- common/test/common_tests/geom_point_test.cljc | 2 +- frontend/src/app/main/constants.cljs | 2 ++ .../app/main/data/workspace/drawing/box.cljs | 8 ++++--- .../src/app/main/data/workspace/media.cljs | 5 +++-- .../app/main/data/workspace/modifiers.cljs | 15 +++++++++---- .../app/main/data/workspace/path/streams.cljs | 4 ++-- .../app/main/data/workspace/svg_upload.cljs | 17 ++++++++------- .../app/main/data/workspace/transforms.cljs | 13 +++++------- 12 files changed, 75 insertions(+), 57 deletions(-) diff --git a/common/src/app/common/geom/point.cljc b/common/src/app/common/geom/point.cljc index 5dd41501e..6c640173a 100644 --- a/common/src/app/common/geom/point.cljc +++ b/common/src/app/common/geom/point.cljc @@ -274,12 +274,12 @@ (Point. (mth/precision (dm/get-prop pt :x) decimals) (mth/precision (dm/get-prop pt :y) decimals)))) -(defn half-round +(defn round-step "Round the coordinates to the closest half-point" - [pt] + [pt step] (assert (point? pt) "expected point instance") - (Point. (mth/half-round (dm/get-prop pt :x)) - (mth/half-round (dm/get-prop pt :y)))) + (Point. (mth/round (dm/get-prop pt :x) step) + (mth/round (dm/get-prop pt :y) step))) (defn transform "Transform a point applying a matrix transformation." diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index 4b11007a3..ff6e05f52 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -382,15 +382,24 @@ result)) (defn set-objects-modifiers - ([modif-tree objects ignore-constraints snap-pixel?] - (set-objects-modifiers nil modif-tree objects ignore-constraints snap-pixel?)) + ([modif-tree objects] + (set-objects-modifiers modif-tree objects nil)) - ([old-modif-tree modif-tree objects ignore-constraints snap-pixel?] + ([modif-tree objects params] + (set-objects-modifiers nil modif-tree objects params)) + + ([old-modif-tree modif-tree objects + {:keys [ignore-constraints snap-pixel? snap-precision] + :or {ignore-constraints false snap-pixel? false snap-precision 1}}] (let [objects (-> objects (cond-> (some? old-modif-tree) (apply-structure-modifiers old-modif-tree)) (apply-structure-modifiers modif-tree)) + modif-tree + (cond-> modif-tree + snap-pixel? (gpp/adjust-pixel-precision objects snap-precision)) + bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points])) bounds (cond-> bounds (some? old-modif-tree) @@ -417,11 +426,7 @@ modif-tree (if old-modif-tree (merge-modif-tree old-modif-tree modif-tree) - modif-tree) - - modif-tree - (cond-> modif-tree - snap-pixel? (gpp/adjust-pixel-precision objects))] + modif-tree)] ;;#?(:cljs ;; (.log js/console ">result" (modif->js modif-tree objects))) diff --git a/common/src/app/common/geom/shapes/pixel_precision.cljc b/common/src/app/common/geom/shapes/pixel_precision.cljc index c1236046f..f75b650d9 100644 --- a/common/src/app/common/geom/shapes/pixel_precision.cljc +++ b/common/src/app/common/geom/shapes/pixel_precision.cljc @@ -18,7 +18,7 @@ [app.common.types.modifiers :as ctm])) (defn size-pixel-precision - [modifiers shape points] + [modifiers shape points precision] (let [origin (gpo/origin points) curr-width (gpo/width-points points) curr-height (gpo/height-points points) @@ -29,8 +29,8 @@ vertical-line? (and path? (<= curr-width 0.01)) horizontal-line? (and path? (<= curr-height 0.01)) - target-width (if vertical-line? curr-width (max 1 (mth/round curr-width))) - target-height (if horizontal-line? curr-height (max 1 (mth/round curr-height))) + target-width (if vertical-line? curr-width (max 1 (mth/round curr-width precision))) + target-height (if horizontal-line? curr-height (max 1 (mth/round curr-height precision))) ratio-width (/ target-width curr-width) ratio-height (/ target-height curr-height) @@ -39,23 +39,23 @@ (ctm/resize scalev origin transform transform-inverse {:precise? true})))) (defn position-pixel-precision - [modifiers _ points] + [modifiers _ points precision] (let [bounds (gpr/bounds->rect points) corner (gpt/point bounds) - target-corner (gpt/round corner) + target-corner (gpt/round-step corner precision) deltav (gpt/to-vec corner target-corner)] (ctm/move modifiers deltav))) (defn set-pixel-precision "Adjust modifiers so they adjust to the pixel grid" - [modifiers shape] + [modifiers shape precision] (let [points (-> shape :points (gco/transform-points (ctm/modifiers->transform modifiers))) has-resize? (not (ctm/only-move? modifiers)) [modifiers points] (let [modifiers (cond-> modifiers - has-resize? (size-pixel-precision shape points)) + has-resize? (size-pixel-precision shape points precision)) points (if has-resize? @@ -63,16 +63,16 @@ (gco/transform-points (ctm/modifiers->transform modifiers)) ) points)] [modifiers points])] - (position-pixel-precision modifiers shape points))) + (position-pixel-precision modifiers shape points precision))) (defn adjust-pixel-precision - [modif-tree objects] + [modif-tree objects precision] (let [update-modifiers (fn [modif-tree shape] (let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])] (cond-> modif-tree (ctm/has-geometry? modifiers) - (update-in [(:id shape) :modifiers] set-pixel-precision shape))))] + (update-in [(:id shape) :modifiers] set-pixel-precision shape precision))))] (->> (keys modif-tree) (map (d/getf objects)) diff --git a/common/src/app/common/math.cljc b/common/src/app/common/math.cljc index 5ed4f01f9..9def09aff 100644 --- a/common/src/app/common/math.cljc +++ b/common/src/app/common/math.cljc @@ -104,15 +104,16 @@ (defn round "Returns the value of a number rounded to - the nearest integer." - [v] - #?(:cljs (js/Math.round v) - :clj (Math/round (float v)))) + the nearest integer. + If given step rounds to the next closest step, for example: + (round 13.4 0.5) => 13.5 + (round 13.4 0.3) => 13.3" + ([v step] + (* (round (/ v step)) step)) -(defn half-round - "Returns a value rounded to the next point or half point" - [v] - (/ (round (* v 2)) 2)) + ([v] + #?(:cljs (js/Math.round v) + :clj (Math/round (float v))))) (defn ceil "Returns the smallest integer greater than diff --git a/common/test/common_tests/geom_point_test.cljc b/common/test/common_tests/geom_point_test.cljc index c98052315..9be0bc153 100644 --- a/common/test/common_tests/geom_point_test.cljc +++ b/common/test/common_tests/geom_point_test.cljc @@ -203,7 +203,7 @@ (t/deftest halft-round-point (let [p1 (gpt/point 1.34567 3.34567) - rs (gpt/half-round p1)] + rs (gpt/round-step p1 0.5)] (t/is (gpt/point? rs)) (t/is (mth/close? 1.5 (:x rs))) (t/is (mth/close? 3.5 (:y rs))))) diff --git a/frontend/src/app/main/constants.cljs b/frontend/src/app/main/constants.cljs index 968a56a13..acae0096e 100644 --- a/frontend/src/app/main/constants.cljs +++ b/frontend/src/app/main/constants.cljs @@ -190,3 +190,5 @@ {:name "YouTube thumb" :width 1280 :height 720}]) + +(def zoom-half-pixel-precision 8) diff --git a/frontend/src/app/main/data/workspace/drawing/box.cljs b/frontend/src/app/main/data/workspace/drawing/box.cljs index 54e5456fe..140d58bbd 100644 --- a/frontend/src/app/main/data/workspace/drawing/box.cljs +++ b/frontend/src/app/main/data/workspace/drawing/box.cljs @@ -16,6 +16,7 @@ [app.common.types.shape-tree :as ctst] [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] + [app.main.constants :refer [zoom-half-pixel-precision]] [app.main.data.workspace.drawing.common :as common] [app.main.data.workspace.state-helpers :as wsh] [app.main.snap :as snap] @@ -70,14 +71,15 @@ (let [stoper? #(or (ms/mouse-up? %) (= % :interrupt)) stoper (rx/filter stoper? stream) layout (get state :workspace-layout) + zoom (get-in state [:workspace-local :zoom] 1) snap-pixel? (contains? layout :snap-pixel-grid) - initial (cond-> @ms/mouse-position snap-pixel? gpt/round) + snap-precision (if (>= zoom zoom-half-pixel-precision) 0.5 1) + initial (cond-> @ms/mouse-position snap-pixel? (gpt/round-step snap-precision)) page-id (:current-page-id state) objects (wsh/lookup-page-objects state page-id) focus (:workspace-focus-selected state) - zoom (get-in state [:workspace-local :zoom] 1) fid (ctst/top-nested-frame objects initial) layout? (ctl/layout? objects fid) @@ -119,7 +121,7 @@ (rx/map #(conj current %))))) (rx/map (fn [[_ shift? point]] - #(update-drawing % initial (cond-> point snap-pixel? gpt/round) shift?))))) + #(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-precision)) shift?))))) (rx/take-until stoper)) (->> (rx/of (common/handle-finish-drawing)) diff --git a/frontend/src/app/main/data/workspace/media.cljs b/frontend/src/app/main/data/workspace/media.cljs index 8fd501f59..766b29406 100644 --- a/frontend/src/app/main/data/workspace/media.cljs +++ b/frontend/src/app/main/data/workspace/media.cljs @@ -8,6 +8,7 @@ (:require [app.common.exceptions :as ex] [app.common.logging :as log] + [app.common.math :as mth] [app.common.pages.changes-builder :as pcb] [app.common.spec :as us] [app.common.types.container :as ctn] @@ -52,8 +53,8 @@ shape {:name name :width width :height height - :x (- x (/ width 2)) - :y (- y (/ height 2)) + :x (mth/round (- x (/ width 2))) + :y (mth/round (- y (/ height 2))) :metadata {:width width :height height :mtype mtype diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 514fc32a7..a93bb08f7 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -17,6 +17,7 @@ [app.common.spec :as us] [app.common.types.modifiers :as ctm] [app.common.types.shape.layout :as ctl] + [app.main.constants :refer [zoom-half-pixel-precision]] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.comments :as-alias dwcm] [app.main.data.workspace.guides :as-alias dwg] @@ -244,12 +245,15 @@ (wsh/lookup-page-objects state) snap-pixel? - (and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))] + (and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid)) + + zoom (dm/get-in state [:workspace-local :zoom]) + snap-precision (if (>= zoom zoom-half-pixel-precision) 0.5 1)] (as-> objects $ (apply-text-modifiers $ (get state :workspace-text-modifier)) ;;(apply-path-modifiers $ (get-in state [:workspace-local :edit-path])) - (gsh/set-objects-modifiers modif-tree $ ignore-constraints snap-pixel?))))) + (gsh/set-objects-modifiers modif-tree $ {:ignore-constraints ignore-constraints :snap-pixel? snap-pixel? :snap-precision snap-precision}))))) (defn- calculate-update-modifiers [old-modif-tree state ignore-constraints ignore-snap-pixel modif-tree] @@ -259,10 +263,13 @@ snap-pixel? (and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid)) + zoom (dm/get-in state [:workspace-local :zoom]) + + snap-precision (if (>= zoom zoom-half-pixel-precision) 0.5 1) objects (-> objects (apply-text-modifiers (get state :workspace-text-modifier)))] - (gsh/set-objects-modifiers old-modif-tree modif-tree objects ignore-constraints snap-pixel?))) + (gsh/set-objects-modifiers old-modif-tree modif-tree objects {:ignore-constraints ignore-constraints :snap-pixel? snap-pixel? :snap-precision snap-precision}))) (defn update-modifiers ([modif-tree] @@ -312,7 +319,7 @@ modif-tree (-> (build-modif-tree ids objects get-modifier) - (gsh/set-objects-modifiers objects false false))] + (gsh/set-objects-modifiers objects))] (assoc state :workspace-modifiers modif-tree)))))) diff --git a/frontend/src/app/main/data/workspace/path/streams.cljs b/frontend/src/app/main/data/workspace/path/streams.cljs index db1a09464..147fbd511 100644 --- a/frontend/src/app/main/data/workspace/path/streams.cljs +++ b/frontend/src/app/main/data/workspace/path/streams.cljs @@ -8,6 +8,7 @@ (:require [app.common.geom.point :as gpt] [app.common.geom.shapes.path :as upg] + [app.main.constants :refer [zoom-half-pixel-precision]] [app.main.data.workspace.path.state :as state] [app.main.snap :as snap] [app.main.store :as st] @@ -17,7 +18,6 @@ [potok.core :as ptk])) (defonce drag-threshold 5) -(def zoom-half-pixel-precision 8) (defn dragging? [start zoom] (fn [current] @@ -36,7 +36,7 @@ position (>= zoom zoom-half-pixel-precision) - (gpt/half-round position) + (gpt/round-step position 0.5) :else (gpt/round position)))) diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index f299fa8d6..94ded56b6 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -11,6 +11,7 @@ [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] + [app.common.math :as mth] [app.common.pages.changes-builder :as pcb] [app.common.pages.helpers :as cph] [app.common.spec :as us :refer [max-safe-int min-safe-int]] @@ -477,15 +478,17 @@ (rx/reduce (fn [acc [url image]] (assoc acc url image)) {}))) (defn create-svg-shapes - [svg-data {:keys [x y] :as position} objects frame-id parent-id selected center?] + [svg-data {:keys [x y]} objects frame-id parent-id selected center?] (try (let [[vb-x vb-y vb-width vb-height] (svg-dimensions svg-data) - x (if center? - (- x vb-x (/ vb-width 2)) - x) - y (if center? - (- y vb-y (/ vb-height 2)) - y) + x (mth/round + (if center? + (- x vb-x (/ vb-width 2)) + x)) + y (mth/round + (if center? + (- y vb-y (/ vb-height 2)) + y)) unames (ctst/retrieve-used-names objects) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index ce9798f77..5525b7302 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -240,14 +240,12 @@ ptk/UpdateEvent (update [_ state] (let [objects (wsh/lookup-page-objects state) - snap-pixel? (and (contains? (:workspace-layout state) :snap-pixel-grid) - (int? value)) get-modifier (fn [shape] (ctm/change-dimensions-modifiers shape attr value)) modif-tree (-> (dwm/build-modif-tree ids objects get-modifier) - (gsh/set-objects-modifiers objects false snap-pixel?))] + (gsh/set-objects-modifiers objects))] (assoc state :workspace-modifiers modif-tree))) @@ -265,14 +263,13 @@ ptk/UpdateEvent (update [_ state] (let [objects (wsh/lookup-page-objects state) - snap-pixel? (contains? (get state :workspace-layout) :snap-pixel-grid) get-modifier (fn [shape] (ctm/change-orientation-modifiers shape orientation)) modif-tree (-> (dwm/build-modif-tree ids objects get-modifier) - (gsh/set-objects-modifiers objects false snap-pixel?))] + (gsh/set-objects-modifiers objects))] (assoc state :workspace-modifiers modif-tree))) @@ -623,7 +620,7 @@ (->> move-events (rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0)) (rx/map #(dwm/create-modif-tree selected (ctm/move-modifiers %))) - (rx/map (partial dwm/set-modifiers)) + (rx/map #(dwm/set-modifiers % false true)) (rx/take-until stopper)) (rx/of (nudge-selected-shapes direction shift?))) @@ -669,11 +666,12 @@ cpos (gpt/point (:x bbox) (:y bbox)) pos (gpt/point (or (:x position) (:x bbox)) (or (:y position) (:y bbox))) + delta (gpt/subtract pos cpos) modif-tree (dwm/create-modif-tree [id] (ctm/move-modifiers delta))] - (rx/of (dwm/set-modifiers modif-tree) + (rx/of (dwm/set-modifiers modif-tree false true) (dwm/apply-modifiers)))))) (defn- move-shapes-to-frame @@ -688,7 +686,6 @@ shapes (->> ids (cph/clean-loops objects) (keep lookup)) - moving-shapes (cond->> shapes (not layout?) From f93d0e1c4da7ef1f4f6b7ae44b88fa8a3cafab61 Mon Sep 17 00:00:00 2001 From: Eva Date: Wed, 18 Jan 2023 11:57:48 +0100 Subject: [PATCH 16/40] :bug: Fix snap to pixel on path creation and edit --- frontend/src/app/main/data/workspace/path/drawing.cljs | 2 +- frontend/src/app/main/data/workspace/path/edition.cljs | 2 +- frontend/src/app/main/ui/workspace/viewport/path_actions.cljs | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/data/workspace/path/drawing.cljs b/frontend/src/app/main/data/workspace/path/drawing.cljs index fddb6c914..ef0e9403d 100644 --- a/frontend/src/app/main/data/workspace/path/drawing.cljs +++ b/frontend/src/app/main/data/workspace/path/drawing.cljs @@ -293,7 +293,7 @@ (update [_ state] (let [id (st/get-path-id state)] (-> state - (assoc-in [:workspace-local :edit-path id :snap-toggled] true)))) + (assoc-in [:workspace-local :edit-path id :snap-toggled] false)))) ptk/WatchEvent (watch [_ state stream] diff --git a/frontend/src/app/main/data/workspace/path/edition.cljs b/frontend/src/app/main/data/workspace/path/edition.cljs index b8712111b..2340da662 100644 --- a/frontend/src/app/main/data/workspace/path/edition.cljs +++ b/frontend/src/app/main/data/workspace/path/edition.cljs @@ -290,7 +290,7 @@ (or (not edit-path) (= :draw (:edit-mode edit-path))) (assoc-in [:workspace-local :edit-path id] {:edit-mode :move :selected #{} - :snap-toggled true}) + :snap-toggled false}) (and (some? edit-path) (= :move (:edit-mode edit-path))) (assoc-in [:workspace-local :edit-path id :edit-mode] :draw)))) diff --git a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs index b66d01848..d7eaef153 100644 --- a/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/path_actions.cljs @@ -106,9 +106,7 @@ on-toggle-snap (mf/use-callback (fn [_] - (st/emit! (drp/toggle-snap)))) - - ] + (st/emit! (drp/toggle-snap))))] [:div.path-actions [:div.viewport-actions-group From de7a1d34c0d108404abbc600bff162db4ebf504e Mon Sep 17 00:00:00 2001 From: Eva Date: Wed, 18 Jan 2023 12:09:15 +0100 Subject: [PATCH 17/40] :bug: Fix board preset size selector css --- .../styles/main/partials/sidebar-element-options.scss | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/resources/styles/main/partials/sidebar-element-options.scss b/frontend/resources/styles/main/partials/sidebar-element-options.scss index 0b8815707..5da973616 100644 --- a/frontend/resources/styles/main/partials/sidebar-element-options.scss +++ b/frontend/resources/styles/main/partials/sidebar-element-options.scss @@ -348,6 +348,7 @@ cursor: pointer; font-size: $fs14; display: flex; + gap: 0 10px; justify-content: start; padding: $size-2; @@ -356,9 +357,6 @@ display: flex; justify-content: start; align-items: center; - &:not(:first-child) { - margin-left: 10px; - } } .check-icon { From a1a3d09998853d5c442201b561ff05be8369f77e Mon Sep 17 00:00:00 2001 From: Eva Date: Wed, 18 Jan 2023 16:34:58 +0100 Subject: [PATCH 18/40] :bug: Remove numbers in layer creation --- common/src/app/common/types/container.cljc | 2 +- common/src/app/common/types/shape.cljc | 10 +- common/src/app/common/types/shape_tree.cljc | 2 + .../src/app/main/data/workspace/bool.cljs | 5 +- .../src/app/main/data/workspace/groups.cljs | 8 +- .../app/main/data/workspace/libraries.cljs | 5 +- .../app/main/data/workspace/selection.cljs | 6 +- .../src/app/main/data/workspace/shapes.cljs | 4 +- .../app/main/data/workspace/svg_upload.cljs | 5 +- .../test/frontend_tests/helpers/pages.cljs | 2 +- .../state_components_sync_test.cljs | 272 +++++++++--------- .../frontend_tests/state_components_test.cljs | 146 +++++----- 12 files changed, 228 insertions(+), 239 deletions(-) diff --git a/common/src/app/common/types/container.cljc b/common/src/app/common/types/container.cljc index 5660f1ae2..cb7911567 100644 --- a/common/src/app/common/types/container.cljc +++ b/common/src/app/common/types/container.cljc @@ -125,7 +125,7 @@ update-new-shape (fn [new-shape original-shape] - (let [new-name (ctst/generate-unique-name @unames (:name new-shape))] + (let [new-name (:name new-shape)] (when (nil? (:parent-id original-shape)) (vswap! unames conj new-name)) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index 507860fb4..4ff5430ee 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -278,7 +278,7 @@ (def ^:private minimal-shapes [{:type :rect - :name "Rect-1" + :name "Rectangle" :fills [{:fill-color default-color :fill-opacity 1}] :strokes [] @@ -292,13 +292,13 @@ :strokes []} {:type :circle - :name "Circle-1" + :name "Ellipse" :fills [{:fill-color default-color :fill-opacity 1}] :strokes []} {:type :path - :name "Path-1" + :name "Path" :fills [] :strokes [{:stroke-style :solid :stroke-alignment :center @@ -307,7 +307,7 @@ :stroke-opacity 1}]} {:type :frame - :name "Board-1" + :name "Board" :fills [{:fill-color clr/white :fill-opacity 1}] :strokes [] @@ -320,7 +320,7 @@ :ry 0} {:type :text - :name "Text-1" + :name "Text" :content nil} {:type :svg-raw}]) diff --git a/common/src/app/common/types/shape_tree.cljc b/common/src/app/common/types/shape_tree.cljc index d7fd2c8db..470d8b68d 100644 --- a/common/src/app/common/types/shape_tree.cljc +++ b/common/src/app/common/types/shape_tree.cljc @@ -304,6 +304,8 @@ [used basename] (us/assert! ::set-of-strings used) (us/assert! ::us/string basename) + ;; We have add a condition because UX doesn't want numbers on + ;; layer names. (if-not (contains? used basename) basename (let [[prefix initial] (extract-numeric-suffix basename)] diff --git a/frontend/src/app/main/data/workspace/bool.cljs b/frontend/src/app/main/data/workspace/bool.cljs index bfaec41ac..b9a5be4d8 100644 --- a/frontend/src/app/main/data/workspace/bool.cljs +++ b/frontend/src/app/main/data/workspace/bool.cljs @@ -11,7 +11,6 @@ [app.common.pages.changes-builder :as pcb] [app.common.pages.helpers :as cph] [app.common.path.shapes-to-path :as stp] - [app.common.types.shape-tree :as ctt] [app.common.uuid :as uuid] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.selection :as dws] @@ -85,9 +84,7 @@ (watch [it state _] (let [page-id (:current-page-id state) objects (wsh/lookup-page-objects state) - base-name (-> bool-type d/name str/capital (str "-1")) - name (-> (ctt/retrieve-used-names objects) - (ctt/generate-unique-name base-name)) + name (-> bool-type d/name str/capital) ids (selected-shapes-idx state) ordered-indexes (cph/order-by-indexed-shapes objects ids) shapes (->> ordered-indexes diff --git a/frontend/src/app/main/data/workspace/groups.cljs b/frontend/src/app/main/data/workspace/groups.cljs index e5cad6899..cbe0558ba 100644 --- a/frontend/src/app/main/data/workspace/groups.cljs +++ b/frontend/src/app/main/data/workspace/groups.cljs @@ -12,7 +12,6 @@ [app.common.pages.helpers :as cph] [app.common.types.component :as ctk] [app.common.types.shape :as cts] - [app.common.types.shape-tree :as ctst] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.selection :as dws] [app.main.data.workspace.state-helpers :as wsh] @@ -73,8 +72,7 @@ (= (count shapes) 1) (= (:type (first shapes)) :group)) (:name (first shapes)) - (-> (ctst/retrieve-used-names objects) - (ctst/generate-unique-name base-name))) + base-name) selrect (gsh/selection-rect shapes) group-idx (->> shapes @@ -162,7 +160,7 @@ shapes (shapes-for-grouping objects selected)] (when-not (empty? shapes) (let [[group changes] - (prepare-create-group it objects page-id shapes "Group-1" false)] + (prepare-create-group it objects page-id shapes "Group" false)] (rx/of (dch/commit-changes changes) (dws/select-shapes (d/ordered-set (:id group)))))))))) @@ -221,7 +219,7 @@ (= (:type (first shapes)) :group)) [first-shape (-> (pcb/empty-changes it page-id) (pcb/with-objects objects))] - (prepare-create-group it objects page-id shapes "Group-1" true)) + (prepare-create-group it objects page-id shapes "Mask" true)) changes (-> changes (pcb/update-shapes (:shapes group) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 9c75d03ae..78aaad5c9 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -22,7 +22,6 @@ [app.common.types.file :as ctf] [app.common.types.file.media-object :as ctfm] [app.common.types.pages-list :as ctpl] - [app.common.types.shape-tree :as ctst] [app.common.types.typography :as ctt] [app.common.uuid :as uuid] [app.main.data.dashboard :as dd] @@ -373,9 +372,7 @@ (watch [it state _] (let [libraries (wsh/get-libraries state) component (cph/get-component libraries id) - all-components (-> state :workspace-data :components vals) - unames (into #{} (map :name) all-components) - new-name (ctst/generate-unique-name unames (:name component)) + new-name (:name component) components-v2 (features/active-feature? state :components-v2) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 5a31013a0..500c75652 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -327,8 +327,7 @@ (defn- prepare-duplicate-frame-change [changes objects page unames update-unames! ids-map obj delta] (let [new-id (ids-map (:id obj)) - frame-name (ctt/generate-unique-name @unames (:name obj)) - _ (update-unames! frame-name) + frame-name (:name obj) new-frame (-> obj (assoc :id new-id @@ -361,8 +360,7 @@ (if (some? obj) (let [new-id (ids-map (:id obj)) parent-id (or parent-id frame-id) - name (ctt/generate-unique-name @unames (:name obj)) - _ (update-unames! name) + name (:name obj) new-obj (-> obj (assoc :id new-id diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 4bba01db8..c6de6aa21 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -87,9 +87,7 @@ selected (wsh/lookup-selected state) id (or (:id attrs) (uuid/next)) - name (-> objects - (ctst/retrieve-used-names) - (ctst/generate-unique-name (:name attrs))) + name (:name attrs) shape (make-new-shape (assoc attrs :id id :name name) diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index 94ded56b6..b2a9bef1c 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -362,7 +362,7 @@ (let [{:keys [tag attrs hidden]} element-data attrs (usvg/format-styles attrs) element-data (cond-> element-data (map? element-data) (assoc :attrs attrs)) - name (ctst/generate-unique-name unames (or (:id attrs) (tag->name tag))) + name (or (:id attrs) (tag->name tag)) att-refs (usvg/find-attr-references attrs) references (usvg/find-def-references (:defs svg-data) att-refs) @@ -492,8 +492,7 @@ unames (ctst/retrieve-used-names objects) - svg-name (->> (str/replace (:name svg-data) ".svg" "") - (ctst/generate-unique-name unames)) + svg-name (str/replace (:name svg-data) ".svg" "") svg-data (-> svg-data (assoc :x x diff --git a/frontend/test/frontend_tests/helpers/pages.cljs b/frontend/test/frontend_tests/helpers/pages.cljs index 34e4994d2..6129eea42 100644 --- a/frontend/test/frontend_tests/helpers/pages.cljs +++ b/frontend/test/frontend_tests/helpers/pages.cljs @@ -87,7 +87,7 @@ :obj shape}])))) (defn group-shapes - ([state label ids] (group-shapes state label ids "Group-1")) + ([state label ids] (group-shapes state label ids "Group")) ([state label ids prefix] (let [page (current-page state) shapes (dwg/shapes-for-grouping (:objects page) ids)] diff --git a/frontend/test/frontend_tests/state_components_sync_test.cljs b/frontend/test/frontend_tests/state_components_sync_test.cljs index d6c94ce01..bdf8a9b4a 100644 --- a/frontend/test/frontend_tests/state_components_sync_test.cljs +++ b/frontend/test/frontend_tests/state_components_sync_test.cljs @@ -55,12 +55,12 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1* ---> Rect 1 (color, opacity) ; #{:fill-group} ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; (let [[[group shape1] [c-group c-shape1] component] @@ -68,14 +68,14 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:touched shape1) #{:fill-group})) (t/is (= (:fill-color shape1) clr/test)) (t/is (= (:fill-opacity shape1) 0.5)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:touched c-shape1) nil)) @@ -110,13 +110,13 @@ ; ; [Page] ; Root Frame - ; Rect 1-1* #--> Rect 1-1 + ; Rect 1 * #--> Rect 1 ; #{:shapes-group} ; Circle 1 ; Rect 1 ---> Rect 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; (let [[[group shape1 shape2] [c-group c-shape1] component] @@ -124,7 +124,7 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) #{:shapes-group})) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -133,7 +133,7 @@ (t/is (= (:touched shape2) nil)) (t/is (not= (:shape-ref shape2) nil)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) @@ -305,7 +305,7 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1* ---> Rect 1 (color, opacity) ; #{:fill-group} ; @@ -314,14 +314,14 @@ new-state (thp/id :instance2))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:touched shape1) #{:fill-group})) (t/is (= (:fill-color shape1) clr/test)) (t/is (= (:fill-opacity shape1) 0.5)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:touched c-shape1) nil)) @@ -367,19 +367,19 @@ ; ; [Page] ; Root Frame - ; Group-1* #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group * #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1* ---> Circle 1 (color, opacity) ; #{:fill-group} ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ; @@ -391,9 +391,9 @@ ; TODO: get and check the instance inside component [Group-1] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) #{:fill-group})) @@ -404,9 +404,9 @@ (t/is (= (:fill-color shape2) clr/white)) (t/is (= (:fill-opacity shape2) 1)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -456,19 +456,19 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1* ---> Rect 1 (color, opacity) ; #{:fill-group} ; Circle 1 ---> Circle 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ; @@ -480,9 +480,9 @@ ; TODO: get and check the instance inside component [Group-1] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -493,9 +493,9 @@ (t/is (= (:fill-color shape2) clr/test)) (t/is (= (:fill-opacity shape2) 0.5)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -545,18 +545,18 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) ; Circle 1 ---> Circle 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1* ---> Rect 1 (color, opacity) ; #{:fill-group} ; Circle 1 @@ -569,9 +569,9 @@ ; TODO: get and check the instance inside component [Group-1] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -582,9 +582,9 @@ (t/is (= (:fill-color shape2) clr/test)) (t/is (= (:fill-opacity shape2) 0.5)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -628,7 +628,7 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1 ---> Rect 1 ; ; [Rect 1] @@ -640,14 +640,14 @@ new-state (:id instance1))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:fill-color shape1) clr/white)) (t/is (= (:fill-opacity shape1) 1)) (t/is (= (:touched shape1) nil)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:fill-color c-shape1) clr/white)) @@ -683,11 +683,11 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1 ---> Rect 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; (let [[[group shape1] [c-group c-shape1] component] @@ -695,14 +695,14 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) nil)) (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:touched shape1) nil)) (t/is (not= (:shape-ref shape1) nil)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) @@ -881,7 +881,7 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1 ---> Rect 1 ; (let [[[group shape1] [c-group c-shape1] component] @@ -889,14 +889,14 @@ new-state (:id instance2))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:fill-color shape1) clr/white)) (t/is (= (:fill-opacity shape1) 1)) (t/is (= (:touched shape1) nil)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:fill-color c-shape1) clr/white)) @@ -943,18 +943,18 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ---> Circle 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ; @@ -964,11 +964,11 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -979,9 +979,9 @@ (t/is (= (:fill-color shape2) clr/white)) (t/is (= (:fill-opacity shape2) 1)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -1032,18 +1032,18 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ---> Circle 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 (color, opacity) ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ; @@ -1053,11 +1053,11 @@ new-state (thp/id :instance2))] - ; TODO: get and check the instance inside component [Group-1] + ; TODO: get and check the instance inside component [Group] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -1068,9 +1068,9 @@ (t/is (= (:fill-color shape2) clr/white)) (t/is (= (:fill-opacity shape2) 1)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -1122,18 +1122,18 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ---> Circle 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) ; #{:fill-group} ; Circle 1 @@ -1146,9 +1146,9 @@ ; TODO: get and check the instance inside component [Group-1] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -1159,9 +1159,9 @@ (t/is (= (:fill-color shape2) clr/white)) (t/is (= (:fill-opacity shape2) 1)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -1209,13 +1209,13 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) ; Rect 1-2 ; Rect 1 ---> Rect 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 (color, opacity) ; (let [[[instance1 shape1] [c-instance1 c-shape1] component1] @@ -1228,21 +1228,21 @@ new-state (:id instance2))] - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:fill-color shape1) clr/test)) (t/is (= (:fill-opacity shape1) 0.5)) (t/is (= (:touched shape1) nil)) - (t/is (= (:name instance2) "Rect 1-2")) + (t/is (= (:name instance2) "Rect 1")) (t/is (= (:touched instance2) nil)) (t/is (= (:name shape2) "Rect 1")) (t/is (= (:fill-color shape2) clr/white)) (t/is (= (:fill-opacity shape2) 1)) (t/is (= (:touched shape2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:fill-color c-shape1) clr/test)) @@ -1289,13 +1289,13 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) - ; Rect 1-2 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 (color, opacity) ; (let [[[instance1 shape1] [c-instance1 c-shape1] component1] @@ -1308,21 +1308,21 @@ new-state (:id instance2))] - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:fill-color shape1) clr/test)) (t/is (= (:fill-opacity shape1) 0.5)) (t/is (= (:touched shape1) nil)) - (t/is (= (:name instance2) "Rect 1-2")) + (t/is (= (:name instance2) "Rect 1")) (t/is (= (:touched instance2) nil)) (t/is (= (:name shape2) "Rect 1")) (t/is (= (:fill-color shape2) clr/test)) (t/is (= (:fill-opacity shape2) 0.5)) (t/is (= (:touched shape2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:fill-color c-shape1) clr/test)) @@ -1375,9 +1375,9 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1 ---> Rect 1 (color, stroke) - ; Rect 1-2 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Rect 1* ---> Rect 1 (color, stroke2) ; #{:stroke-group} ; @@ -1395,21 +1395,21 @@ new-state (:id instance2))] - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:fill-color shape1) clr/test)) (t/is (= (:stroke-width shape1) 0.5)) (t/is (= (:touched shape1) nil)) - (t/is (= (:name instance2) "Rect 1-2")) + (t/is (= (:name instance2) "Rect 1")) (t/is (= (:touched instance2) nil)) (t/is (= (:name shape2) "Rect 1")) (t/is (= (:fill-color shape2) clr/test)) (t/is (= (:stroke-width shape2) 0.2)) (t/is (= (:touched shape2) #{:stroke-group})) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:fill-color c-shape1) clr/test)) @@ -1452,12 +1452,12 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 + ; Rect 1 #--> Rect 1 ; Circle 1 ---> Circle 1 ; Rect 1 ---> Rect 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Circle 1 ; Rect 1 ; @@ -1467,7 +1467,7 @@ new-state (thp/id :instance1))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) nil)) (t/is (not= (:shape-ref group) nil)) (t/is (= (:name shape1) "Circle 1")) @@ -1477,7 +1477,7 @@ (t/is (= (:touched shape2) nil)) (t/is (not= (:shape-ref shape2) nil)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:shape-ref c-group) nil)) (t/is (= (:name c-shape1) "Circle 1")) @@ -1654,7 +1654,7 @@ ; ; [Page] ; Root Frame - ; Rect 1-1 #--> Rect 1-1 (color, opacity) + ; Rect 1 #--> Rect 1 (color, opacity) ; Rect 1 ---> Rect 1 ; (let [[[group shape1] [c-group c-shape1] component] @@ -1662,14 +1662,14 @@ new-state (:id instance2))] - (t/is (= (:name group) "Rect 1-1")) + (t/is (= (:name group) "Rect 1")) (t/is (= (:touched group) nil)) (t/is (= (:name shape1) "Rect 1")) (t/is (= (:fill-color shape1) clr/test)) (t/is (= (:fill-opacity shape1) 0.5)) (t/is (= (:touched shape1) nil)) - (t/is (= (:name c-group) "Rect 1-1")) + (t/is (= (:name c-group) "Rect 1")) (t/is (= (:touched c-group) nil)) (t/is (= (:name c-shape1) "Rect 1")) (t/is (= (:fill-color c-shape1) clr/test)) @@ -1716,18 +1716,18 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ---> Circle 1 (color, opacity) ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 (color, opacity) ; @@ -1739,9 +1739,9 @@ ; TODO: get and check the instance inside component [Group-1] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -1752,9 +1752,9 @@ (t/is (= (:fill-color shape2) clr/white)) (t/is (= (:fill-opacity shape2) 1)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -1805,18 +1805,18 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) ; Circle 1 ---> Circle 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) ; Circle 1 ; @@ -1828,9 +1828,9 @@ ; TODO: get and check the instance inside component [Group-1] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -1841,9 +1841,9 @@ (t/is (= (:fill-color shape2) clr/test)) (t/is (= (:fill-opacity shape2) 0.5)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) @@ -1895,18 +1895,18 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; Group #--> Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 (color, opacity) ; Circle 1 ---> Circle 1 ; ; [Rect 1] - ; Rect 1-1 + ; Rect 1 ; Rect 1 (color, opacity) ; - ; [Group-1] - ; Group-1 - ; Rect 1-1 @--> Rect 1-1 + ; [Group] + ; Group + ; Rect 1 @--> Rect 1 ; Rect 1 ---> Rect 1 ; Circle 1 ; @@ -1918,9 +1918,9 @@ ; TODO: get and check the instance inside component [Group-1] - (t/is (= (:name instance2) "Group-1")) + (t/is (= (:name instance2) "Group")) (t/is (= (:touched instance2) nil)) - (t/is (= (:name instance1) "Rect 1-1")) + (t/is (= (:name instance1) "Rect 1")) (t/is (= (:touched instance1) nil)) (t/is (= (:name shape1) "Circle 1")) (t/is (= (:touched shape1) nil)) @@ -1931,9 +1931,9 @@ (t/is (= (:fill-color shape2) clr/test)) (t/is (= (:fill-opacity shape2) 0.5)) - (t/is (= (:name c-instance2) "Group-1")) + (t/is (= (:name c-instance2) "Group")) (t/is (= (:touched c-instance2) nil)) - (t/is (= (:name c-instance1) "Rect 1-1")) + (t/is (= (:name c-instance1) "Rect 1")) (t/is (= (:touched c-instance1) nil)) (t/is (= (:name c-shape1) "Circle 1")) (t/is (= (:touched c-shape1) nil)) diff --git a/frontend/test/frontend_tests/state_components_test.cljs b/frontend/test/frontend_tests/state_components_test.cljs index 86a4a56d6..8b83e1e75 100644 --- a/frontend/test/frontend_tests/state_components_test.cljs +++ b/frontend/test/frontend_tests/state_components_test.cljs @@ -43,11 +43,11 @@ ; ; [Page] ; Root Frame - ; Rect-2 #--> Rect-2 + ; Rect-1 #--> Rect-1 ; Rect-1 ---> Rect-1 ; - ; [Rect-2] - ; Rect-2 + ; [Rect-1] + ; Rect-1 ; Rect-1 ; (let [shape1 (thp/get-shape new-state :shape1) @@ -60,10 +60,10 @@ file (wsh/get-local-file new-state)] (t/is (= (:name shape1) "Rect-1")) - (t/is (= (:name group) "Rect-2")) - (t/is (= (:name component) "Rect-2")) + (t/is (= (:name group) "Rect-1")) + (t/is (= (:name component) "Rect-1")) (t/is (= (:name c-shape1) "Rect-1")) - (t/is (= (:name c-group) "Rect-2")) + (t/is (= (:name c-group) "Rect-1")) (thl/is-from-file group file))))] @@ -179,12 +179,12 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 + ; Group #--> Group ; Rect-1 ---> Rect-1 ; Rect-2 ---> Rect-2 ; - ; [Group-1] - ; Group-1 + ; [Group] + ; Group ; Rect-1 ; Rect-2 ; @@ -199,11 +199,11 @@ (t/is (= (:name shape1) "Rect-1")) (t/is (= (:name shape2) "Rect-2")) - (t/is (= (:name group) "Group-1")) - (t/is (= (:name component) "Group-1")) + (t/is (= (:name group) "Group")) + (t/is (= (:name component) "Group")) (t/is (= (:name c-shape1) "Rect-1")) (t/is (= (:name c-shape2) "Rect-2")) - (t/is (= (:name c-group) "Group-1")) + (t/is (= (:name c-group) "Group")) (thl/is-from-file group file))))] @@ -229,17 +229,17 @@ ; ; [Page] ; Root Frame - ; Rect-3 #--> Rect-3 - ; Rect-2 @--> Rect-2 + ; Rect-1 #--> Rect-1 + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; - ; [Rect-2] - ; Rect-2 + ; [Rect-1] + ; Rect-1 ; Rect-1 ; - ; [Rect-2] - ; Rect-3 - ; Rect-2 @--> Rect-2 + ; [Rect-1] + ; Rect-1 + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; (let [[[instance1 shape1] @@ -258,18 +258,18 @@ (:parent-id instance1))] (t/is (= (:name shape1) "Rect-1")) - (t/is (= (:name instance1) "Rect-2")) - (t/is (= (:name component1) "Rect-2")) + (t/is (= (:name instance1) "Rect-1")) + (t/is (= (:name component1) "Rect-1")) (t/is (= (:name c-shape1) "Rect-1")) - (t/is (= (:name c-instance1) "Rect-2")) + (t/is (= (:name c-instance1) "Rect-1")) (t/is (= (:name shape1') "Rect-1")) - (t/is (= (:name instance1') "Rect-2")) - (t/is (= (:name instance2) "Rect-3")) - (t/is (= (:name component2) "Rect-3")) + (t/is (= (:name instance1') "Rect-1")) + (t/is (= (:name instance2) "Rect-1")) + (t/is (= (:name component2) "Rect-1")) (t/is (= (:name c-shape1') "Rect-1")) - (t/is (= (:name c-instance1') "Rect-2")) - (t/is (= (:name c-instance2) "Rect-3")))))] + (t/is (= (:name c-instance1') "Rect-1")) + (t/is (= (:name c-instance2) "Rect-1")))))] (ptk/emit! store @@ -332,15 +332,15 @@ ; ; [Page] ; Root Frame - ; Rect-2 #--> Rect-2 + ; Rect-1 #--> Rect-1 ; Rect-1 ---> Rect-1 ; ; [Rect-1] - ; Rect-2 + ; Rect-1 ; Rect-1 ; - ; [Rect-3] - ; Rect-2 + ; [Rect-1] + ; Rect-1 ; Rect-1 ; (let [new-component-id (->> (get-in new-state @@ -363,7 +363,7 @@ new-state new-component-id)] - (t/is (= (:name component2) "Rect-3")))))] + (t/is (= (:name component2) "Rect-1")))))] (ptk/emit! store @@ -434,13 +434,13 @@ ; ; [Page] ; Root Frame - ; Rect-2 #--> Rect-2 + ; Rect-1 #--> Rect-1 ; Rect-1 ---> Rect-1 - ; Rect-3 #--> Rect-2 + ; Rect-1 #--> Rect-1 ; Rect-1 ---> Rect-1 ; - ; [Rect-2] - ; Rect-2 + ; [Rect-1] + ; Rect-1 ; Rect-1 ; (let [new-instance-id (-> new-state @@ -456,9 +456,9 @@ (t/is (not= (:id instance1) (:id instance2))) (t/is (= (:id component) component-id)) - (t/is (= (:name instance2) "Rect-3")) + (t/is (= (:name instance2) "Rect-1")) (t/is (= (:name shape2) "Rect-1")) - (t/is (= (:name c-instance2) "Rect-2")) + (t/is (= (:name c-instance2) "Rect-1")) (t/is (= (:name c-shape2) "Rect-1")) (t/is (= (:component-file instance2) thp/current-file-id)))))] @@ -491,7 +491,7 @@ ; ; [Page] ; Root Frame - ; Rect-2 #--> Rect-2 + ; Rect-1 #--> Rect-1 ; Rect-1 ---> Rect-1 ; (let [new-instance-id (-> new-state @@ -506,9 +506,9 @@ new-instance-id)] (t/is (= (:id component) component-id)) - (t/is (= (:name instance2) "Rect-2")) + (t/is (= (:name instance2) "Rect-1")) (t/is (= (:name shape2) "Rect-1")) - (t/is (= (:name c-instance2) "Rect-2")) + (t/is (= (:name c-instance2) "Rect-1")) (t/is (= (:name c-shape2) "Rect-1")) (t/is (= (:component-file instance2) library-id)))))] @@ -576,17 +576,17 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect-2 @--> Rect-2 + ; Group #--> Group + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; ; [Rect-1] - ; Rect-2 + ; Rect-1 ; Rect-1 ; - ; [Group-1] - ; Group-1 - ; Rect-2 @--> Rect-2 + ; [Group] + ; Group + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; (let [page (thp/current-page new-state) @@ -600,12 +600,12 @@ new-state (:parent-id parent1))] - (t/is (= (:name group) "Group-1")) - (t/is (= (:name shape1) "Rect-2")) + (t/is (= (:name group) "Group")) + (t/is (= (:name shape1) "Rect-1")) (t/is (= (:name shape2) "Rect-1")) - (t/is (= (:name component) "Group-1")) - (t/is (= (:name c-group) "Group-1")) - (t/is (= (:name c-shape1) "Rect-2")) + (t/is (= (:name component) "Group")) + (t/is (= (:name c-group) "Group")) + (t/is (= (:name c-shape1) "Rect-1")) (t/is (= (:name c-shape2) "Rect-1")))))] (ptk/emit! @@ -641,20 +641,20 @@ ; ; [Page] ; Root Frame - ; Rect-2 #--> Rect-2 - ; Rect-2 @--> Rect-2 + ; Rect-1 #--> Rect-1 + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 - ; Rect-3 #--> Rect-2 - ; Rect-2 @--> Rect-2 + ; Rect-1 #--> Rect-1 + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; ; [Rect-1] - ; Rect-2 + ; Rect-1 ; Rect-1 ; - ; [Rect-2] - ; Rect-2 - ; Rect-2 @--> Rect-2 + ; [Rect-1] + ; Rect-1 + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; (let [new-instance-id (-> new-state @@ -672,11 +672,11 @@ (t/is (not= (:id instance1) (:id instance3))) (t/is (= (:id component) component-id)) - (t/is (= (:name instance3) "Rect-3")) - (t/is (= (:name shape3) "Rect-2")) + (t/is (= (:name instance3) "Rect-1")) + (t/is (= (:name shape3) "Rect-1")) (t/is (= (:name shape4) "Rect-1")) - (t/is (= (:name c-instance3) "Rect-2")) - (t/is (= (:name c-shape3) "Rect-2")) + (t/is (= (:name c-instance3) "Rect-1")) + (t/is (= (:name c-shape3) "Rect-1")) (t/is (= (:name c-shape4) "Rect-1")))))] (ptk/emit! @@ -710,13 +710,13 @@ ; ; [Page] ; Root Frame - ; Group-1 #--> Group-1 - ; Rect-2 @--> Rect-2 + ; Group #--> Group + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; - ; [Group-1] - ; Group-1 - ; Rect-2 @--> Rect-2 + ; [Group] + ; Group + ; Rect-1 @--> Rect-1 ; Rect-1 ---> Rect-1 ; (let [instance2 (thp/get-shape new-state :instance2) @@ -726,11 +726,11 @@ new-state (:parent-id instance2))] - (t/is (= (:name group1) "Group-1")) - (t/is (= (:name shape1) "Rect-2")) + (t/is (= (:name group1) "Group")) + (t/is (= (:name shape1) "Rect-1")) (t/is (= (:name shape2) "Rect-1")) - (t/is (= (:name c-group1) "Group-1")) - (t/is (= (:name c-shape1) "Rect-2")) + (t/is (= (:name c-group1) "Group")) + (t/is (= (:name c-shape1) "Rect-1")) (t/is (= (:name c-shape2) "Rect-1")) (t/is (= (:component-file group1) thp/current-file-id)) (t/is (= (:component-file shape1) library-id)) From 61e83d7e01e652820c550bee6c1a39482611b56a Mon Sep 17 00:00:00 2001 From: Eva Date: Wed, 18 Jan 2023 17:36:27 +0100 Subject: [PATCH 19/40] :bug: Add selected colors on rightbar when selecting a board --- .../src/app/main/ui/workspace/sidebar/options.cljs | 2 +- .../ui/workspace/sidebar/options/shapes/frame.cljs | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index 00a136f1c..80d4fa796 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -44,7 +44,7 @@ shape (gsh/transform-shape shape modifiers)] [:* (case (:type shape) - :frame [:& frame/options {:shape shape}] + :frame [:& frame/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] :group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}] :text [:& text/options {:shape shape :file-id file-id :shared-libs shared-libs}] :rect [:& rect/options {:shape shape}] diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs index 01b526220..0fe040b7b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs @@ -6,9 +6,11 @@ (ns app.main.ui.workspace.sidebar.options.shapes.frame (:require + [app.common.data :as d] [app.common.types.shape.layout :as ctl] [app.main.refs :as refs] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] + [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs-shape fill-menu]] [app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]] @@ -21,10 +23,10 @@ [rumext.v2 :as mf])) (mf/defc options - [{:keys [shape] :as props}] + [{:keys [shape file-id shape-with-children shared-libs] :as props}] (let [ids [(:id shape)] type (:type shape) - + objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v)))) stroke-values (select-keys shape stroke-attrs) layer-values (select-keys shape layer-attrs) measure-values (select-measure-keys shape) @@ -63,6 +65,11 @@ [:& stroke-menu {:ids ids :type type :values stroke-values}] + (when (> (count objects) 2) + [:& color-selection-menu {:type type + :shapes (vals objects) + :file-id file-id + :shared-libs shared-libs}]) [:& shadow-menu {:ids ids :values (select-keys shape [:shadow])}] [:& blur-menu {:ids ids From 1f9c89fb32dc55b8857d46afc939273f0fa5864e Mon Sep 17 00:00:00 2001 From: Eva Date: Thu, 19 Jan 2023 09:55:43 +0100 Subject: [PATCH 20/40] :bug: Fix add svg did not update layout --- frontend/src/app/main/data/workspace/svg_upload.cljs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index b2a9bef1c..096bd0464 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -22,6 +22,7 @@ [app.main.data.workspace.selection :as dws] [app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.state-helpers :as wsh] + [app.main.data.workspace.undo :as dwu] [app.main.repo :as rp] [app.util.color :as uc] [app.util.path.parser :as upp] @@ -585,7 +586,11 @@ (filter #(= :add-obj (:type %))) (map :id) reverse - vec))] + vec)) + undo-id (js/Symbol)] - (rx/of (dch/commit-changes changes) - (dws/select-shapes (d/ordered-set (:id new-shape)))))))) + (rx/of (dwu/start-undo-transaction undo-id) + (dch/commit-changes changes) + (dws/select-shapes (d/ordered-set (:id new-shape))) + (ptk/data-event :layout/update [(:id new-shape)]) + (dwu/commit-undo-transaction undo-id)))))) From 9fd6c65d9314cd70adb2c8ee6d12ab25322bd4de Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jan 2023 14:34:16 +0100 Subject: [PATCH 21/40] :bug: Fix problem with empty paths --- .../src/app/main/data/workspace/path/drawing.cljs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/data/workspace/path/drawing.cljs b/frontend/src/app/main/data/workspace/path/drawing.cljs index ef0e9403d..649d84571 100644 --- a/frontend/src/app/main/data/workspace/path/drawing.cljs +++ b/frontend/src/app/main/data/workspace/path/drawing.cljs @@ -279,11 +279,14 @@ state))) ptk/WatchEvent - (watch [_ _ _] - (rx/of (setup-frame-path) - (dwdc/handle-finish-drawing) - (dwe/start-edition-mode shape-id) - (change-edit-mode :draw))))) + (watch [_ state _] + (let [content (get-in state [:workspace-drawing :object :content] [])] + (if (seq content) + (rx/of (setup-frame-path) + (dwdc/handle-finish-drawing) + (dwe/start-edition-mode shape-id) + (change-edit-mode :draw)) + (rx/of (dwdc/handle-finish-drawing))))))) (defn handle-new-shape "Creates a new path shape" From 89371e10d10498029675a09371214dc61edbeb7d Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jan 2023 14:34:58 +0100 Subject: [PATCH 22/40] :bug: Fix problem moving shapes inside a group inside a layout --- .../src/app/common/geom/shapes/modifiers.cljc | 2 +- common/src/app/common/types/shape/layout.cljc | 17 ++++++++++++----- .../src/app/main/data/workspace/transforms.cljs | 4 ++-- frontend/src/app/main/refs.cljs | 6 +++--- frontend/src/app/util/snap_data.cljs | 4 ++-- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index ff6e05f52..ad762570f 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -359,7 +359,7 @@ to-reflow (cond-> to-reflow - (and (ctl/layout-child-id? objects current) + (and (ctl/layout-descent? objects parent-base) (not= uuid/zero (:frame-id parent-base))) (conj (:frame-id parent-base)))] (recur modif-tree diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc index 6213668aa..88988c275 100644 --- a/common/src/app/common/types/shape/layout.cljc +++ b/common/src/app/common/types/shape/layout.cljc @@ -6,6 +6,7 @@ (ns app.common.types.shape.layout (:require + [app.common.data.macros :as dm] [app.common.spec :as us] [clojure.spec.alpha :as s])) @@ -99,15 +100,21 @@ ([shape] (and (= :frame (:type shape)) (= :flex (:layout shape))))) -(defn layout-child? [objects shape] +(defn layout-immediate-child? [objects shape] + (let [parent-id (:parent-id shape) + parent (get objects parent-id)] + (layout? parent))) + +(defn layout-immediate-child-id? [objects id] + (let [parent-id (dm/get-in objects [id :parent-id]) + parent (get objects parent-id)] + (layout? parent))) + +(defn layout-descent? [objects shape] (let [frame-id (:frame-id shape) frame (get objects frame-id)] (layout? frame))) -(defn layout-child-id? [objects id] - (let [shape (get objects id)] - (layout-child? objects shape))) - (defn inside-layout? "Check if the shape is inside a layout" [objects shape] diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 5525b7302..6ff4cfa8c 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -440,7 +440,7 @@ exclude-frames-siblings (into exclude-frames (comp (mapcat (partial cph/get-siblings-ids objects)) - (filter (partial ctl/layout-child-id? objects))) + (filter (partial ctl/layout-immediate-child-id? objects))) selected) fix-axis @@ -640,7 +640,7 @@ (let [objects (wsh/lookup-page-objects state) selected (wsh/lookup-selected state {:omit-blocked? true}) selected-shapes (->> selected (map (d/getf objects)))] - (if (every? (partial ctl/layout-child? objects) selected-shapes) + (if (every? (partial ctl/layout-immediate-child-id? objects) selected-shapes) (rx/of (reorder-selected-layout-child direction)) (rx/of (nudge-selected-shapes direction shift?))))))) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 51a0becaa..262aa8139 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -402,7 +402,7 @@ (let [objects (wsh/lookup-page-objects state)] (into [] (comp (map (d/getf objects)) - (filter (partial ctl/layout-child? objects))) + (filter (partial ctl/layout-immediate-child? objects))) ids))) st/state =)) @@ -481,7 +481,7 @@ (fn [objects] (->> ids (map (d/getf objects)) - (some (partial ctl/layout-child? objects)))) + (some (partial ctl/layout-immediate-child? objects)))) workspace-page-objects)) (defn get-flex-child-viewer @@ -491,7 +491,7 @@ (let [objects (wsh/lookup-viewer-objects state page-id)] (into [] (comp (map (d/getf objects)) - (filter (partial ctl/layout-child? objects))) + (filter (partial ctl/layout-immediate-child? objects))) ids))) st/state =)) diff --git a/frontend/src/app/util/snap_data.cljs b/frontend/src/app/util/snap_data.cljs index 1de3b7a25..deb4239fe 100644 --- a/frontend/src/app/util/snap_data.cljs +++ b/frontend/src/app/util/snap_data.cljs @@ -82,7 +82,7 @@ grid-y-data (get-grids-snap-points frame :y)] (cond-> page-data - (not (ctl/layout-child? objects frame)) + (not (ctl/layout-descent? objects frame)) (-> ;; Update root frame information (assoc-in [uuid/zero :objects-data frame-id] frame-data) @@ -106,7 +106,7 @@ :id (:id shape) :pt %)))] (cond-> page-data - (not (ctl/layout-child? objects shape)) + (not (ctl/layout-descent? objects shape)) (-> (assoc-in [frame-id :objects-data (:id shape)] shape-data) (update-in [frame-id :x] (make-insert-tree-data shape-data :x)) (update-in [frame-id :y] (make-insert-tree-data shape-data :y)))))) From ab7683f1e3c17db163a78cfd1ca54c96db94896c Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jan 2023 15:19:17 +0100 Subject: [PATCH 23/40] :sparkles: Improved text layout handling --- .../app/main/data/workspace/modifiers.cljs | 2 +- .../src/app/main/data/workspace/texts.cljs | 123 ++++++++++++------ 2 files changed, 82 insertions(+), 43 deletions(-) diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index a93bb08f7..4e2c5de55 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -219,7 +219,7 @@ result (let [[id text-modifier] (first modifiers)] (recur (rest modifiers) - (update objects id apply-text-modifier text-modifier)))))) + (update result id apply-text-modifier text-modifier)))))) #_(defn apply-path-modifiers [objects path-modifiers] diff --git a/frontend/src/app/main/data/workspace/texts.cljs b/frontend/src/app/main/data/workspace/texts.cljs index be4b7eab6..b98de7713 100644 --- a/frontend/src/app/main/data/workspace/texts.cljs +++ b/frontend/src/app/main/data/workspace/texts.cljs @@ -15,7 +15,6 @@ [app.common.pages.helpers :as cph] [app.common.text :as txt] [app.common.types.modifiers :as ctm] - [app.common.uuid :as uuid] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.modifiers :as dwm] @@ -318,16 +317,25 @@ (defn not-changed? [old-dim new-dim] (> (mth/abs (- old-dim new-dim)) 1)) -(defn resize-text - [id new-width new-height] - (ptk/reify ::resize-text +(defn commit-resize-text + [] + (ptk/reify ::commit-resize-text ptk/WatchEvent (watch [_ state _] - (let [shape (wsh/lookup-shape state id) + (let [props (::resize-text-debounce-props state) + objects (wsh/lookup-page-objects state) undo-id (js/Symbol)] - (letfn [(update-fn [shape] - (let [{:keys [selrect grow-type]} shape - {shape-width :width shape-height :height} selrect + + (letfn [(changed-text? [id] + (let [shape (get objects id) + [new-width new-height] (get props id)] + (or (and (not-changed? (:width shape) new-width) (= (:grow-type shape) :auto-width)) + (and (not-changed? (:height shape) new-height) + (or (= (:grow-type shape) :auto-height) (= (:grow-type shape) :auto-width)))))) + + (update-fn [{:keys [id selrect grow-type] :as shape}] + (let [{shape-width :width shape-height :height} selrect + [new-width new-height] (get props id) shape (cond-> shape @@ -342,14 +350,39 @@ shape))] - (when (or (and (not-changed? (:width shape) new-width) (= (:grow-type shape) :auto-width)) - (and (not-changed? (:height shape) new-height) - (or (= (:grow-type shape) :auto-height) (= (:grow-type shape) :auto-width)))) + (let [ids (->> (keys props) (filter changed-text?))] (rx/of (dwu/start-undo-transaction undo-id) - (dch/update-shapes [id] update-fn {:reg-objects? true :save-undo? true}) - (ptk/data-event :layout/update [id]) + (dch/update-shapes ids update-fn {:reg-objects? true :save-undo? true}) + (ptk/data-event :layout/update ids) (dwu/commit-undo-transaction undo-id)))))))) +(defn resize-text + [id new-width new-height] + + (let [cur-event (js/Symbol)] + (ptk/reify ::resize-text + ptk/UpdateEvent + (update [_ state] + (-> state + (update ::resize-text-debounce-props (fnil assoc {}) id [new-width new-height]) + (cond-> (nil? (::resize-text-debounce-event state)) + (assoc ::resize-text-debounce-event cur-event)))) + + ptk/WatchEvent + (watch [_ state stream] + (if (= (::resize-text-debounce-event state) cur-event) + (let [stopper (->> stream (rx/filter (ptk/type? :app.main.data.workspace/finalize)))] + (rx/concat + (rx/merge + (->> stream + (rx/filter (ptk/type? ::resize-text)) + (rx/debounce 50) + (rx/take 1) + (rx/map #(commit-resize-text)) + (rx/take-until stopper)) + (rx/of (resize-text id new-width new-height))) + (rx/of #(dissoc % ::resize-text-debounce-props ::resize-text-debounce-event)))) + (rx/empty)))))) (defn save-font [data] @@ -384,37 +417,43 @@ new-shape)) -(defn update-text-modifier-state - [id props] - (ptk/reify ::update-text-modifier-state - ptk/UpdateEvent - (update [_ state] - (update-in state [:workspace-text-modifier id] (fnil merge {}) props)))) +(defn commit-update-text-modifier + [] + (ptk/reify ::commit-update-text-modifier + ptk/WatchEvent + (watch [_ state _] + (let [ids (::update-text-modifier-debounce-ids state)] + (let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))] + (rx/of (dwm/update-modifiers modif-tree false true))))))) (defn update-text-modifier [id props] - (ptk/reify ::update-text-modifier - ptk/WatchEvent - (watch [_ state _] - (let [modifiers (get-in (:workspace-modifiers state) [id :modifiers]) - shape (-> (wsh/lookup-shape state id) - (gsh/transform-shape modifiers)) + (let [cur-event (js/Symbol)] + (ptk/reify ::update-text-modifier + ptk/UpdateEvent + (update [_ state] + (-> state + (update-in [:workspace-text-modifier id] (fnil merge {}) props) + (update ::update-text-modifier-debounce-ids (fnil conj #{}) id) + (cond-> (nil? (::update-text-modifier-debounce-event state)) + (assoc ::update-text-modifier-debounce-event cur-event)))) - current-width (:width shape) - current-height (:height shape)] - (rx/concat - (rx/of (update-text-modifier-state id props)) - - (if (or (and (some? (:width props)) - (not (mth/close? (:width props) current-width))) - (and (some? (:height props)) - (not (mth/close? (:height props) current-height)))) - - (let [modif-tree (dwm/create-modif-tree [id] (ctm/reflow-modifiers))] - (->> (rx/of (dwm/update-modifiers modif-tree false true)) - (rx/observe-on :async))) - (rx/empty))))))) + ptk/WatchEvent + (watch [_ state stream] + (if (= (::update-text-modifier-debounce-event state) cur-event) + (let [stopper (->> stream (rx/filter (ptk/type? :app.main.data.workspace/finalize)))] + (rx/concat + (rx/merge + (->> stream + (rx/filter (ptk/type? ::update-text-modifier)) + (rx/debounce 50) + (rx/take 1) + (rx/map #(commit-update-text-modifier)) + (rx/take-until stopper)) + (rx/of (update-text-modifier id props))) + (rx/of #(dissoc % ::update-text-modifier-debounce-event ::update-text-modifier-debounce-ids)))) + (rx/empty)))))) (defn clean-text-modifier [id] @@ -464,18 +503,18 @@ (defn update-position-data [id position-data] - (let [start (uuid/next)] + (let [cur-event (js/Symbol)] (ptk/reify ::update-position-data ptk/UpdateEvent (update [_ state] (let [state (assoc-in state [:workspace-text-modifier id :position-data] position-data)] (if (nil? (::update-position-data-debounce state)) - (assoc state ::update-position-data-debounce start) + (assoc state ::update-position-data-debounce cur-event) (assoc-in state [::update-position-data id] position-data)))) ptk/WatchEvent (watch [_ state stream] - (if (= (::update-position-data-debounce state) start) + (if (= (::update-position-data-debounce state) cur-event) (let [stopper (->> stream (rx/filter (ptk/type? :app.main.data.workspace/finalize)))] (rx/merge (->> stream From 4e1eb2d6e9e14393795b54d5fea59ce2393b3126 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jan 2023 16:31:45 +0100 Subject: [PATCH 24/40] :bug: Fix problem when flipping a mask --- .../app/main/data/workspace/transforms.cljs | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 6ff4cfa8c..4539c490c 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -750,36 +750,22 @@ (ptk/reify ::flip-horizontal-selected ptk/WatchEvent (watch [_ state _] - (let [objects (wsh/lookup-page-objects state) - selected (wsh/lookup-selected state {:omit-blocked? true}) - shapes (map #(get objects %) selected) - selrect (gsh/selection-rect shapes) - origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2))) - - modif-tree (dwm/create-modif-tree - selected - (-> (ctm/empty) - (ctm/resize (gpt/point -1.0 1.0) origin) - (ctm/move (gpt/point (:width selrect) 0))))] - - (rx/of (dwm/set-modifiers modif-tree true) - (dwm/apply-modifiers)))))) + (let [objects (wsh/lookup-page-objects state) + selected (wsh/lookup-selected state {:omit-blocked? true}) + shapes (map #(get objects %) selected) + selrect (gsh/selection-rect shapes) + center (gsh/center-selrect selrect) + modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point -1.0 1.0) center))] + (rx/of (dwm/apply-modifiers {:modifiers modifiers})))))) (defn flip-vertical-selected [] (ptk/reify ::flip-vertical-selected ptk/WatchEvent (watch [_ state _] - (let [objects (wsh/lookup-page-objects state) - selected (wsh/lookup-selected state {:omit-blocked? true}) - shapes (map #(get objects %) selected) - selrect (gsh/selection-rect shapes) - origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect)) - - modif-tree (dwm/create-modif-tree - selected - (-> (ctm/empty) - (ctm/resize (gpt/point 1.0 -1.0) origin) - (ctm/move (gpt/point 0 (:height selrect)))))] - - (rx/of (dwm/set-modifiers modif-tree true) - (dwm/apply-modifiers)))))) + (let [objects (wsh/lookup-page-objects state) + selected (wsh/lookup-selected state {:omit-blocked? true}) + shapes (map #(get objects %) selected) + selrect (gsh/selection-rect shapes) + center (gsh/center-selrect selrect) + modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point 1.0 -1.0) center))] + (rx/of (dwm/apply-modifiers {:modifiers modifiers})))))) From 4b5caf5fb90b9ca54ad9aca553dad81c7894bc15 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jan 2023 17:08:50 +0100 Subject: [PATCH 25/40] :sparkles: Shift+move ignores snap-pixel on the axis moving --- .../src/app/common/geom/shapes/modifiers.cljc | 6 ++-- .../common/geom/shapes/pixel_precision.cljc | 21 ++++++++---- .../app/main/data/workspace/modifiers.cljs | 14 ++++++-- .../app/main/data/workspace/transforms.cljs | 33 ++++++++++--------- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index ad762570f..15cfdd9c0 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -389,8 +389,8 @@ (set-objects-modifiers nil modif-tree objects params)) ([old-modif-tree modif-tree objects - {:keys [ignore-constraints snap-pixel? snap-precision] - :or {ignore-constraints false snap-pixel? false snap-precision 1}}] + {:keys [ignore-constraints snap-pixel? snap-precision snap-ignore-axis] + :or {ignore-constraints false snap-pixel? false snap-precision 1 snap-ignore-axis nil}}] (let [objects (-> objects (cond-> (some? old-modif-tree) (apply-structure-modifiers old-modif-tree)) @@ -398,7 +398,7 @@ modif-tree (cond-> modif-tree - snap-pixel? (gpp/adjust-pixel-precision objects snap-precision)) + snap-pixel? (gpp/adjust-pixel-precision objects snap-precision snap-ignore-axis)) bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points])) bounds (cond-> bounds diff --git a/common/src/app/common/geom/shapes/pixel_precision.cljc b/common/src/app/common/geom/shapes/pixel_precision.cljc index f75b650d9..e85c70893 100644 --- a/common/src/app/common/geom/shapes/pixel_precision.cljc +++ b/common/src/app/common/geom/shapes/pixel_precision.cljc @@ -39,16 +39,25 @@ (ctm/resize scalev origin transform transform-inverse {:precise? true})))) (defn position-pixel-precision - [modifiers _ points precision] + [modifiers _ points precision ignore-axis] (let [bounds (gpr/bounds->rect points) corner (gpt/point bounds) - target-corner (gpt/round-step corner precision) + target-corner + (cond-> corner + (= ignore-axis :x) + (update :y mth/round precision) + + (= ignore-axis :y) + (update :x mth/round precision) + + (nil? ignore-axis) + (gpt/round-step precision)) deltav (gpt/to-vec corner target-corner)] (ctm/move modifiers deltav))) (defn set-pixel-precision "Adjust modifiers so they adjust to the pixel grid" - [modifiers shape precision] + [modifiers shape precision ignore-axis] (let [points (-> shape :points (gco/transform-points (ctm/modifiers->transform modifiers))) has-resize? (not (ctm/only-move? modifiers)) @@ -63,16 +72,16 @@ (gco/transform-points (ctm/modifiers->transform modifiers)) ) points)] [modifiers points])] - (position-pixel-precision modifiers shape points precision))) + (position-pixel-precision modifiers shape points precision ignore-axis))) (defn adjust-pixel-precision - [modif-tree objects precision] + [modif-tree objects precision ignore-axis] (let [update-modifiers (fn [modif-tree shape] (let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])] (cond-> modif-tree (ctm/has-geometry? modifiers) - (update-in [(:id shape) :modifiers] set-pixel-precision shape precision))))] + (update-in [(:id shape) :modifiers] set-pixel-precision shape precision ignore-axis))))] (->> (keys modif-tree) (map (d/getf objects)) diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 4e2c5de55..717dfa7fe 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -241,6 +241,9 @@ (calculate-modifiers state false false modif-tree)) ([state ignore-constraints ignore-snap-pixel modif-tree] + (calculate-modifiers state ignore-constraints ignore-snap-pixel modif-tree nil)) + + ([state ignore-constraints ignore-snap-pixel modif-tree params] (let [objects (wsh/lookup-page-objects state) @@ -253,7 +256,11 @@ (as-> objects $ (apply-text-modifiers $ (get state :workspace-text-modifier)) ;;(apply-path-modifiers $ (get-in state [:workspace-local :edit-path])) - (gsh/set-objects-modifiers modif-tree $ {:ignore-constraints ignore-constraints :snap-pixel? snap-pixel? :snap-precision snap-precision}))))) + (gsh/set-objects-modifiers modif-tree $ (merge + params + {:ignore-constraints ignore-constraints + :snap-pixel? snap-pixel? + :snap-precision snap-precision})))))) (defn- calculate-update-modifiers [old-modif-tree state ignore-constraints ignore-snap-pixel modif-tree] @@ -292,10 +299,13 @@ (set-modifiers modif-tree ignore-constraints false)) ([modif-tree ignore-constraints ignore-snap-pixel] + (set-modifiers modif-tree ignore-constraints ignore-snap-pixel nil)) + + ([modif-tree ignore-constraints ignore-snap-pixel params] (ptk/reify ::set-modifiers ptk/UpdateEvent (update [_ state] - (assoc state :workspace-modifiers (calculate-modifiers state ignore-constraints ignore-snap-pixel modif-tree)))))) + (assoc state :workspace-modifiers (calculate-modifiers state ignore-constraints ignore-snap-pixel modif-tree params)))))) ;; Rotation use different algorithm to calculate children modifiers (and do not use child constraints). (defn set-rotation-modifiers diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 4539c490c..06de28bb4 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -443,18 +443,8 @@ (filter (partial ctl/layout-immediate-child-id? objects))) selected) - fix-axis - (fn [[position shift?]] - (let [delta (gpt/to-vec from-position position)] - (if shift? - (if (> (mth/abs (:x delta)) (mth/abs (:y delta))) - (gpt/point (:x delta) 0) - (gpt/point 0 (:y delta))) - delta))) - position (->> ms/mouse-position - (rx/with-latest-from ms/mouse-position-shift) - (rx/map #(fix-axis %))) + (rx/map #(gpt/to-vec from-position %))) snap-delta (rx/concat ;; We send the nil first so the stream is not waiting for the first value @@ -491,11 +481,24 @@ (rx/merge ;; Temporary modifiers stream (->> move-stream + (rx/with-latest-from ms/mouse-position-shift) (rx/map - (fn [[move-vector target-frame drop-index]] - (-> (dwm/create-modif-tree ids (ctm/move-modifiers move-vector)) - (dwm/build-change-frame-modifiers objects selected target-frame drop-index) - (dwm/set-modifiers))))) + (fn [[[move-vector target-frame drop-index] shift?]] + (let [x-disp? (> (mth/abs (:x move-vector)) (mth/abs (:y move-vector))) + [move-vector snap-ignore-axis] + (cond + (and shift? x-disp?) + [(assoc move-vector :y 0) :y] + + shift? + [(assoc move-vector :x 0) :x] + + :else + [move-vector nil])] + + (-> (dwm/create-modif-tree ids (ctm/move-modifiers move-vector)) + (dwm/build-change-frame-modifiers objects selected target-frame drop-index) + (dwm/set-modifiers false false {:snap-ignore-axis snap-ignore-axis})))))) (->> move-stream (rx/map (comp set-ghost-displacement first))) From d78ad30e23d4e006d02401447e6fd0548e631ada Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jan 2023 17:13:55 +0100 Subject: [PATCH 26/40] :sparkles: Enter on containers selects children --- frontend/src/app/main/data/workspace.cljs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index ff5ba2a52..e017b6362 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -846,8 +846,8 @@ :text (rx/of (dwe/start-edition-mode id)) - (:group :bool) - (rx/of (dws/select-shapes (into (d/ordered-set) [(last shapes)]))) + (:group :bool :frame) + (rx/of (dws/select-shapes (into (d/ordered-set) shapes))) :svg-raw nil From e7ac7ff7fb9eca82786440b71e79902638de9566 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 18 Jan 2023 17:26:16 +0100 Subject: [PATCH 27/40] :bug: Fix problem with disappearing titles --- .../app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs index a3c2081a0..2c849e422 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs @@ -183,6 +183,9 @@ (dom/remove-attribute! node "data-old-width") (dom/remove-attribute! node "data-old-height")) + (dom/class? node "frame-title") + (dom/remove-attribute! node "data-old-transform") + :else (let [old-transform (dom/get-attribute node "data-old-transform")] (if (some? old-transform) From 0632111e96ecd60e66b39d01b6bfe4d3e1c46d85 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 19 Jan 2023 13:25:59 +0100 Subject: [PATCH 28/40] :bug: Fix reorder layers with keys --- frontend/src/app/main/data/workspace/transforms.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 06de28bb4..7cda5044a 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -643,7 +643,7 @@ (let [objects (wsh/lookup-page-objects state) selected (wsh/lookup-selected state {:omit-blocked? true}) selected-shapes (->> selected (map (d/getf objects)))] - (if (every? (partial ctl/layout-immediate-child-id? objects) selected-shapes) + (if (every? (partial ctl/layout-immediate-child? objects) selected-shapes) (rx/of (reorder-selected-layout-child direction)) (rx/of (nudge-selected-shapes direction shift?))))))) From 75d6e21af872f0974f79b2fabe306db205f73fa3 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 19 Jan 2023 13:34:13 +0100 Subject: [PATCH 29/40] :sparkles: Show tools on path creation. Change snap while drawing --- common/src/app/common/geom/point.cljc | 2 +- .../app/main/data/workspace/path/drawing.cljs | 39 ++++---------- .../app/main/data/workspace/path/edition.cljs | 54 +++++++++---------- .../app/main/data/workspace/path/streams.cljs | 28 +++++++--- .../main/ui/workspace/shapes/path/common.cljs | 12 +++-- .../main/ui/workspace/shapes/path/editor.cljs | 11 ++-- .../main/ui/workspace/viewport/widgets.cljs | 13 ++--- 7 files changed, 79 insertions(+), 80 deletions(-) diff --git a/common/src/app/common/geom/point.cljc b/common/src/app/common/geom/point.cljc index 6c640173a..d83a46c99 100644 --- a/common/src/app/common/geom/point.cljc +++ b/common/src/app/common/geom/point.cljc @@ -60,7 +60,7 @@ (point v v) (point-like? v) - (map->Point v) + (Point. (:x v) (:y v)) :else (ex/raise :hint "invalid arguments (on pointer constructor)" :value v))) diff --git a/frontend/src/app/main/data/workspace/path/drawing.cljs b/frontend/src/app/main/data/workspace/path/drawing.cljs index 649d84571..307c6e290 100644 --- a/frontend/src/app/main/data/workspace/path/drawing.cljs +++ b/frontend/src/app/main/data/workspace/path/drawing.cljs @@ -8,7 +8,6 @@ (:require [app.common.geom.point :as gpt] [app.common.geom.shapes.flex-layout :as gsl] - [app.common.geom.shapes.path :as upg] [app.common.path.commands :as upc] [app.common.path.shapes-to-path :as upsp] [app.common.spec :as us] @@ -125,14 +124,11 @@ (ptk/reify ::close-path-drag-start ptk/WatchEvent (watch [_ state stream] - (let [id (st/get-path-id state) - stop-stream + (let [stop-stream (->> stream (rx/filter #(or (helpers/end-path-event? %) (ms/mouse-up? %)))) content (st/get-path state :content) - snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled]) - points (upg/content->points content) handlers (-> (upc/content->handlers content) (get position)) @@ -141,7 +137,7 @@ (first handlers)) drag-events-stream - (->> (streams/position-stream snap-toggled points) + (->> (streams/position-stream) (rx/take-until stop-stream) (rx/map #(drag-handler position idx prefix %)))] @@ -164,16 +160,10 @@ (defn start-path-from-point [position] (ptk/reify ::start-path-from-point ptk/WatchEvent - (watch [_ state stream] + (watch [_ _ stream] (let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %) (ms/mouse-up? %)))) - content (st/get-path state :content) - points (upg/content->points content) - - id (st/get-path-id state) - snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled]) - - drag-events (->> (streams/position-stream snap-toggled points) + drag-events (->> (streams/position-stream) (rx/take-until mouse-up) (rx/map #(drag-handler %)))] @@ -192,11 +182,11 @@ (rx/merge-map #(rx/empty)))) (defn make-drag-stream - [stream snap-toggled _zoom points down-event] + [stream down-event] (let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %) (ms/mouse-up? %)))) - drag-events (->> (streams/position-stream snap-toggled points) + drag-events (->> (streams/position-stream) (rx/take-until mouse-up) (rx/map #(drag-handler %)))] @@ -217,20 +207,13 @@ (assoc-in [:workspace-local :edit-path id :edit-mode] :draw)))) ptk/WatchEvent - (watch [_ state stream] - (let [zoom (get-in state [:workspace-local :zoom]) - mouse-down (->> stream (rx/filter ms/mouse-down?)) + (watch [_ _ stream] + (let [mouse-down (->> stream (rx/filter ms/mouse-down?)) end-path-events (->> stream (rx/filter helpers/end-path-event?)) - content (st/get-path state :content) - points (upg/content->points content) - - id (st/get-path-id state) - snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled]) - ;; Mouse move preview mousemove-events - (->> (streams/position-stream snap-toggled points) + (->> (streams/position-stream) (rx/take-until end-path-events) (rx/map #(preview-next-point %))) @@ -238,12 +221,12 @@ mousedown-events (->> mouse-down (rx/take-until end-path-events) - (rx/with-latest merge (streams/position-stream snap-toggled points)) + (rx/with-latest merge (streams/position-stream)) ;; We change to the stream that emits the first event (rx/switch-map #(rx/race (make-node-events-stream stream) - (make-drag-stream stream snap-toggled zoom points %))))] + (make-drag-stream stream %))))] (rx/concat (rx/of (undo/start-path-undo)) diff --git a/frontend/src/app/main/data/workspace/path/edition.cljs b/frontend/src/app/main/data/workspace/path/edition.cljs index 2340da662..318f1dbf3 100644 --- a/frontend/src/app/main/data/workspace/path/edition.cljs +++ b/frontend/src/app/main/data/workspace/path/edition.cljs @@ -7,6 +7,7 @@ (ns app.main.data.workspace.path.edition (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.geom.point :as gpt] [app.common.geom.shapes.path :as upg] [app.common.path.commands :as upc] @@ -35,8 +36,8 @@ (let [content (st/get-path state :content) modifiers (helpers/move-handler-modifiers content index prefix false match-opposite? dx dy) [cx cy] (if (= prefix :c1) [:c1x :c1y] [:c2x :c2y]) - point (gpt/point (+ (get-in content [index :params cx]) dx) - (+ (get-in content [index :params cy]) dy))] + point (gpt/point (+ (dm/get-in content [index :params cx]) dx) + (+ (dm/get-in content [index :params cy]) dy))] (-> state (update-in [:workspace-local :edit-path id :content-modifiers] merge modifiers) @@ -51,7 +52,7 @@ id (st/get-path-id state) page-id (:current-page-id state) shape (st/get-path state) - content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers]) + content-modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers]) content (:content shape) new-content (upc/apply-content-modifiers content content-modifiers) @@ -98,7 +99,7 @@ (let [id (st/get-path-id state) content (st/get-path state :content) modifiers-reducer (partial modify-content-point content move-modifier) - content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {}) + content-modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers] {}) content-modifiers (->> points (reduce modifiers-reducer content-modifiers))] @@ -115,9 +116,9 @@ modifiers-reducer (partial modify-content-point content delta) - points (get-in state [:workspace-local :edit-path id :selected-points] #{}) + points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{}) - modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {}) + modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers] {}) modifiers (->> points (reduce modifiers-reducer modifiers))] @@ -132,8 +133,8 @@ (ptk/reify ::start-move-path-point ptk/WatchEvent (watch [_ state _] - (let [id (get-in state [:workspace-local :edition]) - selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{}) + (let [id (dm/get-in state [:workspace-local :edition]) + selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{}) selected? (contains? selected-points position)] (streams/drag-stream (rx/of @@ -148,10 +149,9 @@ ptk/WatchEvent (watch [_ state stream] (let [stopper (->> stream (rx/filter ms/mouse-up?)) - id (get-in state [:workspace-local :edition]) - snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled]) + id (dm/get-in state [:workspace-local :edition]) - selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{}) + selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{}) content (st/get-path state :content) points (upg/content->points content)] @@ -159,7 +159,7 @@ (rx/concat ;; This stream checks the consecutive mouse positions to do the dragging (->> points - (streams/move-points-stream snap-toggled start-position selected-points) + (streams/move-points-stream start-position selected-points) (rx/map #(move-selected-path-point start-position %)) (rx/take-until stopper)) (rx/of (apply-content-modifiers))))))) @@ -178,7 +178,7 @@ (ptk/reify ::finish-move-selected ptk/UpdateEvent (update [_ state] - (let [id (get-in state [:workspace-local :edition])] + (let [id (dm/get-in state [:workspace-local :edition])] (-> state (update-in [:workspace-local :edit-path id] dissoc :current-move)))))) @@ -192,8 +192,8 @@ ptk/UpdateEvent (update [_ state] - (let [id (get-in state [:workspace-local :edition]) - current-move (get-in state [:workspace-local :edit-path id :current-move])] + (let [id (dm/get-in state [:workspace-local :edition]) + current-move (dm/get-in state [:workspace-local :edit-path id :current-move])] (if (nil? current-move) (-> state (assoc-in [:workspace-local :edit-path id :moving-nodes] true) @@ -202,11 +202,11 @@ ptk/WatchEvent (watch [_ state stream] - (let [id (get-in state [:workspace-local :edition]) - current-move (get-in state [:workspace-local :edit-path id :current-move])] + (let [id (dm/get-in state [:workspace-local :edition]) + current-move (dm/get-in state [:workspace-local :edit-path id :current-move])] ;; id can be null if we just selected the tool but we didn't start drawing (if (and id (= same-event current-move)) - (let [points (get-in state [:workspace-local :edit-path id :selected-points] #{}) + (let [points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{}) move-events (->> stream (rx/filter (ptk/type? ::move-selected)) @@ -238,13 +238,13 @@ (ptk/reify ::start-move-handler ptk/WatchEvent (watch [_ state stream] - (let [id (get-in state [:workspace-local :edition]) + (let [id (dm/get-in state [:workspace-local :edition]) cx (d/prefix-keyword prefix :x) cy (d/prefix-keyword prefix :y) start-point @ms/mouse-position - modifiers (get-in state [:workspace-local :edit-path id :content-modifiers]) - start-delta-x (get-in modifiers [index cx] 0) - start-delta-y (get-in modifiers [index cy] 0) + modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers]) + start-delta-x (dm/get-in modifiers [index cx] 0) + start-delta-y (dm/get-in modifiers [index cy] 0) content (st/get-path state :content) points (upg/content->points content) @@ -253,14 +253,12 @@ handler (-> content (get index) (upc/get-handler prefix)) [op-idx op-prefix] (upc/opposite-index content index prefix) - opposite (upc/handler->point content op-idx op-prefix) - - snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])] + opposite (upc/handler->point content op-idx op-prefix)] (streams/drag-stream (rx/concat (rx/of (dch/update-shapes [id] upsp/convert-to-path)) - (->> (streams/move-handler-stream snap-toggled start-point point handler opposite points) + (->> (streams/move-handler-stream start-point point handler opposite points) (rx/take-until (->> stream (rx/filter #(or (ms/mouse-up? %) (streams/finish-edition? %))))) (rx/map @@ -283,7 +281,7 @@ (ptk/reify ::start-path-edit ptk/UpdateEvent (update [_ state] - (let [edit-path (get-in state [:workspace-local :edit-path id]) + (let [edit-path (dm/get-in state [:workspace-local :edit-path id]) content (st/get-path state :content) state (st/set-content state (ups/close-subpaths content))] (cond-> state @@ -297,7 +295,7 @@ ptk/WatchEvent (watch [_ state stream] - (let [mode (get-in state [:workspace-local :edit-path id :edit-mode]) + (let [mode (dm/get-in state [:workspace-local :edit-path id :edit-mode]) stopper (->> stream (rx/filter #(or (= (ptk/type %) ::dwe/clear-edition-mode) diff --git a/frontend/src/app/main/data/workspace/path/streams.cljs b/frontend/src/app/main/data/workspace/path/streams.cljs index 147fbd511..071e6ab12 100644 --- a/frontend/src/app/main/data/workspace/path/streams.cljs +++ b/frontend/src/app/main/data/workspace/path/streams.cljs @@ -6,10 +6,11 @@ (ns app.main.data.workspace.path.streams (:require + [app.common.data.macros :as dm] [app.common.geom.point :as gpt] [app.common.geom.shapes.path :as upg] [app.main.constants :refer [zoom-half-pixel-precision]] - [app.main.data.workspace.path.state :as state] + [app.main.data.workspace.path.state :as pst] [app.main.snap :as snap] [app.main.store :as st] [app.main.streams :as ms] @@ -71,15 +72,23 @@ (->> position-stream (rx/merge-map (fn [] to-stream))))))) +(defn snap-toggled-stream + [] + (let [get-snap (fn [state] + (let [id (pst/get-path-id state)] + (dm/get-in state [:workspace-local :edit-path id :snap-toggled])))] + (-> (l/derived get-snap st/state) + (rx/from-atom {:emit-current-value? true})))) + (defn move-points-stream - [snap-toggled start-point selected-points points] + [start-point selected-points points] (let [zoom (get-in @st/state [:workspace-local :zoom] 1) ranges (snap/create-ranges points selected-points) d-pos (/ snap/snap-path-accuracy zoom) check-path-snap - (fn [position] + (fn [[position snap-toggled]] (if snap-toggled (let [delta (gpt/subtract position start-point) moved-points (->> selected-points (mapv #(gpt/add % delta))) @@ -88,6 +97,7 @@ position))] (->> ms/mouse-position (rx/map to-pixel-snap) + (rx/with-latest-from (snap-toggled-stream)) (rx/map check-path-snap)))) (defn get-angle [node handler opposite] @@ -99,7 +109,7 @@ [rot-angle rot-sign]))) (defn move-handler-stream - [snap-toggled start-point node handler opposite points] + [start-point node handler opposite points] (let [zoom (get-in @st/state [:workspace-local :zoom] 1) ranges (snap/create-ranges points) @@ -108,7 +118,7 @@ [initial-angle] (get-angle node handler opposite) check-path-snap - (fn [position] + (fn [[position snap-toggled]] (if snap-toggled (let [delta (gpt/subtract position start-point) handler (gpt/add handler delta) @@ -134,13 +144,14 @@ (rx/map to-pixel-snap) (rx/with-latest merge (->> ms/mouse-position-shift (rx/map #(hash-map :shift? %)))) (rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %)))) + (rx/with-latest-from (snap-toggled-stream)) (rx/map check-path-snap)))) (defn position-stream - [snap-toggled _points] + [] (let [zoom (get-in @st/state [:workspace-local :zoom] 1) d-pos (/ snap/snap-path-accuracy zoom) - get-content #(state/get-path % :content) + get-content #(pst/get-path % :content) content-stream (-> (l/derived get-content st/state) @@ -154,7 +165,8 @@ (->> ms/mouse-position (rx/map to-pixel-snap) (rx/with-latest vector ranges-stream) - (rx/map (fn [[position ranges]] + (rx/with-latest-from (snap-toggled-stream)) + (rx/map (fn [[[position ranges] snap-toggled]] (if snap-toggled (let [snap (snap/get-snap-delta [position] ranges d-pos)] (gpt/add position snap)) diff --git a/frontend/src/app/main/ui/workspace/shapes/path/common.cljs b/frontend/src/app/main/ui/workspace/shapes/path/common.cljs index 8c6215304..0322e6571 100644 --- a/frontend/src/app/main/ui/workspace/shapes/path/common.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/path/common.cljs @@ -6,7 +6,10 @@ (ns app.main.ui.workspace.shapes.path.common (:require + [app.common.data.macros :as dm] + [app.main.data.workspace.path.state :as pst] [app.main.refs :as refs] + [app.main.store :as st] [okulary.core :as l] [rumext.v2 :as mf])) @@ -17,10 +20,11 @@ (def gray-color "var(--color-gray-20)") (def current-edit-path-ref - (let [selfn (fn [local] - (let [id (:edition local)] - (get-in local [:edit-path id])))] - (l/derived selfn refs/workspace-local))) + (l/derived + (fn [state] + (let [id (pst/get-path-id state)] + (dm/get-in state [:workspace-local :edit-path id]))) + st/state)) (defn make-edit-path-ref [id] (mf/use-memo diff --git a/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs b/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs index 8a991bf3f..9ee12f976 100644 --- a/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs @@ -327,14 +327,15 @@ [:g.path-node {:key (dm/str index "-" (:x position) "-" (:y position))} [:g.point-handlers {:pointer-events (when (= edit-mode :draw) "none")} - (for [[index prefix] pos-handlers] - (let [handler-position (upc/handler->point content index prefix) - handler-hover? (contains? hover-handlers [index prefix]) + (for [[hindex prefix] pos-handlers] + (let [handler-position (upc/handler->point content hindex prefix) + handler-hover? (contains? hover-handlers [hindex prefix]) moving-handler? (= handler-position moving-handler) matching-handler? (matching-handler? content position pos-handlers)] - [:& path-handler {:point position + [:& path-handler {:key (dm/str (dm/str index "-" (:x position) "-" (:y position)) "-" hindex "-" (d/name prefix)) + :point position :handler handler-position - :index index + :index hindex :prefix prefix :zoom zoom :hover? handler-hover? diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index 087dfd205..d95835fd5 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -50,12 +50,13 @@ (mf/defc viewport-actions {::mf/wrap [mf/memo]} [] - (let [edition (mf/deref refs/selected-edition) - selected (mf/deref refs/selected-objects) - shape (-> selected first)] - (when (and (= (count selected) 1) - (= (:id shape) edition) - (not= :text (:type shape))) + (let [edition (mf/deref refs/selected-edition) + selected (mf/deref refs/selected-objects) + drawing (mf/deref refs/workspace-drawing) + drawing-obj (:object drawing) + shape (or drawing-obj (-> selected first))] + (when (or (and (= (count selected) 1) (= (:id shape) edition) (not= :text (:type shape))) + (and (some? drawing-obj) (= :path (:type drawing-obj)))) [:div.viewport-actions [:& path-actions {:shape shape}]]))) From 77d71abb5dabfba1b928faf444646490662d8ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Thu, 19 Jan 2023 13:44:28 +0100 Subject: [PATCH 30/40] :bug: Sync correctly all layout attributes --- common/src/app/common/pages/common.cljc | 156 ++++++++++++------------ 1 file changed, 80 insertions(+), 76 deletions(-) diff --git a/common/src/app/common/pages/common.cljc b/common/src/app/common/pages/common.cljc index 6654e592f..ab5379504 100644 --- a/common/src/app/common/pages/common.cljc +++ b/common/src/app/common/pages/common.cljc @@ -19,84 +19,88 @@ ;; in the main component, none of the attributes of the same group is changed. (def component-sync-attrs - {:name :name-group - :fills :fill-group - :fill-color :fill-group - :fill-opacity :fill-group - :fill-color-gradient :fill-group - :fill-color-ref-file :fill-group - :fill-color-ref-id :fill-group - :hide-fill-on-export :fill-group - :content :content-group - :position-data :content-group - :hidden :visibility-group - :blocked :modifiable-group - :grow-type :text-font-group - :font-family :text-font-group - :font-size :text-font-group - :font-style :text-font-group - :font-weight :text-font-group - :letter-spacing :text-display-group - :line-height :text-display-group - :text-align :text-display-group - :strokes :stroke-group - :stroke-color :stroke-group - :stroke-color-gradient :stroke-group - :stroke-color-ref-file :stroke-group - :stroke-color-ref-id :stroke-group - :stroke-opacity :stroke-group - :stroke-style :stroke-group - :stroke-width :stroke-group - :stroke-alignment :stroke-group - :stroke-cap-start :stroke-group - :stroke-cap-end :stroke-group - :rx :radius-group - :ry :radius-group - :r1 :radius-group - :r2 :radius-group - :r3 :radius-group - :r4 :radius-group - :type :geometry-group - :selrect :geometry-group - :points :geometry-group - :locked :geometry-group - :proportion :geometry-group - :proportion-lock :geometry-group - :x :geometry-group - :y :geometry-group - :width :geometry-group - :height :geometry-group - :rotation :geometry-group - :transform :geometry-group - :transform-inverse :geometry-group - :opacity :layer-effects-group - :blend-mode :layer-effects-group - :shadow :shadow-group - :blur :blur-group - :masked-group? :mask-group - :constraints-h :constraints-group - :constraints-v :constraints-group - :fixed-scroll :constraints-group - :exports :exports-group + {:name :name-group + :fills :fill-group + :fill-color :fill-group + :fill-opacity :fill-group + :fill-color-gradient :fill-group + :fill-color-ref-file :fill-group + :fill-color-ref-id :fill-group + :hide-fill-on-export :fill-group + :content :content-group + :position-data :content-group + :hidden :visibility-group + :blocked :modifiable-group + :grow-type :text-font-group + :font-family :text-font-group + :font-size :text-font-group + :font-style :text-font-group + :font-weight :text-font-group + :letter-spacing :text-display-group + :line-height :text-display-group + :text-align :text-display-group + :strokes :stroke-group + :stroke-color :stroke-group + :stroke-color-gradient :stroke-group + :stroke-color-ref-file :stroke-group + :stroke-color-ref-id :stroke-group + :stroke-opacity :stroke-group + :stroke-style :stroke-group + :stroke-width :stroke-group + :stroke-alignment :stroke-group + :stroke-cap-start :stroke-group + :stroke-cap-end :stroke-group + :rx :radius-group + :ry :radius-group + :r1 :radius-group + :r2 :radius-group + :r3 :radius-group + :r4 :radius-group + :type :geometry-group + :selrect :geometry-group + :points :geometry-group + :locked :geometry-group + :proportion :geometry-group + :proportion-lock :geometry-group + :x :geometry-group + :y :geometry-group + :width :geometry-group + :height :geometry-group + :rotation :geometry-group + :transform :geometry-group + :transform-inverse :geometry-group + :opacity :layer-effects-group + :blend-mode :layer-effects-group + :shadow :shadow-group + :blur :blur-group + :masked-group? :mask-group + :constraints-h :constraints-group + :constraints-v :constraints-group + :fixed-scroll :constraints-group + :exports :exports-group - :layout :layout-container - :layout-dir :layout-container - :layout-gap :layout-container - :layout-wrap-type :layout-container - :layout-padding-type :layout-container - :layout-padding :layout-container - :layout-h-orientation :layout-container - :layout-v-orientation :layout-container + :layout :layout-container + :layout-align-content :layout-container + :layout-align-items :layout-container + :layout-flex-dir :layout-container + :layout-gap :layout-container + :layout-gap-type :layout-container + :layout-justify-content :layout-container + :layout-wrap-type :layout-container + :layout-padding-type :layout-container + :layout-padding :layout-container + :layout-h-orientation :layout-container + :layout-v-orientation :layout-container - :layout-item-margin :layout-item - :layout-item-margin-type :layout-item - :layout-item-h-sizing :layout-item - :layout-item-v-sizing :layout-item - :layout-item-max-h :layout-item - :layout-item-min-h :layout-item - :layout-item-max-w :layout-item - :layout-item-min-w :layout-item - :layout-item-align-self :layout-item}) + :layout-item-margin :layout-item + :layout-item-margin-type :layout-item + :layout-item-h-sizing :layout-item + :layout-item-v-sizing :layout-item + :layout-item-max-h :layout-item + :layout-item-min-h :layout-item + :layout-item-max-w :layout-item + :layout-item-min-w :layout-item + :layout-item-align-self :layout-item}) ;; Attributes that may directly be edited by the user with forms (def editable-attrs From 792c17fe465baaa15ea574f43ad3117c7d09c53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Thu, 19 Jan 2023 14:18:55 +0100 Subject: [PATCH 31/40] :bug: Fix display of components with frame root in assets panel --- frontend/src/app/main/render.cljs | 58 ++++++++++--------- .../app/main/ui/workspace/sidebar/assets.cljs | 3 +- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/frontend/src/app/main/render.cljs b/frontend/src/app/main/render.cljs index d1b9c0ff7..b1953c6f4 100644 --- a/frontend/src/app/main/render.cljs +++ b/frontend/src/app/main/render.cljs @@ -292,34 +292,37 @@ ;; used to render thumbnails on assets panel. (mf/defc component-svg {::mf/wrap [mf/memo #(mf/deferred % ts/idle-then-raf)]} - [{:keys [objects group zoom] :or {zoom 1} :as props}] - (let [group-id (:id group) + [{:keys [objects root-shape zoom] :or {zoom 1} :as props}] + (let [root-shape-id (:id root-shape) include-metadata? (mf/use-ctx export/include-metadata-ctx) vector (mf/use-memo - (mf/deps (:x group) (:y group)) + (mf/deps (:x root-shape) (:y root-shape)) (fn [] - (-> (gpt/point (:x group) (:y group)) + (-> (gpt/point (:x root-shape) (:y root-shape)) (gpt/negate)))) objects (mf/use-memo - (mf/deps vector objects group-id) + (mf/deps vector objects root-shape-id) (fn [] - (let [children-ids (cons group-id (cph/get-children-ids objects group-id)) + (let [children-ids (cons root-shape-id (cph/get-children-ids objects root-shape-id)) update-fn #(update %1 %2 gsh/transform-shape (ctm/move-modifiers vector))] (reduce update-fn objects children-ids)))) - group (get objects group-id) - width (* (:width group) zoom) - height (* (:height group) zoom) - vbox (format-viewbox {:width (:width group 0) - :height (:height group 0)}) - group-wrapper + root-shape (get objects root-shape-id) + width (* (:width root-shape) zoom) + height (* (:height root-shape) zoom) + vbox (format-viewbox {:width (:width root-shape 0) + :height (:height root-shape 0)}) + root-shape-wrapper (mf/use-memo - (mf/deps objects) - (fn [] (group-wrapper-factory objects)))] + (mf/deps objects root-shape) + (fn [] + (case (:type root-shape) + :group (group-wrapper-factory objects) + :frame (frame-wrapper-factory objects))))] [:svg {:view-box vbox :width (ust/format-precision width viewbox-decimal-precision) @@ -330,8 +333,8 @@ :xmlns:penpot (when include-metadata? "https://penpot.app/xmlns") :fill "none"} - [:> shape-container {:shape group} - [:& group-wrapper {:shape group :view-box vbox}]]])) + [:> shape-container {:shape root-shape} + [:& root-shape-wrapper {:shape root-shape :view-box vbox}]]])) (mf/defc object-svg {::mf/wrap [mf/memo]} @@ -375,12 +378,12 @@ (mf/defc component-symbol [{:keys [id data] :as props}] - (let [name (:name data) - path (:path data) - objects (-> (:objects data) - (adapt-objects-for-shape id)) - object (get objects id) - selrect (:selrect object) + (let [name (:name data) + path (:path data) + objects (-> (:objects data) + (adapt-objects-for-shape id)) + root-shape (get objects id) + selrect (:selrect root-shape) main-instance-id (:main-instance-id data) main-instance-page (:main-instance-page data) @@ -394,8 +397,11 @@ group-wrapper (mf/use-memo - (mf/deps objects) - (fn [] (group-wrapper-factory objects)))] + (mf/deps objects root-shape) + (fn [] + (case (:type root-shape) + :group (group-wrapper-factory objects) + :frame (frame-wrapper-factory objects))))] [:> "symbol" #js {:id (str id) :viewBox vbox @@ -405,8 +411,8 @@ "penpot:main-instance-x" main-instance-x "penpot:main-instance-y" main-instance-y} [:title name] - [:> shape-container {:shape object} - [:& group-wrapper {:shape object :view-box vbox}]]])) + [:> shape-container {:shape root-shape} + [:& group-wrapper {:shape root-shape :view-box vbox}]]])) (mf/defc components-sprite-svg {::mf/wrap-props false} diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 6a287f580..dcde545bb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -12,6 +12,7 @@ [app.common.pages.helpers :as cph] [app.common.spec :as us] [app.common.text :as txt] + [app.common.types.component :as ctk] [app.config :as cf] [app.main.data.events :as ev] [app.main.data.modal :as modal] @@ -434,7 +435,7 @@ :on-drag-over on-drag-over :on-drop on-drop} - [:& component-svg {:group (get-in component [:objects (:id component)]) + [:& component-svg {:root-shape (ctk/get-component-root component) :objects (:objects component)}] (let [renaming? (= renaming (:id component))] [:* From 2fef3dc881c689283b8ce375ad686c7fea0184e1 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 18 Jan 2023 17:12:33 +0100 Subject: [PATCH 32/40] :tada: Add prepl support And rename the current repl to urepl (user-repl). --- backend/scripts/repl | 16 +++++++++- backend/src/app/config.clj | 14 +++++---- backend/src/app/main.clj | 11 +++++-- backend/src/app/srepl.clj | 61 ++++++++++++++++++++++++++------------ 4 files changed, 73 insertions(+), 29 deletions(-) diff --git a/backend/scripts/repl b/backend/scripts/repl index 3fe39461b..9be6c1490 100755 --- a/backend/scripts/repl +++ b/backend/scripts/repl @@ -2,7 +2,21 @@ export PENPOT_HOST=devenv export PENPOT_TENANT=dev -export PENPOT_FLAGS="$PENPOT_FLAGS enable-backend-asserts enable-audit-log enable-transit-readable-response enable-demo-users disable-secure-session-cookies enable-smtp enable-webhooks" +export PENPOT_FLAGS="\ + $PENPOT_FLAGS \ + enable-backend-asserts \ + enable-audit-log \ + enable-transit-readable-response \ + enable-demo-users \ + disable-secure-session-cookies \ + enable-smtp \ + enable-prepl-server \ + enable-urepl-server \ + enable-rpc-climit \ + enable-rpc-rlimit \ + enable-soft-rpc-rlimit \ + enable-webhooks \ + enable-access-tokens"; # export PENPOT_DATABASE_URI="postgresql://172.17.0.1:5432/penpot" # export PENPOT_DATABASE_USERNAME="penpot" diff --git a/backend/src/app/config.clj b/backend/src/app/config.clj index 870ff58d5..ff0a187ad 100644 --- a/backend/src/app/config.clj +++ b/backend/src/app/config.clj @@ -64,8 +64,6 @@ :tenant "default" :redis-uri "redis://redis/0" - :srepl-host "127.0.0.1" - :srepl-port 6062 :assets-storage-backend :assets-fs :storage-assets-fs-directory "assets" @@ -196,8 +194,10 @@ (s/def ::smtp-ssl ::us/boolean) (s/def ::smtp-tls ::us/boolean) (s/def ::smtp-username (s/nilable ::us/string)) -(s/def ::srepl-host ::us/string) -(s/def ::srepl-port ::us/integer) +(s/def ::urepl-host ::us/string) +(s/def ::urepl-port ::us/integer) +(s/def ::prepl-host ::us/string) +(s/def ::prepl-port ::us/integer) (s/def ::assets-storage-backend ::us/keyword) (s/def ::storage-assets-fs-directory ::us/string) (s/def ::storage-assets-s3-bucket ::us/string) @@ -308,8 +308,10 @@ ::smtp-tls ::smtp-username - ::srepl-host - ::srepl-port + ::urepl-host + ::urepl-port + ::prepl-host + ::prepl-port ::assets-storage-backend ::storage-assets-fs-directory diff --git a/backend/src/app/main.clj b/backend/src/app/main.clj index 6b5141a84..02d33f479 100644 --- a/backend/src/app/main.clj +++ b/backend/src/app/main.clj @@ -21,6 +21,7 @@ [app.metrics :as-alias mtx] [app.metrics.definition :as-alias mdef] [app.redis :as-alias rds] + [app.srepl :as-alias srepl] [app.storage :as-alias sto] [app.util.time :as dt] [app.worker :as-alias wrk] @@ -404,9 +405,13 @@ ::http.client/client (ig/ref ::http.client/client) ::props (ig/ref :app.setup/props)} - :app.srepl/server - {:port (cf/get :srepl-port) - :host (cf/get :srepl-host)} + [::srepl/urepl ::srepl/server] + {:port (cf/get :urepl-port 6062) + :host (cf/get :urepl-host "localhost")} + + [::srepl/prepl ::srepl/server] + {:port (cf/get :prepl-port 6063) + :host (cf/get :prepl-host "localhost")} :app.setup/builtin-templates {::http.client/client (ig/ref ::http.client/client)} diff --git a/backend/src/app/srepl.clj b/backend/src/app/srepl.clj index ed4b44467..cd5838a76 100644 --- a/backend/src/app/srepl.clj +++ b/backend/src/app/srepl.clj @@ -9,7 +9,10 @@ (:require [app.common.logging :as l] [app.common.spec :as us] + [app.config :as cf] [app.srepl.main] + [app.util.json :as json] + [app.util.locks :as locks] [clojure.core.server :as ccs] [clojure.main :as cm] [clojure.spec.alpha :as s] @@ -20,39 +23,59 @@ (ccs/repl-init) (in-ns 'app.srepl.main)) -(defn repl +(defn user-repl [] (cm/repl :init repl-init :read ccs/repl-read)) +(defn json-prepl + [] + (let [out *out* + lock (locks/create)] + (ccs/prepl *in* + (fn [m] + (binding [*out* out, *flush-on-newline* true, *print-readably* true] + (locks/locking lock + (println (json/encode-str m)))))))) + ;; --- State initialization -(s/def ::name ::us/not-empty-string) -(s/def ::port int?) +(s/def ::port ::us/integer) (s/def ::host ::us/not-empty-string) +(s/def ::flag #{:urepl-server :prepl-server}) +(s/def ::type #{::prepl ::urepl}) +(s/def ::key (s/tuple ::type ::us/keyword)) (defmethod ig/pre-init-spec ::server [_] - (s/keys :opt-un [::port ::host ::name])) + (s/keys :req [::flag] + :req-un [::port ::host])) (defmethod ig/prep-key ::server - [_ cfg] - (merge {:name "main"} cfg)) + [[type _] cfg] + (assoc cfg ::flag (keyword (str (name type) "-server")))) (defmethod ig/init-key ::server - [_ {:keys [port host name] :as cfg}] - (when (and port host name) - (l/info :msg "initializing server repl" :port port :host host :name name) - (ccs/start-server {:address host - :port port - :name name - :accept 'app.srepl/repl}) - cfg)) + [[type _] {:keys [::flag port host] :as cfg}] + (when (contains? cf/flags flag) + (let [accept (case type + ::prepl 'app.srepl/json-prepl + ::urepl 'app.srepl/user-repl) + params {:address host + :port port + :name (name type) + :accept accept}] + + (l/info :msg "initializing repl server" + :name (name type) + :port port + :host host) + + (ccs/start-server params) + + params))) (defmethod ig/halt-key! ::server - [_ cfg] - (when cfg - (ccs/stop-server (:name cfg)))) - - + [_ params] + (some-> params :name ccs/stop-server)) From d98fd76032b0afa6a84bd613418b9011257689c0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 19 Jan 2023 12:41:06 +0100 Subject: [PATCH 33/40] :tada: Add namespace with a set of helpers for access throught the BREPL --- backend/src/app/srepl.clj | 1 + backend/src/app/srepl/ext.clj | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 backend/src/app/srepl/ext.clj diff --git a/backend/src/app/srepl.clj b/backend/src/app/srepl.clj index cd5838a76..5885fa369 100644 --- a/backend/src/app/srepl.clj +++ b/backend/src/app/srepl.clj @@ -10,6 +10,7 @@ [app.common.logging :as l] [app.common.spec :as us] [app.config :as cf] + [app.srepl.ext] [app.srepl.main] [app.util.json :as json] [app.util.locks :as locks] diff --git a/backend/src/app/srepl/ext.clj b/backend/src/app/srepl/ext.clj new file mode 100644 index 000000000..739491257 --- /dev/null +++ b/backend/src/app/srepl/ext.clj @@ -0,0 +1,44 @@ +;; 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 app.srepl.ext + "PREPL API for external usage (CLI or ADMIN)" + (:require + [app.auth :as auth] + [app.common.uuid :as uuid] + [app.db :as db] + [app.rpc.commands.auth :as cmd.auth])) + +(defn- get-current-system + [] + (or (deref (requiring-resolve 'app.main/system)) + (deref (requiring-resolve 'user/system)))) + +(defn derive-password + [password] + (auth/derive-password password)) + +(defn create-profile + [fullname, email, password] + (when-let [system (get-current-system)] + (db/with-atomic [conn (:app.db/pool system)] + (let [params {:id (uuid/next) + :email email + :fullname fullname + :is-active true + :password password + :props {}} + + profile (->> (cmd.auth/create-profile conn params) + (cmd.auth/create-profile-relations conn))] + + (str (:id profile)))))) + + + + + + From 73658c47f31745216975e21313745d11c8b406f1 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 19 Jan 2023 13:01:23 +0100 Subject: [PATCH 34/40] :bug: Fix issues on rlimit module --- backend/src/app/rpc/rlimit.clj | 122 +++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 53 deletions(-) diff --git a/backend/src/app/rpc/rlimit.clj b/backend/src/app/rpc/rlimit.clj index 5eb0f85ee..67be94684 100644 --- a/backend/src/app/rpc/rlimit.clj +++ b/backend/src/app/rpc/rlimit.clj @@ -182,78 +182,94 @@ (assoc ::lresult/remaining remaining) (assoc ::lresult/reset (dt/plus ts {unit 1}))))))))) -(defn- process-limits +(defn- process-limits! [redis user-id limits now] - (-> (p/all (map (partial process-limit redis user-id now) limits)) - (p/then (fn [results] - (let [remaining (->> results - (d/index-by ::name ::lresult/remaining) - (uri/map->query-string)) - reset (->> results - (d/index-by ::name (comp dt/->seconds ::lresult/reset)) - (uri/map->query-string)) - rejected (->> results - (filter (complement ::lresult/allowed?)) - (first))] + (->> (p/all (map (partial process-limit redis user-id now) limits)) + (p/fmap (fn [results] + (let [remaining (->> results + (d/index-by ::name ::lresult/remaining) + (uri/map->query-string)) + reset (->> results + (d/index-by ::name (comp dt/->seconds ::lresult/reset)) + (uri/map->query-string)) + rejected (->> results + (filter (complement ::lresult/allowed?)) + (first))] - (when rejected - (l/warn :hint "rejected rate limit" - :user-id (str user-id) - :limit-service (-> rejected ::service name) - :limit-name (-> rejected ::name name) - :limit-strategy (-> rejected ::strategy name))) + (when rejected + (l/warn :hint "rejected rate limit" + :user-id (str user-id) + :limit-service (-> rejected ::service name) + :limit-name (-> rejected ::name name) + :limit-strategy (-> rejected ::strategy name))) - {:enabled? true - :allowed? (not (some? rejected)) - :headers {"x-rate-limit-remaining" remaining - "x-rate-limit-reset" reset}}))))) + {:enabled? true + :allowed? (not (some? rejected)) + :headers {"x-rate-limit-remaining" remaining + "x-rate-limit-reset" reset}}))))) (defn- handle-response [f cfg params result] (if (:enabled? result) (let [headers (:headers result)] - (when-not (:allowed? result) - (ex/raise :type :rate-limit - :code :request-blocked - :hint "rate limit reached" - ::http/headers headers)) - (-> (f cfg params) - (p/then (fn [response] - (vary-meta response update ::http/headers merge headers))))) + (if (:allowed? result) + (->> (f cfg params) + (p/fmap (fn [response] + (vary-meta response update ::http/headers merge headers)))) + (p/rejected + (ex/error :type :rate-limit + :code :request-blocked + :hint "rate limit reached" + ::http/headers headers)))) (f cfg params))) +(defn- get-limits + [state skey sname] + (some->> (or (get-in @state [::limits skey]) + (get-in @state [::limits :default])) + (map #(assoc % ::service sname)) + (seq))) + +(defn- get-uid + [{:keys [::http/request] :as params}] + (or (::rpc/profile-id params) + (some-> request parse-client-ip) + uuid/zero)) + (defn wrap [{:keys [rlimit redis] :as cfg} f mdata] (if rlimit (let [skey (keyword (::rpc/type cfg) (->> mdata ::sv/spec name)) sname (str (::rpc/type cfg) "." (->> mdata ::sv/spec name))] - (fn [cfg {:keys [::http/request] :as params}] - (let [uid (or (:profile-id params) - (some-> request parse-client-ip) - uuid/zero) - rsp (when (and uid @enabled?) - (when-let [limits (or (get-in @rlimit [::limits skey]) - (get-in @rlimit [::limits :default]))] - (let [redis (redis/get-or-connect redis ::rlimit default-options) - limits (map #(assoc % ::service sname) limits) - resp (-> (process-limits redis uid limits (dt/now)) - (p/catch (fn [cause] - ;; If we have an error on processing the rate-limit we just skip - ;; it for do not cause service interruption because of redis - ;; downtime or similar situation. - (l/error :hint "error on processing rate-limit" :cause cause) - {:enabled? false})))] + (fn [cfg params] + (if @enabled? + (try + (let [uid (get-uid params) + rsp (when-let [limits (get-limits rlimit skey sname)] + (let [redis (redis/get-or-connect redis ::rpc/rlimit default-options) + rsp (->> (process-limits! redis uid limits (dt/now)) + (p/merr (fn [cause] + ;; If we have an error on processing the rate-limit we just skip + ;; it for do not cause service interruption because of redis + ;; downtime or similar situation. + (l/error :hint "error on processing rate-limit" :cause cause) + (p/resolved {:enabled? false}))))] - ;; If soft rate are enabled, we process the rate-limit but return unprotected - ;; response. - (if (contains? cf/flags :soft-rpc-rlimit) - (p/resolved {:enabled? false}) - resp)))) + ;; If soft rate are enabled, we process the rate-limit but return unprotected + ;; response. + (if (contains? cf/flags :soft-rpc-rlimit) + {:enabled? false} + rsp)))] - rsp (or rsp (p/resolved {:enabled? false}))] + (->> (p/promise rsp) + (p/fmap #(or % {:enabled? false})) + (p/mcat #(handle-response f cfg params %)))) - (p/then rsp (partial handle-response f cfg params))))) + (catch Throwable cause + (p/rejected cause))) + + (f cfg params)))) f)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; From 685a071e87d3646bc21e127180dd7e952fa51aa1 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 19 Jan 2023 15:47:25 +0100 Subject: [PATCH 35/40] :bug: Fix rounding error with matrices --- common/src/app/common/geom/shapes/transforms.cljc | 10 +++++++++- frontend/src/app/main/data/workspace/modifiers.cljs | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index c3035df27..cbff62e3a 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -238,7 +238,15 @@ points-transform-mtx (gmt/translate-matrix center))) - transform-inverse (when transform (gmt/inverse transform))] + transform-inverse (when transform (gmt/inverse transform)) + + ;; There is a rounding error when the matrix returned have float point values + ;; when the matrix is unit we return a "pure" matrix so we don't accumulate + ;; rounding problems + [transform transform-inverse] + (if (gmt/unit? transform) + [(gmt/matrix) (gmt/matrix)] + [transform transform-inverse])] [sr transform transform-inverse])) diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 717dfa7fe..de4782c4a 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -219,7 +219,7 @@ result (let [[id text-modifier] (first modifiers)] (recur (rest modifiers) - (update result id apply-text-modifier text-modifier)))))) + (d/update-when result id apply-text-modifier text-modifier)))))) #_(defn apply-path-modifiers [objects path-modifiers] From 6a257503aef3719c7d2fcdf85c2850ac2a7a7ed7 Mon Sep 17 00:00:00 2001 From: Eva Date: Thu, 19 Jan 2023 14:34:16 +0100 Subject: [PATCH 36/40] :bug: Fix create layout over mask destroy mask --- frontend/src/app/main/data/workspace/shape_layout.cljs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index d16e28850..85a429a53 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -155,10 +155,12 @@ single? (= (count selected-shapes) 1) has-group? (->> selected-shapes (d/seek cph/group-shape?)) is-group? (and single? has-group?) + has-mask? (->> selected-shapes (d/seek cph/mask-shape?)) + is-mask? (and single? has-mask?) has-component? (some true? (map ctc/instance-root? selected-shapes)) is-component? (and single? has-component?)] - (if (and (not is-component?) is-group?) + (if (and (not is-component?) is-group? (not is-mask?)) (let [new-shape-id (uuid/next) parent-id (:parent-id (first selected-shapes)) shapes-ids (:shapes (first selected-shapes)) From 40195a4f520c73903051d52cda6c26464bcb805a Mon Sep 17 00:00:00 2001 From: Eva Date: Thu, 19 Jan 2023 14:35:20 +0100 Subject: [PATCH 37/40] :bug: Fix index on layout created over group --- common/src/app/common/pages/helpers.cljc | 10 ++++++++++ frontend/src/app/main/data/workspace/shape_layout.cljs | 5 +++-- frontend/src/app/main/data/workspace/shapes.cljs | 9 ++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index bdc5a781f..973c1a714 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -353,6 +353,16 @@ (filter (comp (into #{} ids) second)) (map second))) +(defn get-index-replacement + "Given a collection of shapes, calculate their positions + in the parent, find first index and return next one" + [shapes objects] + (->> shapes + (order-by-indexed-shapes objects) + first + (get-position-on-parent objects) + inc)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SHAPES ORGANIZATION (PATH MANAGEMENT) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 85a429a53..fcf8f4dbf 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -165,11 +165,12 @@ parent-id (:parent-id (first selected-shapes)) shapes-ids (:shapes (first selected-shapes)) ordered-ids (into (d/ordered-set) shapes-ids) - undo-id (js/Symbol)] + undo-id (js/Symbol) + group-index (cph/get-index-replacement selected objects)] (rx/of (dwu/start-undo-transaction undo-id) (dwse/select-shapes ordered-ids) - (dws/create-artboard-from-selection new-shape-id parent-id) + (dws/create-artboard-from-selection new-shape-id parent-id group-index) (cl/remove-all-fills [new-shape-id] {:color clr/black :opacity 1}) (create-layout-from-id [new-shape-id] type) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index c6de6aa21..a8551942d 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -359,6 +359,8 @@ ([id] (create-artboard-from-selection id nil)) ([id parent-id] + (create-artboard-from-selection id parent-id nil)) + ([id parent-id index] (ptk/reify ::create-artboard-from-selection ptk/WatchEvent (watch [_ state _] @@ -367,11 +369,8 @@ selected (wsh/lookup-selected state) selected (cph/clean-loops objects selected) selected-objs (map #(get objects %) selected) - new-index (->> selected - (cph/order-by-indexed-shapes objects) - first - (cph/get-position-on-parent objects) - inc)] + new-index (or index + (cph/get-index-replacement selected objects))] (when (d/not-empty? selected) (let [srect (gsh/selection-rect selected-objs) frame-id (get-in objects [(first selected) :frame-id]) From dc89610d07243fd2edd03705d5b4d361faf8ae8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Thu, 19 Jan 2023 16:40:27 +0100 Subject: [PATCH 38/40] :bug: Avoid creating component with shapes that belong to other one --- .../src/app/main/ui/workspace/context_menu.cljs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index ac119cefe..9fc5c2a06 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -10,6 +10,7 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.pages.helpers :as cph] + [app.common.types.component :as ctk] [app.common.types.components-list :as ctkl] [app.common.types.file :as ctf] [app.common.types.page :as ctp] @@ -398,6 +399,7 @@ has-component? (some true? (map #(contains? % :component-id) shapes)) is-component? (and single? (-> shapes first :component-id some?)) + is-non-root? (and single? (ctk/in-component-instance-not-root? (first shapes))) shape-id (-> shapes first :id) component-id (-> shapes first :component-id) @@ -452,10 +454,12 @@ :on-accept do-update-component-in-bulk}))] [:* [:* - [:& menu-separator] - [:& menu-entry {:title (tr "workspace.shape.menu.create-component") - :shortcut (sc/get-tooltip :create-component) - :on-click do-add-component}] + (when (or (not is-non-root?) (and has-component? (not single?))) + [:& menu-separator]) + (when-not is-non-root? + [:& menu-entry {:title (tr "workspace.shape.menu.create-component") + :shortcut (sc/get-tooltip :create-component) + :on-click do-add-component}]) (when (and has-component? (not single?)) [:* [:& menu-entry {:title (tr "workspace.shape.menu.detach-instances-in-bulk") @@ -468,7 +472,6 @@ ;; WARNING: this menu is the same as the context menu at the sidebar. ;; If you change it, you must change equally the file ;; app/main/ui/workspace/sidebar/options/menus/component.cljs - [:* [:& menu-separator] (if main-component? From 8c6f07ab65dce5cedef949a2c85a37ae425a374f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Thu, 19 Jan 2023 16:54:30 +0100 Subject: [PATCH 39/40] :bug: Fix right sidebar component options menu --- .../main/ui/workspace/sidebar/options/menus/component.cljs | 3 ++- .../app/main/ui/workspace/sidebar/options/shapes/frame.cljs | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index d78a034f0..0c3238ea9 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -36,6 +36,7 @@ main-instance? (if components-v2 (:main-instance? values) true) + main-component? (:main-instance? values) local-component? (= library-id current-file-id) workspace-data (deref refs/workspace-data) workspace-libraries (deref refs/workspace-libraries) @@ -101,7 +102,7 @@ [:& context-menu {:on-close on-menu-close :show (:menu-open @local) :options - (if main-instance? + (if main-component? [[(tr "workspace.shape.menu.show-in-assets") do-show-in-assets]] (if local-component? (if is-dangling? diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs index 0fe040b7b..6656c66bc 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/frame.cljs @@ -11,6 +11,7 @@ [app.main.refs :as refs] [app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]] [app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]] + [app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]] [app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]] [app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs-shape fill-menu]] [app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]] @@ -33,6 +34,7 @@ constraint-values (select-keys shape constraint-attrs) layout-container-values (select-keys shape layout-container-flex-attrs) layout-item-values (select-keys shape layout-item-attrs) + [comp-ids comp-values] [[(:id shape)] (select-keys shape component-attrs)] is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids)) is-layout-child? (mf/deref is-layout-child-ref) @@ -42,6 +44,9 @@ :values measure-values :type type :shape shape}] + [:& component-menu {:ids comp-ids + :values comp-values + :shape-name (:name shape)}] (when (not is-layout-child?) [:& constraints-menu {:ids ids :values constraint-values}]) From 8b377ac556f44e558b0b14b22037a2791c7853f3 Mon Sep 17 00:00:00 2001 From: Eva Date: Thu, 19 Jan 2023 19:33:00 +0100 Subject: [PATCH 40/40] :lipstick: Add entry on changes --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 9a93fecde..33750acfb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -45,6 +45,7 @@ - Fix undo ungroup (shift+g) scrambles positions [Taiga #4674](https://tree.taiga.io/project/penpot/issue/4674) - Fix justified text is stretched [Github #2539](https://github.com/penpot/penpot/issues/2539) - Fix mousewheel on viewer inspector [Taiga #4221](https://tree.taiga.io/project/penpot/issue/4221) +- Fix path edition activated on boards [Taiga #4105](https://tree.taiga.io/project/penpot/issue/4105) ## 1.16.2-beta