diff --git a/CHANGES.md b/CHANGES.md index cc0f73b625..f4c1e99d62 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,12 @@ ### :bug: Bugs fixed +- Don't allow registry with email and password, if password login is disabled (invitation workflow) [Github #4975](https://github.com/penpot/penpot/issues/4975) + +## 2.1.2 + +### :bug: Bugs fixed + - User switch language to "zh_hant" will get 400 [Github #4884](https://github.com/penpot/penpot/issues/4884) - Smtp config ignoring port if ssl is set [Github #4872](https://github.com/penpot/penpot/issues/4872) - Ability to let users to authenticate with a private oidc provider only [Github #4963](https://github.com/penpot/penpot/issues/4963) diff --git a/backend/src/app/rpc/commands/auth.clj b/backend/src/app/rpc/commands/auth.clj index 20a25e9f83..3adac1f55b 100644 --- a/backend/src/app/rpc/commands/auth.clj +++ b/backend/src/app/rpc/commands/auth.clj @@ -180,10 +180,11 @@ (defn- validate-register-attempt! [cfg params] - (when-not (contains? cf/flags :registration) - (when-not (contains? params :invitation-token) - (ex/raise :type :restriction - :code :registration-disabled))) + (when (or + (not (contains? cf/flags :registration)) + (not (contains? cf/flags :login-with-password))) + (ex/raise :type :restriction + :code :registration-disabled)) (when (contains? params :invitation-token) (let [invitation (tokens/verify (::setup/props cfg) @@ -282,6 +283,7 @@ is-demo (:is-demo params false) is-muted (:is-muted params false) is-active (:is-active params false) + theme (:theme params nil) email (str/lower email) params {:id id @@ -292,6 +294,7 @@ :password password :deleted-at (:deleted-at params) :props props + :theme theme :is-active is-active :is-muted is-muted :is-demo is-demo}] @@ -347,11 +350,13 @@ :extra-data ptoken}))) (defn register-profile - [{:keys [::db/conn] :as cfg} {:keys [token fullname] :as params}] - (let [claims (tokens/verify (::setup/props cfg) {:token token :iss :prepared-register}) + [{:keys [::db/conn] :as cfg} {:keys [token fullname theme] :as params}] + (let [theme (when (= theme "light") theme) + claims (tokens/verify (::setup/props cfg) {:token token :iss :prepared-register}) params (-> claims (into params) - (assoc :fullname fullname)) + (assoc :fullname fullname) + (assoc :theme theme)) profile (if-let [profile-id (:profile-id claims)] (profile/get-profile conn profile-id) @@ -456,7 +461,8 @@ (def schema:register-profile [:map {:title "register-profile"} [:token schema:token] - [:fullname [::sm/word-string {:max 100}]]]) + [:fullname [::sm/word-string {:max 100}]] + [:theme {:optional true} [:string {:max 10}]]]) (sv/defmethod ::register-profile {::rpc/auth false diff --git a/backend/src/app/rpc/commands/verify_token.clj b/backend/src/app/rpc/commands/verify_token.clj index 95f266d6ee..67b5425b77 100644 --- a/backend/src/app/rpc/commands/verify_token.clj +++ b/backend/src/app/rpc/commands/verify_token.clj @@ -8,6 +8,7 @@ (:require [app.common.exceptions :as ex] [app.common.schema :as sm] + [app.config :as cf] [app.db :as db] [app.db.sql :as-alias sql] [app.http.session :as session] @@ -156,11 +157,12 @@ :code :invalid-invitation-token :hint "invitation token contains unexpected data")) - (let [invitation (db/get* conn :team-invitation - {:team-id team-id :email-to member-email}) - profile (db/get* conn :profile - {:id profile-id} - {:columns [:id :email]})] + (let [invitation (db/get* conn :team-invitation + {:team-id team-id :email-to member-email}) + profile (db/get* conn :profile + {:id profile-id} + {:columns [:id :email]}) + registration-disabled? (not (contains? cf/flags :registration))] (when (nil? invitation) (ex/raise :type :validation :code :invalid-token @@ -189,12 +191,12 @@ :hint "logged-in user does not matches the invitation")) ;; If we have not logged-in user, and invitation comes with member-id we - ;; redirect user to login, if no memeber-id is present in the invitation - ;; token, we redirect user the the register page. + ;; redirect user to login, if no memeber-id is present and in the invitation + ;; token and registration is enabled, we redirect user the the register page. {:invitation-token token :iss :team-invitation - :redirect-to (if member-id :auth-login :auth-register) + :redirect-to (if (or member-id registration-disabled?) :auth-login :auth-register) :state :pending}))) ;; --- Default diff --git a/backend/test/backend_tests/rpc_profile_test.clj b/backend/test/backend_tests/rpc_profile_test.clj index 7a90c9a817..1bd49db485 100644 --- a/backend/test/backend_tests/rpc_profile_test.clj +++ b/backend/test/backend_tests/rpc_profile_test.clj @@ -505,6 +505,54 @@ (t/is (nil? (:error out))) (t/is (= 0 (:call-count @mock)))))))) +(t/deftest prepare-and-register-with-invitation-and-enabled-registration-1 + (let [sprops (:app.setup/props th/*system*) + itoken (tokens/generate sprops + {:iss :team-invitation + :exp (dt/in-future "48h") + :role :editor + :team-id uuid/zero + :member-email "user@example.com"}) + data {::th/type :prepare-register-profile + :invitation-token itoken + :email "user@example.com" + :password "foobar"} + + {:keys [result error] :as out} (th/command! data)] + (t/is (nil? error)) + (t/is (map? result)) + (t/is (string? (:token result))) + + (let [rtoken (:token result) + data {::th/type :register-profile + :token rtoken + :fullname "foobar"} + + {:keys [result error] :as out} (th/command! data)] + ;; (th/print-result! out) + (t/is (nil? error)) + (t/is (map? result)) + (t/is (string? (:invitation-token result)))))) + +(t/deftest prepare-and-register-with-invitation-and-enabled-registration-2 + (let [sprops (:app.setup/props th/*system*) + itoken (tokens/generate sprops + {:iss :team-invitation + :exp (dt/in-future "48h") + :role :editor + :team-id uuid/zero + :member-email "user2@example.com"}) + + data {::th/type :prepare-register-profile + :invitation-token itoken + :email "user@example.com" + :password "foobar"} + out (th/command! data)] + + (t/is (not (th/success? out))) + (let [edata (-> out :error ex-data)] + (t/is (= :restriction (:type edata))) + (t/is (= :email-does-not-match-invitation (:code edata)))))) (t/deftest prepare-and-register-with-invitation-and-disabled-registration-1 (with-redefs [app.config/flags [:disable-registration]] @@ -519,22 +567,12 @@ :invitation-token itoken :email "user@example.com" :password "foobar"} + out (th/command! data)] - {:keys [result error] :as out} (th/command! data)] - (t/is (nil? error)) - (t/is (map? result)) - (t/is (string? (:token result))) - - (let [rtoken (:token result) - data {::th/type :register-profile - :token rtoken - :fullname "foobar"} - - {:keys [result error] :as out} (th/command! data)] - ;; (th/print-result! out) - (t/is (nil? error)) - (t/is (map? result)) - (t/is (string? (:invitation-token result))))))) + (t/is (not (th/success? out))) + (let [edata (-> out :error ex-data)] + (t/is (= :restriction (:type edata))) + (t/is (= :registration-disabled (:code edata))))))) (t/deftest prepare-and-register-with-invitation-and-disabled-registration-2 (with-redefs [app.config/flags [:disable-registration]] @@ -555,7 +593,28 @@ (t/is (not (th/success? out))) (let [edata (-> out :error ex-data)] (t/is (= :restriction (:type edata))) - (t/is (= :email-does-not-match-invitation (:code edata))))))) + (t/is (= :registration-disabled (:code edata))))))) + +(t/deftest prepare-and-register-with-invitation-and-disabled-login-with-password + (with-redefs [app.config/flags [:disable-login-with-password]] + (let [sprops (:app.setup/props th/*system*) + itoken (tokens/generate sprops + {:iss :team-invitation + :exp (dt/in-future "48h") + :role :editor + :team-id uuid/zero + :member-email "user2@example.com"}) + + data {::th/type :prepare-register-profile + :invitation-token itoken + :email "user@example.com" + :password "foobar"} + out (th/command! data)] + + (t/is (not (th/success? out))) + (let [edata (-> out :error ex-data)] + (t/is (= :restriction (:type edata))) + (t/is (= :registration-disabled (:code edata))))))) (t/deftest prepare-register-with-registration-disabled (with-redefs [app.config/flags #{}] diff --git a/docker/devenv/docker-compose.yaml b/docker/devenv/docker-compose.yaml index 0d6aa068f4..f4e9b0e792 100644 --- a/docker/devenv/docker-compose.yaml +++ b/docker/devenv/docker-compose.yaml @@ -125,3 +125,7 @@ services: ports: - "10389:10389" - "10636:10636" + ulimits: + nofile: + soft: "1024" + hard: "1024" \ No newline at end of file diff --git a/docker/images/files/nginx.conf b/docker/images/files/nginx.conf index 8d0fff0a24..fee0e3fca6 100644 --- a/docker/images/files/nginx.conf +++ b/docker/images/files/nginx.conf @@ -38,7 +38,10 @@ http { gzip_types text/plain text/css text/javascript application/javascript application/json application/transit+json; - resolver $PENPOT_INTERNAL_RESOLVER; + proxy_buffer_size 16k; + proxy_busy_buffers_size 24k; # essentially, proxy_buffer_size + 2 small buffers of 4k + proxy_buffers 32 4k; + resolver $PENPOT_INTERNAL_RESOLVER ipv6=off; map $http_upgrade $connection_upgrade { default upgrade; diff --git a/frontend/src/app/main/data/users.cljs b/frontend/src/app/main/data/users.cljs index 1a61a0644d..6cc9c66073 100644 --- a/frontend/src/app/main/data/users.cljs +++ b/frontend/src/app/main/data/users.cljs @@ -19,6 +19,7 @@ [app.main.data.websocket :as ws] [app.main.features :as features] [app.main.repo :as rp] + [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.router :as rt] [app.util.storage :refer [storage]] @@ -135,7 +136,8 @@ (swap! storage assoc :profile profile) (i18n/set-locale! (:lang profile)) (when (not= previous-email email) - (set-current-team! nil))))))) + (set-current-team! nil)) + (dom/set-html-theme-color (or (:theme profile) "default"))))))) (defn fetch-profile [] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index b230569aba..dfb18f0d63 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -47,7 +47,6 @@ [app.main.data.workspace.collapse :as dwco] [app.main.data.workspace.drawing :as dwd] [app.main.data.workspace.edition :as dwe] - [app.main.data.workspace.fix-bool-contents :as fbc] [app.main.data.workspace.fix-broken-shapes :as fbs] [app.main.data.workspace.fix-deleted-fonts :as fdf] [app.main.data.workspace.groups :as dwg] @@ -129,7 +128,6 @@ (when (and (not (boolean (-> state :profile :props :v2-info-shown))) (features/active-feature? state "components/v2")) (modal/show :v2-info {})) - (fbc/fix-bool-contents) (fdf/fix-deleted-fonts) (fbs/fix-broken-shapes))))) diff --git a/frontend/src/app/main/data/workspace/fix_bool_contents.cljs b/frontend/src/app/main/data/workspace/fix_bool_contents.cljs deleted file mode 100644 index 5cb1c493af..0000000000 --- a/frontend/src/app/main/data/workspace/fix_bool_contents.cljs +++ /dev/null @@ -1,95 +0,0 @@ -;; 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.main.data.workspace.fix-bool-contents - (:require - [app.common.data :as d] - [app.common.geom.shapes :as gsh] - [app.main.data.changes :as dch] - [app.main.data.workspace.shapes :as dwsh] - [app.main.data.workspace.state-helpers :as wsh] - [beicon.v2.core :as rx] - [potok.v2.core :as ptk])) - -;; This event will update the file so the boolean data has a pre-generated path data -;; to increase performance. -;; For new shapes this will be generated in the :reg-objects but we need to do this for -;; old files. - -;; FIXME: Remove me after June 2022 - -(defn fix-bool-contents - "This event will calculate the bool content and update the page. This is kind of a 'addhoc' migration - to fill the optional value 'bool-content'" - [] - - (letfn [(should-migrate-shape? [shape] - (and (= :bool (:type shape)) (not (contains? shape :bool-content)))) - - (should-migrate-component? [component] - (->> (:objects component) - (vals) - (d/seek should-migrate-shape?))) - - (update-shape [shape objects] - (cond-> shape - (should-migrate-shape? shape) - (assoc :bool-content (gsh/calc-bool-content shape objects)))) - - (migrate-component [component] - (-> component - (update - :objects - (fn [objects] - (d/mapm #(update-shape %2 objects) objects))))) - - (update-library - [library] - (-> library - (d/update-in-when - [:data :components] - (fn [components] - (d/mapm #(migrate-component %2) components)))))] - - (ptk/reify ::fix-bool-contents - ptk/UpdateEvent - (update [_ state] - ;; Update (only-local) the imported libraries - (-> state - (d/update-when - :workspace-libraries - (fn [libraries] (d/mapm #(update-library %2) libraries))))) - - ptk/WatchEvent - (watch [it state _] - (let [objects (wsh/lookup-page-objects state) - - ids (into #{} - (comp (filter should-migrate-shape?) (map :id)) - (vals objects)) - - components (->> (wsh/lookup-local-components state) - (vals) - (filter should-migrate-component?)) - - component-changes - (into [] - (map (fn [component] - {:type :mod-component - :id (:id component) - :objects (-> component migrate-component :objects)})) - components)] - - (rx/of (dwsh/update-shapes ids #(update-shape % objects) {:reg-objects? false - :save-undo? false - :ignore-tree true})) - - (if (empty? component-changes) - (rx/empty) - (rx/of (dch/commit-changes {:origin it - :redo-changes component-changes - :undo-changes [] - :save-undo? false})))))))) diff --git a/frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs b/frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs index f79db68675..75f7c83d2f 100644 --- a/frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs +++ b/frontend/src/app/main/data/workspace/fix_deleted_fonts.cljs @@ -6,11 +6,9 @@ (ns app.main.data.workspace.fix-deleted-fonts (:require - [app.common.data :as d] [app.common.files.helpers :as cfh] [app.common.text :as txt] [app.main.data.changes :as dwc] - [app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.state-helpers :as wsh] [app.main.fonts :as fonts] [beicon.v2.core :as rx] @@ -22,14 +20,7 @@ ;; - Moving files from one team to another in the same instance ;; - Custom fonts are explicitly deleted in the team area -(defn has-invalid-font-family - [node] - (let [fonts (deref fonts/fontsdb)] - (and - (some? (:font-family node)) - (nil? (get fonts (:font-id node)))))) - -(defn calculate-alternative-font-id +(defn- calculate-alternative-font-id [value] (let [fonts (deref fonts/fontsdb)] (->> (vals fonts) @@ -37,39 +28,44 @@ (first) :id))) -(defn should-fix-deleted-font-shape? +(defn- has-invalid-font-family? + [node] + (let [fonts (deref fonts/fontsdb) + font-family (:font-family node) + alternative-font-id (calculate-alternative-font-id font-family)] + (and (some? font-family) + (nil? (get fonts (:font-id node))) + (some? alternative-font-id)))) + +(defn- should-fix-deleted-font-shape? [shape] (let [text-nodes (txt/node-seq txt/is-text-node? (:content shape))] - (and (cfh/text-shape? shape) (some has-invalid-font-family text-nodes)))) + (and (cfh/text-shape? shape) + (some has-invalid-font-family? text-nodes)))) -(defn should-fix-deleted-font-component? +(defn- should-fix-deleted-font-component? [component] - (->> (:objects component) - (vals) - (d/seek should-fix-deleted-font-shape?))) + (let [xf (comp (map val) + (filter should-fix-deleted-font-shape?))] + (first (sequence xf (:objects component))))) -(defn should-fix-deleted-font-typography? - [typography] - (let [fonts (deref fonts/fontsdb)] - (nil? (get fonts (:font-id typography))))) - -(defn fix-deleted-font +(defn- fix-deleted-font [node] (let [alternative-font-id (calculate-alternative-font-id (:font-family node))] (cond-> node (some? alternative-font-id) (assoc :font-id alternative-font-id)))) -(defn fix-deleted-font-shape +(defn- fix-deleted-font-shape [shape] - (let [transform (partial txt/transform-nodes has-invalid-font-family fix-deleted-font)] + (let [transform (partial txt/transform-nodes has-invalid-font-family? fix-deleted-font)] (update shape :content transform))) -(defn fix-deleted-font-component +(defn- fix-deleted-font-component [component] (update component :objects (fn [objects] - (d/mapm #(fix-deleted-font-shape %2) objects)))) + (update-vals objects fix-deleted-font-shape)))) (defn fix-deleted-font-typography [typography] @@ -77,54 +73,60 @@ (cond-> typography (some? alternative-font-id) (assoc :font-id alternative-font-id)))) +(defn- generate-deleted-font-shape-changes + [{:keys [objects id]}] + (sequence + (comp (map val) + (filter should-fix-deleted-font-shape?) + (map (fn [shape] + {:type :mod-obj + :id (:id shape) + :page-id id + :operations [{:type :set + :attr :content + :val (:content (fix-deleted-font-shape shape))} + {:type :set + :attr :position-data + :val nil}]}))) + objects)) + +(defn- generate-deleted-font-components-changes + [state] + (sequence + (comp (map val) + (filter should-fix-deleted-font-component?) + (map (fn [component] + {:type :mod-component + :id (:id component) + :objects (-> (fix-deleted-font-component component) :objects)}))) + (wsh/lookup-local-components state))) + +(defn- generate-deleted-font-typography-changes + [state] + (sequence + (comp (map val) + (filter has-invalid-font-family?) + (map (fn [typography] + {:type :mod-typography + :typography (fix-deleted-font-typography typography)}))) + (get-in state [:workspace-data :typographies]))) + (defn fix-deleted-fonts [] (ptk/reify ::fix-deleted-fonts ptk/WatchEvent (watch [it state _] - (let [objects (wsh/lookup-page-objects state) - - ids (into #{} - (comp (filter should-fix-deleted-font-shape?) (map :id)) - (vals objects)) - - components (->> (wsh/lookup-local-components state) - (vals) - (filter should-fix-deleted-font-component?)) - - component-changes - (into [] - (map (fn [component] - {:type :mod-component - :id (:id component) - :objects (-> (fix-deleted-font-component component) :objects)})) - components) - - typographies (->> (get-in state [:workspace-data :typographies]) - (vals) - (filter should-fix-deleted-font-typography?)) - - typography-changes - (into [] - (map (fn [typography] - {:type :mod-typography - :typography (fix-deleted-font-typography typography)})) - typographies)] - - (rx/concat - (rx/of (dwsh/update-shapes ids #(fix-deleted-font-shape %) {:reg-objects? false - :save-undo? false - :ignore-tree true})) - (if (empty? component-changes) - (rx/empty) - (rx/of (dwc/commit-changes {:origin it - :redo-changes component-changes - :undo-changes [] - :save-undo? false}))) - - (if (empty? typography-changes) - (rx/empty) - (rx/of (dwc/commit-changes {:origin it - :redo-changes typography-changes - :undo-changes [] - :save-undo? false})))))))) + (let [data (get state :workspace-data) + shape-changes (mapcat generate-deleted-font-shape-changes (vals (:pages-index data))) + components-changes (generate-deleted-font-components-changes state) + typography-changes (generate-deleted-font-typography-changes state) + changes (concat shape-changes + components-changes + typography-changes)] + (if (seq changes) + (rx/of (dwc/commit-changes + {:origin it + :redo-changes (vec changes) + :undo-changes [] + :save-undo? false})) + (rx/empty)))))) diff --git a/frontend/src/app/main/ui/auth.cljs b/frontend/src/app/main/ui/auth.cljs index 42db83794d..bec7eccd52 100644 --- a/frontend/src/app/main/ui/auth.cljs +++ b/frontend/src/app/main/ui/auth.cljs @@ -30,26 +30,27 @@ (not= section :auth-register-success)) params (:query-params route) error (:error params) - hide-image-auth? (cf/external-feature-flag "signup-01" "test")] + default-light? (cf/external-feature-flag "onboarding-02" "test")] (mf/with-effect [] (dom/set-html-title (tr "title.default"))) + (mf/with-effect [default-light?] + (when default-light? + (dom/set-html-theme-color "light"))) + (mf/with-effect [error] (when error (st/emit! (du/show-redirect-error error)))) - [:main {:class (stl/css-case :auth-section (not hide-image-auth?) - :auth-section-hide-image hide-image-auth?)} + [:main {:class (stl/css :auth-section)} (when show-login-icon [:h1 {:class (stl/css :logo-container)} [:a {:href "#/" :title "Penpot" :class (stl/css :logo-btn)} i/logo]]) - (when (not hide-image-auth?) - [:div {:class (stl/css :login-illustration)} - i/login-illustration]) + [:div {:class (stl/css :login-illustration)} + i/login-illustration] - [:section {:class (stl/css-case :auth-content (not hide-image-auth?) - :auth-content-hide-image hide-image-auth?)} + [:section {:class (stl/css :auth-content)} (case section :auth-register diff --git a/frontend/src/app/main/ui/auth.scss b/frontend/src/app/main/ui/auth.scss index edcb34520f..4b3caeefcf 100644 --- a/frontend/src/app/main/ui/auth.scss +++ b/frontend/src/app/main/ui/auth.scss @@ -24,24 +24,6 @@ } } -// A-B text signup-01 -.auth-section-hide-image { - position: relative; - align-items: center; - background: var(--panel-background-color); - display: grid; - gap: $s-32; - height: 100%; - padding: $s-32; - width: 100%; - overflow: auto; - - @media (max-width: 992px) { - display: flex; - justify-content: center; - } -} - .logo-container { position: absolute; top: $s-20; @@ -83,19 +65,6 @@ width: 100%; } -// A-B text signup-01 -.auth-content-hide-image { - display: grid; - grid-template-rows: 1fr auto; - gap: $s-24; - height: fit-content; - margin: auto; - max-width: $s-412; - padding-block-end: $s-8; - position: relative; - width: 100%; -} - .logo-btn { svg { width: $s-120; diff --git a/frontend/src/app/main/ui/auth/register.cljs b/frontend/src/app/main/ui/auth/register.cljs index f4788b628d..e4edd02996 100644 --- a/frontend/src/app/main/ui/auth/register.cljs +++ b/frontend/src/app/main/ui/auth/register.cljs @@ -110,7 +110,8 @@ [:& login/login-buttons {:params params}]) (when (or login/show-alt-login-buttons? (false? hide-separator)) [:hr {:class (stl/css :separator)}]) - [:& register-form {:params params :on-success-callback on-success-callback}]]) + (when (contains? cf/flags :login-with-password) + [:& register-form {:params params :on-success-callback on-success-callback}])]) (mf/defc register-page {::mf/props :obj} @@ -176,6 +177,7 @@ [{:keys [params on-success-callback]}] (let [form (fm/use-form :schema schema:register-validate-form :initial params) submitted? (mf/use-state false) + theme (when (cf/external-feature-flag "onboarding-02" "test") "light") on-success (mf/use-fn @@ -207,7 +209,8 @@ (mf/deps on-success on-error) (fn [form _] (reset! submitted? true) - (let [params (:clean-data @form)] + (let [params (cond-> (:clean-data @form) + (some? theme) (assoc :theme theme))] (->> (rp/cmd! :register-profile params) (rx/finalize #(reset! submitted? false)) (rx/subs! on-success on-error)))))] diff --git a/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs b/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs index 681dffd372..3879ba5072 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs @@ -64,24 +64,25 @@ [{:keys [grow-type id migrate] :as shape} node] ;; Check if we need to update the size because it's auto-width or auto-height ;; Update the position-data of every text fragment - (p/let [position-data (tsp/calc-position-data id)] - ;; At least one paragraph needs to be inside the bounding box - (when (gsht/overlaps-position-data? shape position-data) - (st/emit! (dwt/update-position-data id position-data))) + (->> (tsp/calc-position-data id) + (p/fmap (fn [position-data] + ;; At least one paragraph needs to be inside the bounding box + (when (gsht/overlaps-position-data? shape position-data) + (st/emit! (dwt/update-position-data id position-data))) - (when (contains? #{:auto-height :auto-width} grow-type) - (let [{:keys [width height]} - (-> (dom/query node ".paragraph-set") - (dom/get-bounding-rect)) + (when (contains? #{:auto-height :auto-width} grow-type) + (let [{:keys [width height]} + (-> (dom/query node ".paragraph-set") + (dom/get-bounding-rect)) - width (mth/ceil width) - height (mth/ceil height)] - (when (and (not (mth/almost-zero? width)) - (not (mth/almost-zero? height)) - (not migrate)) - (st/emit! (dwt/resize-text id width height))))) + width (mth/ceil width) + height (mth/ceil height)] + (when (and (not (mth/almost-zero? width)) + (not (mth/almost-zero? height)) + (not migrate)) + (st/emit! (dwt/resize-text id width height))))) - (st/emit! (dwt/clean-text-modifier id)))) + (st/emit! (dwt/clean-text-modifier id)))))) (defn- update-text-modifier [{:keys [grow-type id] :as shape} node]