From b901a10aaaf0710de4f6066533483c0d5be7e361 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 6 Jul 2022 08:13:29 +0200 Subject: [PATCH 01/34] :bug: Fix typographies grouping --- CHANGES.md | 1 + .../app/main/data/workspace/libraries.cljs | 14 +++++---- .../app/main/ui/workspace/sidebar/assets.cljs | 3 +- .../sidebar/options/menus/typography.cljs | 30 ++++++++----------- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8208c96e2..79a414a06 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ - Fix colors from unlinked libs in color selected widget [Taiga #3712](https://tree.taiga.io/project/penpot/issue/3712) - Fix fill information not complete when paste plain text [Taiga #3680](https://tree.taiga.io/project/penpot/issue/3680) - Fix problem when resizing groups [Taiga #3702](https://tree.taiga.io/project/penpot/issue/3702) +- Fix issues on typographies assets grouping [#2073](https://github.com/penpot/penpot/issues/2073) ## 1.14.1-beta diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 90a0c7a84..cc63069ce 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -233,10 +233,12 @@ (defn- do-update-tipography [it state typography file-id] - (let [data (get state :workspace-data) - changes (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/update-typography typography))] + (let [data (get state :workspace-data) + [path name] (cph/parse-path-name (:name typography)) + typography (assoc typography :path path :name name) + changes (-> (pcb/empty-changes it) + (pcb/with-library-data data) + (pcb/update-typography typography))] (rx/of (dwu/start-undo-transaction) (dch/commit-changes changes) (sync-file (:current-file-id state) file-id) @@ -259,9 +261,9 @@ (ptk/reify ::rename-typography ptk/WatchEvent (watch [it state _] - (let [data (get state :workspace-data) + (let [data (get state :workspace-data) [path name] (cph/parse-path-name new-name) - object (get-in data [:typographies id]) + object (get-in data [:typographies id]) new-object (assoc object :path path :name name)] (do-update-tipography it state new-object file-id))))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 71c5fb260..1987dca1a 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -1562,7 +1562,6 @@ (fn [event] (on-drop-asset-group event dragging? prefix selected-typographies-paths selected-typographies-full move-typography)))] - [:div {:on-drag-enter on-drag-enter :on-drag-leave on-drag-leave :on-drag-over on-drag-over @@ -1588,6 +1587,7 @@ [:div.drop-space]) (for [typography typographies] [:& typography-item {:typography typography + :key (dm/str (:id typography)) :file file :local? local? :handle-change handle-change @@ -1605,6 +1605,7 @@ (when-not (empty? path-item) [:& typographies-group {:file-id file-id :prefix (cph/merge-path-item prefix path-item) + :key (dm/str path-item) :groups content :open-groups open-groups :file file diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs index ee70c8d50..c8e6da475 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/typography.cljs @@ -468,27 +468,21 @@ (fn [event] (let [name (dom/get-target-val event)] (when-not (str/blank? name) - (on-change {:name name })))))] + (on-change {:name name})))))] - (mf/use-effect - (mf/deps editing?) - (fn [] - (when editing? - (reset! open? editing?)))) + (mf/with-effect [editing?] + (when editing? + (reset! open? editing?))) - (mf/use-effect - (mf/deps focus-name?) - (fn [] - (when focus-name? - (tm/schedule - #(when-let [node (mf/ref-val name-input-ref)] - (dom/focus! node) - (dom/select-text! node)))))) + (mf/with-effect [focus-name?] + (when focus-name? + (tm/schedule + #(when-let [node (mf/ref-val name-input-ref)] + (dom/focus! node) + (dom/select-text! node))))) - (mf/use-effect - (mf/deps on-change) - (fn [] - (mf/set-ref-val! on-change-ref {:on-change on-change}))) + (mf/with-effect [on-change] + (mf/set-ref-val! on-change-ref {:on-change on-change})) [:* [:div.element-set-options-group.typography-entry From 46c9fc1c5f641479b37de4315f8879b6ce9e9baf Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 27 Jun 2022 14:21:45 +0200 Subject: [PATCH 02/34] :bug: Normalize return value from parse-client-ip function --- backend/src/app/loggers/audit.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/app/loggers/audit.clj b/backend/src/app/loggers/audit.clj index 26e86a0aa..bb8b784ec 100644 --- a/backend/src/app/loggers/audit.clj +++ b/backend/src/app/loggers/audit.clj @@ -32,7 +32,7 @@ [request] (or (some-> (yrq/get-header request "x-forwarded-for") (str/split ",") first) (yrq/get-header request "x-real-ip") - (yrq/remote-addr request))) + (some-> (yrq/remote-addr request) str))) (defn extract-utm-params "Extracts additional data from params and namespace them under From 06905d5fa6d30c892e8adf3222e3ac92de0ea5d9 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 13 Jul 2022 11:02:33 +0200 Subject: [PATCH 03/34] :bug: Fix SVG texts positioning inconsistencies --- CHANGES.md | 1 + frontend/src/app/main/ui/shapes/text/svg_text.cljs | 10 ++-------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 79a414a06..15390b086 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ - Fix fill information not complete when paste plain text [Taiga #3680](https://tree.taiga.io/project/penpot/issue/3680) - Fix problem when resizing groups [Taiga #3702](https://tree.taiga.io/project/penpot/issue/3702) - Fix issues on typographies assets grouping [#2073](https://github.com/penpot/penpot/issues/2073) +- Fix text positioning inconsistencies between browsers ## 1.14.1-beta diff --git a/frontend/src/app/main/ui/shapes/text/svg_text.cljs b/frontend/src/app/main/ui/shapes/text/svg_text.cljs index 4c8054c24..5ee933815 100644 --- a/frontend/src/app/main/ui/shapes/text/svg_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/svg_text.cljs @@ -11,7 +11,6 @@ [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] - [app.config :as cfg] [app.main.ui.context :as muc] [app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.custom-stroke :refer [shape-custom-strokes]] @@ -87,18 +86,13 @@ [:> :g group-props (for [[index data] (d/enumerate position-data)] - (let [y (if (cfg/check-browser? :safari) - (- (:y data) (:height data)) - (:y data)) - - alignment-bl (when (cfg/check-browser? :safari) "text-before-edge") - dominant-bl (when-not (cfg/check-browser? :safari) "ideographic") + (let [y (- (:y data) (:height data)) + dominant-bl "text-before-edge" rtl? (= "rtl" (:direction data)) props (-> #js {:key (dm/str "text-" (:id shape) "-" index) :x (if rtl? (+ (:x data) (:width data)) (:x data)) :y y :transform (position-data-transform shape data) - :alignmentBaseline alignment-bl :dominantBaseline dominant-bl :style (-> #js {:fontFamily (:font-family data) :fontSize (:font-size data) From 1c09328d0e26adb73b32147345c99351b65fc951 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 13 Jul 2022 11:20:32 +0200 Subject: [PATCH 04/34] :paperclip: Update version.txt file --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 398dc6c5e..a7525c96c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.14.1-beta +1.14.2-beta From 4bac2f15a2fc3d339392911ca37ca4c1dec71903 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 13 Jul 2022 11:29:22 +0200 Subject: [PATCH 05/34] :arrow_up: Use correct version of im4java (fixes tests) --- backend/deps.edn | 3 ++- backend/test/app/services_media_test.clj | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/deps.edn b/backend/deps.edn index 34e62ccb9..70e6717f0 100644 --- a/backend/deps.edn +++ b/backend/deps.edn @@ -34,7 +34,8 @@ buddy/buddy-sign {:mvn/version "3.4.333"} org.jsoup/jsoup {:mvn/version "1.14.3"} - org.im4java/im4java {:mvn/version "1.4.0"} + org.im4java/im4java {:git/tag "1.4.0-penpot-2" :git/sha "e2b3e16" + :git/url "https://github.com/penpot/im4java"} org.lz4/lz4-java {:mvn/version "1.8.0"} org.clojars.pntblnk/clj-ldap {:mvn/version "0.0.17"} diff --git a/backend/test/app/services_media_test.clj b/backend/test/app/services_media_test.clj index d0ce566b0..51e8e7d68 100644 --- a/backend/test/app/services_media_test.clj +++ b/backend/test/app/services_media_test.clj @@ -46,7 +46,8 @@ (t/is (sto/storage-object? mobj1)) (t/is (sto/storage-object? mobj2)) (t/is (= 122785 (:size mobj1))) - (t/is (= 3303 (:size mobj2))))) + (t/is (or (= 3302 (:size mobj2)) + (= 3303 (:size mobj2)))))) )) (t/deftest media-object-upload From be0c810c5fba165756630a8432d5c808098555bf Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 15 Jul 2022 08:03:06 +0200 Subject: [PATCH 06/34] :bug: Fix worker synchronize cron entries --- backend/src/app/worker.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/app/worker.clj b/backend/src/app/worker.clj index 249bfba06..39b4fd896 100644 --- a/backend/src/app/worker.clj +++ b/backend/src/app/worker.clj @@ -501,9 +501,9 @@ (db/exec-one! conn [sql:upsert-cron-task id cron cron]))) (defn- synchronize-cron-entries - [{:keys [pool schedule]}] + [{:keys [pool entries]}] (db/with-atomic [conn pool] - (run! (partial synchronize-cron-item conn) schedule))) + (run! (partial synchronize-cron-item conn) entries))) (def sql:lock-cron-task "select id from scheduled_task where id=? for update skip locked") From d16761772b0f705fb0fe4e184192caec2feb71e7 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 19 Aug 2022 11:49:45 +0200 Subject: [PATCH 07/34] :bug: Fix border radious on boolean operations --- CHANGES.md | 1 + .../app/main/ui/workspace/sidebar/options/menus/measures.cljs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index c3da69c9e..e0de21261 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -35,6 +35,7 @@ ### :bug: Bugs fixed +- Fix border radious on boolean operations [Taiga](https://tree.taiga.io/project/penpot/issue/3959) - Fix inconsistent representation of rectangles [Taiga #3977](https://tree.taiga.io/project/penpot/issue/3977) - Fix recent fonts info [Taiga #3953](https://tree.taiga.io/project/penpot/issue/3953) - Fix clipped elements affect boards and centering [Taiga #3666](https://tree.taiga.io/project/penpot/issue/3666) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index dd197446f..5a44676ba 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -174,7 +174,9 @@ (fn [shape] (if (ctsr/has-radius? shape) (update-fn shape) - shape))))) + shape)) + {:reg-objects? true + :attrs [:rx :ry :r1 :r2 :r3 :r4]}))) on-switch-to-radius-1 (mf/use-callback From 36af30385006d9ba855264e56abc05921f007a87 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 19 Aug 2022 11:52:17 +0200 Subject: [PATCH 08/34] :bug: Fix share prototypes overlay and stroke --- CHANGES.md | 3 ++- frontend/resources/styles/main/partials/share-link.scss | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index e0de21261..4bf4c81ce 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -35,7 +35,8 @@ ### :bug: Bugs fixed -- Fix border radious on boolean operations [Taiga](https://tree.taiga.io/project/penpot/issue/3959) +- Fix share prototypes overlay and stroke [Taiga #3994](https://tree.taiga.io/project/penpot/issue/3994) +- Fix border radious on boolean operations [Taiga #3959](https://tree.taiga.io/project/penpot/issue/3959) - Fix inconsistent representation of rectangles [Taiga #3977](https://tree.taiga.io/project/penpot/issue/3977) - Fix recent fonts info [Taiga #3953](https://tree.taiga.io/project/penpot/issue/3953) - Fix clipped elements affect boards and centering [Taiga #3666](https://tree.taiga.io/project/penpot/issue/3666) diff --git a/frontend/resources/styles/main/partials/share-link.scss b/frontend/resources/styles/main/partials/share-link.scss index 0a9f4c5bd..5b96657c6 100644 --- a/frontend/resources/styles/main/partials/share-link.scss +++ b/frontend/resources/styles/main/partials/share-link.scss @@ -1,4 +1,5 @@ .share-modal { + background: none; display: block; top: 50px; left: calc(100vw - 500px); @@ -6,6 +7,7 @@ .share-link-dialog { width: 480px; background-color: $color-white; + border: 1px solid $color-gray-10; .modal-content { padding: 16px 32px; From eb797f37a791eca689cdd48dd28fcd3ea531e67a Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 19 Aug 2022 12:07:11 +0200 Subject: [PATCH 09/34] :bug: Fix hide html options on handoff --- CHANGES.md | 1 + .../resources/styles/main/partials/handoff.scss | 17 ++--------------- .../src/app/main/ui/viewer/handoff/code.cljs | 12 ++---------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4bf4c81ce..225d24b97 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -35,6 +35,7 @@ ### :bug: Bugs fixed +- Fix hide html options on handoff [Taiga 3533](https://tree.taiga.io/project/penpot/issue/3533) - Fix share prototypes overlay and stroke [Taiga #3994](https://tree.taiga.io/project/penpot/issue/3994) - Fix border radious on boolean operations [Taiga #3959](https://tree.taiga.io/project/penpot/issue/3959) - Fix inconsistent representation of rectangles [Taiga #3977](https://tree.taiga.io/project/penpot/issue/3977) diff --git a/frontend/resources/styles/main/partials/handoff.scss b/frontend/resources/styles/main/partials/handoff.scss index adcb45082..a4eb7dd4f 100644 --- a/frontend/resources/styles/main/partials/handoff.scss +++ b/frontend/resources/styles/main/partials/handoff.scss @@ -330,26 +330,13 @@ } .code-row-lang { + color: $color-gray-10; position: relative; display: flex; flex-direction: row; + font-size: $fs14; margin: 0.5rem; - .code-selection { - height: 100%; - margin: 0; - padding: 0.5rem; - width: 4.5rem; - font-size: $fs12; - background: $color-gray-50; - color: $color-gray-10; - border-radius: 2px; - border: 1px solid $color-gray-30; - background-image: url("/images/icons/arrow-down-white.svg"); - background-repeat: no-repeat; - background-position: 90% 48%; - background-size: 8px; - } .expand-button, .copy-button { margin-top: 8px; diff --git a/frontend/src/app/main/ui/viewer/handoff/code.cljs b/frontend/src/app/main/ui/viewer/handoff/code.cljs index 030a443b4..265b2eba5 100644 --- a/frontend/src/app/main/ui/viewer/handoff/code.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/code.cljs @@ -72,12 +72,7 @@ [:div.element-options [:div.code-block - [:div.code-row-lang - [:select.code-selection - [:option {:value "css"} "CSS"] - #_[:option {:value "sass"} "SASS"] - #_[:option {:value "less"} "Less"] - #_[:option {:value "stylus"} "Stylus"]] + [:div.code-row-lang "CSS" [:button.expand-button {:on-click on-expand } @@ -91,10 +86,7 @@ :code style-code}]]] [:div.code-block - [:div.code-row-lang - [:select.code-selection - [:option "SVG"] - [:option "HTML"]] + [:div.code-row-lang "SVG" [:button.expand-button {:on-click on-expand} From f9502315ec670c4f351a88db11e76c2c05c2416b Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:04:25 +0200 Subject: [PATCH 10/34] :sparkles: Remove duplicate helper from page helpers --- common/src/app/common/pages/focus.cljc | 5 ++--- common/src/app/common/pages/helpers.cljc | 23 ++++++----------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/common/src/app/common/pages/focus.cljc b/common/src/app/common/pages/focus.cljc index a7ca0f495..726c102e6 100644 --- a/common/src/app/common/pages/focus.cljc +++ b/common/src/app/common/pages/focus.cljc @@ -40,6 +40,5 @@ (defn is-in-focus? [objects focus id] - (d/seek - #(contains? focus %) - (cph/get-parents-seq objects id))) + (d/seek (partial contains? focus) + (cons id (cph/get-parent-ids objects id)))) diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index fb3563c9f..3f5ef1ce4 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -96,16 +96,6 @@ [objects id] (-> objects (get id) :parent-id)) -(defn get-parents-seq - [objects shape-id] - - (cond - (nil? shape-id) - nil - - :else - (lazy-seq (cons shape-id (get-parents-seq objects (get-in objects [shape-id :parent-id])))))) - (defn get-parent-ids "Returns a vector of parents of the specified shape." [objects shape-id] @@ -220,8 +210,8 @@ (defn- get-base [objects id-a id-b] - (let [parents-a (reverse (get-parents-seq objects id-a)) - parents-b (reverse (get-parents-seq objects id-b)) + (let [parents-a (reverse (cons id-a (get-parent-ids objects id-a))) + parents-b (reverse (cons id-b (get-parent-ids objects id-b))) [base base-child-a base-child-b] (loop [parents-a (rest parents-a) @@ -648,7 +638,7 @@ (defn is-child? [objects parent-id candidate-child-id] - (let [parents (get-parents-seq objects candidate-child-id)] + (let [parents (get-parent-ids objects candidate-child-id)] (some? (d/seek #(= % parent-id) parents)))) (defn reduce-objects @@ -688,11 +678,10 @@ (defn get-shape-id-root-frame [objects shape-id] - (->> (get-parents-seq objects shape-id) + (->> (get-parent-ids objects shape-id) + (cons shape-id) (map (d/getf objects)) - (d/seek #(and (= :frame (:type %)) - (= uuid/zero (:frame-id %)))) - + (d/seek root-frame?) :id)) (defn get-viewer-frames From 9722e6ea9757cb2ad4d0ba2e6a87e0a1f0cbe159 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:05:45 +0200 Subject: [PATCH 11/34] :paperclip: Update gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 22ae73c02..b7f152cd6 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ /backend/resources/public/assets /backend/resources/public/media /backend/target/ +/backend/builtin-templates /bundle* /cd.md /clj-profiler/ From 48de242a2d723be32e5c1a40038c0eb3f05a7565 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:06:03 +0200 Subject: [PATCH 12/34] :bug: Fix z-index on viewer sidebar --- frontend/resources/styles/main/partials/viewer.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/resources/styles/main/partials/viewer.scss b/frontend/resources/styles/main/partials/viewer.scss index 0a774646f..00a0c14bc 100644 --- a/frontend/resources/styles/main/partials/viewer.scss +++ b/frontend/resources/styles/main/partials/viewer.scss @@ -164,6 +164,7 @@ top: 50px; width: 256px; height: 100%; + z-index: 10; } } From 50d371c14b305877073febf1f28e89acba5cdb69 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:22:52 +0200 Subject: [PATCH 13/34] :recycle: Refactor viewer state management (partial) --- frontend/src/app/main/data/comments.cljs | 7 + frontend/src/app/main/data/viewer.cljs | 139 ++++---- frontend/src/app/main/ui/context.cljs | 6 +- frontend/src/app/main/ui/shapes/shape.cljs | 24 +- frontend/src/app/main/ui/viewer.cljs | 326 ++++++++++-------- frontend/src/app/main/ui/viewer/handoff.cljs | 4 +- .../app/main/ui/viewer/handoff/render.cljs | 5 +- frontend/src/app/main/ui/viewer/header.cljs | 9 +- .../src/app/main/ui/viewer/interactions.cljs | 150 ++++---- frontend/src/app/main/ui/viewer/shapes.cljs | 53 ++- frontend/src/app/util/dom.cljs | 8 + 11 files changed, 434 insertions(+), 297 deletions(-) diff --git a/frontend/src/app/main/data/comments.cljs b/frontend/src/app/main/data/comments.cljs index e09d8eff8..50f6dcff0 100644 --- a/frontend/src/app/main/data/comments.cljs +++ b/frontend/src/app/main/data/comments.cljs @@ -342,6 +342,13 @@ (some? list) (assoc :list list))))))) +(defn update-options + [params] + (ptk/reify ::update-options + ptk/UpdateEvent + (update [_ state] + (update state :comments-local merge params)))) + (s/def ::create-draft-params (s/keys :req-un [::page-id ::file-id ::position])) diff --git a/frontend/src/app/main/data/viewer.cljs b/frontend/src/app/main/data/viewer.cljs index d920b7685..c8061dac6 100644 --- a/frontend/src/app/main/data/viewer.cljs +++ b/frontend/src/app/main/data/viewer.cljs @@ -7,6 +7,7 @@ (ns app.main.data.viewer (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.geom.point :as gpt] [app.common.pages.helpers :as cph] [app.common.spec :as us] @@ -20,6 +21,9 @@ [cljs.spec.alpha :as s] [potok.core :as ptk])) +(s/def ::nilable-boolean (s/nilable ::us/boolean)) +(s/def ::nilable-animation (s/nilable ::ctsi/animation)) + ;; --- Local State Initialization (def ^:private @@ -32,7 +36,6 @@ :comments-show :unresolved :selected #{} :collapsed #{} - :overlays [] :hover nil :share-id "" :file-comments-users []}) @@ -329,7 +332,8 @@ (declare flash-done) -(def flash-interactions +(defn flash-interactions + [] (ptk/reify ::flash-interactions ptk/UpdateEvent (update [_ state] @@ -367,7 +371,7 @@ (ptk/reify ::complete-animation ptk/UpdateEvent (update [_ state] - (d/dissoc-in state [:viewer-local :current-animation])))) + (dissoc state :viewer-animation)))) ;; --- Navigation inside page @@ -376,7 +380,7 @@ (ptk/reify ::go-to-frame-by-index ptk/UpdateEvent (update [_ state] - (assoc-in state [:viewer-local :overlays] [])) + (assoc state :viewer-overlays [])) ptk/WatchEvent (watch [_ state _] @@ -391,8 +395,9 @@ (go-to-frame frame-id nil)) ([frame-id animation] - (us/verify ::us/uuid frame-id) - (us/verify (s/nilable ::ctsi/animation) animation) + (us/assert! ::us/uuid frame-id) + (us/assert! ::nilable-animation animation) + (ptk/reify ::go-to-frame ptk/UpdateEvent (update [_ state] @@ -404,13 +409,13 @@ frame (get frames index)] (cond-> state :always - (assoc-in [:viewer-local :overlays] []) + (assoc :viewer-overlays []) (some? animation) - (assoc-in [:viewer-local :current-animation] - {:kind :go-to-frame - :orig-frame-id (:id frame) - :animation animation})))) + (assoc :viewer-animation + {:kind :go-to-frame + :orig-frame-id (:id frame) + :animation animation})))) ptk/WatchEvent (watch [_ state _] @@ -440,7 +445,7 @@ (ptk/reify ::go-to-section ptk/UpdateEvent (update [_ state] - (assoc-in state [:viewer-local :overlays] [])) + (assoc state :viewer-overlays [])) ptk/WatchEvent (watch [_ state _] @@ -451,64 +456,69 @@ ;; --- Overlays -(defn- do-open-overlay +(defn- open-overlay* [state frame position close-click-outside background-overlay animation] (cond-> state :always - (update-in [:viewer-local :overlays] conj - {:frame frame - :position position - :close-click-outside close-click-outside - :background-overlay background-overlay}) - (some? animation) - (assoc-in [:viewer-local :current-animation] - {:kind :open-overlay - :overlay-id (:id frame) - :animation animation}))) + (update :viewer-overlays conj + {:frame frame + :id (:id frame) + :position position + :close-click-outside close-click-outside + :background-overlay background-overlay}) -(defn- do-close-overlay + (some? animation) + (assoc :viewer-animation + {:kind :open-overlay + :overlay-id (:id frame) + :animation animation}))) + +(defn- close-overlay* [state frame-id animation] (if (nil? animation) - (update-in state [:viewer-local :overlays] - (fn [overlays] - (d/removev #(= (:id (:frame %)) frame-id) overlays))) - (assoc-in state [:viewer-local :current-animation] - {:kind :close-overlay - :overlay-id frame-id - :animation animation}))) + (update state :viewer-overlays + (fn [overlays] + (d/removev #(= (:id (:frame %)) frame-id) overlays))) + (assoc state :viewer-animation + {:kind :close-overlay + :overlay-id frame-id + :animation animation}))) (defn open-overlay [frame-id position close-click-outside background-overlay animation] - (us/verify ::us/uuid frame-id) - (us/verify ::gpt/point position) - (us/verify (s/nilable ::us/boolean) close-click-outside) - (us/verify (s/nilable ::us/boolean) background-overlay) - (us/verify (s/nilable ::ctsi/animation) animation) + (us/assert! ::us/uuid frame-id) + (us/assert! ::gpt/point position) + (us/assert! ::nilable-boolean close-click-outside) + (us/assert! ::nilable-boolean background-overlay) + (us/assert! ::nilable-animation animation) + (ptk/reify ::open-overlay ptk/UpdateEvent (update [_ state] (let [route (:route state) qparams (:query-params route) page-id (:page-id qparams) - frames (get-in state [:viewer :pages page-id :all-frames]) + frames (dm/get-in state [:viewer :pages page-id :all-frames]) frame (d/seek #(= (:id %) frame-id) frames) - overlays (get-in state [:viewer-local :overlays])] + overlays (:viewer-overlays state)] (if-not (some #(= (:frame %) frame) overlays) - (do-open-overlay state - frame - position - close-click-outside - background-overlay - animation) + (open-overlay* state + frame + position + close-click-outside + background-overlay + animation) state))))) + (defn toggle-overlay [frame-id position close-click-outside background-overlay animation] - (us/verify ::us/uuid frame-id) - (us/verify ::gpt/point position) - (us/verify (s/nilable ::us/boolean) close-click-outside) - (us/verify (s/nilable ::us/boolean) background-overlay) - (us/verify (s/nilable ::ctsi/animation) animation) + (us/assert! ::us/uuid frame-id) + (us/assert! ::gpt/point position) + (us/assert! ::nilable-boolean close-click-outside) + (us/assert! ::nilable-boolean background-overlay) + (us/assert! ::nilable-animation animation) + (ptk/reify ::toggle-overlay ptk/UpdateEvent (update [_ state] @@ -517,29 +527,30 @@ page-id (:page-id qparams) frames (get-in state [:viewer :pages page-id :all-frames]) frame (d/seek #(= (:id %) frame-id) frames) - overlays (get-in state [:viewer-local :overlays])] + overlays (:viewer-overlays state)] (if-not (some #(= (:frame %) frame) overlays) - (do-open-overlay state - frame - position - close-click-outside - background-overlay - animation) - (do-close-overlay state - (:id frame) - (ctsi/invert-direction animation))))))) + (open-overlay* state + frame + position + close-click-outside + background-overlay + animation) + (close-overlay* state + (:id frame) + (ctsi/invert-direction animation))))))) (defn close-overlay ([frame-id] (close-overlay frame-id nil)) ([frame-id animation] - (us/verify ::us/uuid frame-id) - (us/verify (s/nilable ::ctsi/animation) animation) + (us/assert! ::us/uuid frame-id) + (us/assert! ::nilable-animation animation) + (ptk/reify ::close-overlay ptk/UpdateEvent (update [_ state] - (do-close-overlay state - frame-id - animation))))) + (close-overlay* state + frame-id + animation))))) ;; --- Objects selection diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index 34a3518c9..315324668 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -21,6 +21,8 @@ (def current-project-id (mf/create-context nil)) (def current-page-id (mf/create-context nil)) (def current-file-id (mf/create-context nil)) -(def scroll-ctx (mf/create-context nil)) +(def current-scroll (mf/create-context nil)) +(def current-zoom (mf/create-context nil)) + (def active-frames-ctx (mf/create-context nil)) -(def render-thumbnails (mf/create-context nil)) +(def render-thumbnails (mf/create-context nil)) diff --git a/frontend/src/app/main/ui/shapes/shape.cljs b/frontend/src/app/main/ui/shapes/shape.cljs index c7ea0ebf3..3b868ca9d 100644 --- a/frontend/src/app/main/ui/shapes/shape.cljs +++ b/frontend/src/app/main/ui/shapes/shape.cljs @@ -11,6 +11,7 @@ [app.common.pages.helpers :as cph] [app.common.uuid :as uuid] [app.main.ui.context :as muc] + [app.main.ui.hooks :as h] [app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.export :as ed] [app.main.ui.shapes.fills :as fills] @@ -49,18 +50,19 @@ {::mf/forward-ref true ::mf/wrap-props false} [props ref] - (let [shape (obj/get props "shape") - children (obj/get props "children") - pointer-events (obj/get props "pointer-events") - disable-shadows? (obj/get props "disable-shadows?") - type (:type shape) - render-id (mf/use-memo #(str (uuid/next))) - filter-id (str "filter_" render-id) - styles (-> (obj/create) - (obj/set! "pointerEvents" pointer-events) - (cond-> (and (:blend-mode shape) (not= (:blend-mode shape) :normal)) - (obj/set! "mixBlendMode" (d/name (:blend-mode shape))))) + (let [shape (unchecked-get props "shape") + children (unchecked-get props "children") + pointer-events (unchecked-get props "pointer-events") + disable-shadows? (unchecked-get props "disable-shadows?") + + type (:type shape) + render-id (h/use-id) + filter-id (dm/str "filter_" render-id) + styles (-> (obj/create) + (obj/set! "pointerEvents" pointer-events) + (cond-> (and (:blend-mode shape) (not= (:blend-mode shape) :normal)) + (obj/set! "mixBlendMode" (d/name (:blend-mode shape))))) include-metadata? (mf/use-ctx ed/include-metadata-ctx) diff --git a/frontend/src/app/main/ui/viewer.cljs b/frontend/src/app/main/ui/viewer.cljs index f2f86ace9..a066c1388 100644 --- a/frontend/src/app/main/ui/viewer.cljs +++ b/frontend/src/app/main/ui/viewer.cljs @@ -27,7 +27,7 @@ [app.main.ui.static :as static] [app.main.ui.viewer.comments :refer [comments-layer comments-sidebar]] [app.main.ui.viewer.handoff :as handoff] - [app.main.ui.viewer.header :refer [header]] + [app.main.ui.viewer.header :as header] [app.main.ui.viewer.interactions :as interactions] [app.main.ui.viewer.login] [app.main.ui.viewer.thumbnails :refer [thumbnails-panel]] @@ -36,8 +36,15 @@ [app.util.webapi :as wapi] [cuerdas.core :as str] [goog.events :as events] + [okulary.core :as l] [rumext.alpha :as mf])) +(def current-animation-ref + (l/derived :viewer-animation st/state)) + +(def current-overlays-ref + (l/derived :viewer-overlays st/state)) + (defn- calculate-size [objects frame zoom] (let [{:keys [x y width height]} (gsb/get-object-bounds objects frame)] @@ -60,7 +67,6 @@ :height (* height zoom) :vbox (str "0 0 " width " " height)}))) - (mf/defc viewer-pagination [{:keys [index num-frames left-bar right-bar] :as props}] [:* @@ -75,94 +81,134 @@ [:div.counter (str/join " / " [(+ index 1) num-frames])] [:span]]]) +(mf/defc viewer-pagination-and-sidebar + {::mf/wrap [mf/memo]} + [{:keys [section index frames users frame page]}] + (let [comments-local (mf/deref refs/comments-local) + show-sidebar? (and (= section :comments) (:show-sidebar? comments-local))] + [:* + [:& viewer-pagination + {:index index + :num-frames (count (:frames page)) + :right-bar show-sidebar?}] + + (when show-sidebar? + [:& comments-sidebar + {:users users + :frame frame + :page page}])])) + +(mf/defc viewer-overlay + [{:keys [overlay file page frame zoom wrapper-size close-overlay interactions-mode]}] + (let [close-click-outside? (:close-click-outside overlay) + background-overlay? (:background-overlay overlay) + overlay-frame (:frame overlay) + overlay-position (:position overlay) + + size + (mf/with-memo [page overlay zoom] + (calculate-size (:objects page) (:frame overlay) zoom)) + + on-click + (mf/use-fn + (mf/deps overlay close-overlay close-click-outside?) + (fn [_] + (when close-click-outside? + (close-overlay (:frame overlay)))))] + + [:* + (when (or close-click-outside? background-overlay?) + [:div.viewer-overlay-background + {:class (dom/classnames :visible background-overlay?) + :style {:width (:width wrapper-size) + :height (:height wrapper-size) + :position "absolute" + :left 0 + :top 0} + :on-click on-click}]) + + [:div.viewport-container.viewer-overlay + {:id (dm/str "overlay-" (:id overlay-frame)) + :style {:width (:width size) + :height (:height size) + :left (* (:x overlay-position) zoom) + :top (* (:y overlay-position) zoom)}} + + [:& interactions/viewport + {:frame overlay-frame + :base-frame frame + :frame-offset overlay-position + :size size + :page page + :interactions-mode interactions-mode}]]])) + + (mf/defc viewer-wrapper [{:keys [wrapper-size scroll orig-frame orig-viewport-ref orig-size page file users current-viewport-ref size frame interactions-mode overlays zoom close-overlay section index] :as props}] - (let [{clist :list} (mf/deref refs/comments-local) - show-comments-list (and (= section :comments) (= :show clist))] - [:* - [:& viewer-pagination {:index index :num-frames (count (:frames page)) :right-bar show-comments-list}] + [:* + [:& viewer-pagination-and-sidebar + {:section section + :index index + :page page + :users users + :frame frame}] - (when show-comments-list - [:& comments-sidebar {:users users :frame frame :page page}]) + [:div.viewer-wrapper + {:style {:width (:width wrapper-size) + :height (:height wrapper-size)}} + [:div.viewer-clipper + (when orig-frame + [:div.viewport-container + {:ref orig-viewport-ref + :style {:width (:width orig-size) + :height (:height orig-size) + :position "relative"}} - [:div.viewer-wrapper - {:style {:width (:width wrapper-size) - :height (:height wrapper-size)}} - [:& (mf/provider ctx/scroll-ctx) {:value @scroll} - [:div.viewer-clipper - [:* - (when orig-frame - [:div.viewport-container - {:ref orig-viewport-ref - :style {:width (:width orig-size) - :height (:height orig-size) - :position "relative"}} + [:& interactions/viewport + {:frame orig-frame + :base-frame orig-frame + :frame-offset (gpt/point 0 0) + :size orig-size + :page page + :file file + :users users + :interactions-mode :hide}]]) - [:& interactions/viewport - {:frame orig-frame - :base-frame orig-frame - :frame-offset (gpt/point 0 0) - :size orig-size - :page page - :file file - :users users - :interactions-mode :hide}]]) + [:div.viewport-container + {:ref current-viewport-ref + :style {:width (:width size) + :height (:height size) + :position "relative"}} - [:div.viewport-container - {:ref current-viewport-ref - :style {:width (:width size) - :height (:height size) - :position "relative"}} + [:& interactions/viewport + {:frame frame + :base-frame frame + :frame-offset (gpt/point 0 0) + :size size + :page page + :interactions-mode interactions-mode}] - [:& interactions/viewport - {:frame frame - :base-frame frame - :frame-offset (gpt/point 0 0) - :size size - :page page - :file file - :users users - :interactions-mode interactions-mode}] + (for [overlay overlays] + [:& viewer-overlay {:overlay overlay + :file file + :key (dm/str (:id overlay)) + :page page + :frame frame + :zoom zoom + :wrapper-size wrapper-size + :close-overlay close-overlay + :interactions-mode interactions-mode}]) - (for [overlay overlays] - (let [size-over (calculate-size (:objects page) (:frame overlay) zoom)] - [:* - (when (or (:close-click-outside overlay) - (:background-overlay overlay)) - [:div.viewer-overlay-background - {:class (dom/classnames - :visible (:background-overlay overlay)) - :style {:width (:width wrapper-size) - :height (:height wrapper-size) - :position "absolute" - :left 0 - :top 0} - :on-click #(when (:close-click-outside overlay) - (close-overlay (:frame overlay)))}]) - [:div.viewport-container.viewer-overlay + ]] - {:id (str "overlay-" (-> overlay :frame :id)) - :style {:width (:width size-over) - :height (:height size-over) - :left (* (:x (:position overlay)) zoom) - :top (* (:y (:position overlay)) zoom)}} - [:& interactions/viewport - {:frame (:frame overlay) - :base-frame frame - :frame-offset (:position overlay) - :size size-over - :page page - :file file - :users users - :interactions-mode interactions-mode}]]]))]] - (when (= section :comments) - [:& comments-layer {:file file - :users users - :frame frame - :page page - :zoom zoom}])]]]])) + (when (= section :comments) + [:& comments-layer {:file file + :users users + :frame frame + :page page + :zoom zoom}])]]) (mf/defc viewer [{:keys [params data]}] @@ -184,10 +230,11 @@ local (mf/deref refs/viewer-local) nav-scroll (:nav-scroll local) - orig-viewport-ref (mf/use-ref nil) + orig-viewport-ref (mf/use-ref nil) current-viewport-ref (mf/use-ref nil) - viewer-section-ref (mf/use-ref nil) - current-animation (:current-animation local) + viewer-section-ref (mf/use-ref nil) + + current-animation (mf/deref current-animation-ref) page-id (or page-id (-> file :data :pages first)) @@ -206,47 +253,49 @@ frames (:frames page) frame (get frames index) - fullscreen? (mf/deref refs/viewer-fullscreen?) - overlays (:overlays local) - scroll (mf/use-state nil) + fullscreen? (mf/deref header/fullscreen-ref) + overlays (:overlays local) + overlays (mf/deref current-overlays-ref) + scroll (mf/use-state nil) orig-frame (when (:orig-frame-id current-animation) (d/seek #(= (:id %) (:orig-frame-id current-animation)) frames)) - size (mf/use-memo - (mf/deps frame zoom) - (fn [] (calculate-size (:objects page) frame zoom))) + size + (mf/with-memo [frame zoom] + (calculate-size (:objects page) frame zoom)) - orig-size (mf/use-memo - (mf/deps orig-frame zoom) - (fn [] (when orig-frame - (calculate-size (:objects page) orig-frame zoom)))) + orig-size + (mf/with-memo [orig-frame zoom] + (when orig-frame + (calculate-size (:objects page) orig-frame zoom))) - wrapper-size (mf/use-memo - (mf/deps size orig-size zoom) - (fn [] (calculate-wrapper size orig-size zoom))) + wrapper-size + (mf/with-memo [size orig-size zoom] + (calculate-wrapper size orig-size zoom)) interactions-mode (:interactions-mode local) on-click - (mf/use-callback + (mf/use-fn (mf/deps section) (fn [_] (when (= section :comments) (st/emit! (dcm/close-thread))))) set-up-new-size - (mf/use-callback + (mf/use-fn (fn [_] (let [viewer-section (dom/get-element "viewer-section") size (dom/get-client-size viewer-section)] (st/emit! (dv/set-viewport-size {:size size}))))) on-scroll - (fn [event] - (reset! scroll (dom/get-target-scroll event)))] + (mf/use-fn + (fn [event] + (reset! scroll (dom/get-target-scroll event))))] (hooks/use-shortcuts ::viewer sc/shortcuts) @@ -264,14 +313,13 @@ (let [name (:name file)] (dom/set-html-title (str "\u25b6 " (tr "title.viewer" name)))))) - (mf/use-effect - (fn [] - (dom/set-html-theme-color clr/gray-50 "dark") - (let [key1 (events/listen js/window "click" on-click) - key2 (events/listen (mf/ref-val viewer-section-ref) "scroll" on-scroll)] - (fn [] - (events/unlistenByKey key1) - (events/unlistenByKey key2))))) + (mf/with-effect [] + (dom/set-html-theme-color clr/gray-50 "dark") + (let [key1 (events/listen js/window "click" on-click) + key2 (events/listen (mf/ref-val viewer-section-ref) "scroll" on-scroll)] + (fn [] + (events/unlistenByKey key1) + (events/unlistenByKey key2)))) (mf/use-layout-effect (fn [] @@ -362,20 +410,22 @@ fonts (into #{} (keep :font-id) text-nodes)] (run! fonts/ensure-loaded! fonts)))) - [:div#viewer-layout {:class (dom/classnames - :force-visible (:show-thumbnails local) - :viewer-layout (not= section :handoff) - :handoff-layout (= section :handoff) - :fullscreen fullscreen?)} + [:div#viewer-layout + {:class (dom/classnames + :force-visible (:show-thumbnails local) + :viewer-layout (not= section :handoff) + :handoff-layout (= section :handoff) + :fullscreen fullscreen?)} - [:& header {:project project - :index index - :file file - :page page - :frame frame - :permissions permissions - :zoom zoom - :section section}] + [:& header/header + {:project project + :index index + :file file + :page page + :frame frame + :permissions permissions + :zoom zoom + :section section}] [:div.viewer-content [:div.thumbnail-close {:on-click #(st/emit! dv/close-thumbnails-panel) @@ -410,23 +460,25 @@ :index index :viewer-pagination viewer-pagination}] - [:& viewer-wrapper - {:wrapper-size wrapper-size - :scroll scroll - :orig-frame orig-frame - :orig-viewport-ref orig-viewport-ref - :orig-size orig-size - :page page - :file file - :users users - :current-viewport-ref current-viewport-ref - :size size - :frame frame - :interactions-mode interactions-mode - :overlays overlays - :zoom zoom - :section section - :index index}]))]]])) + [:& (mf/provider ctx/current-scroll) {:value @scroll} + [:& (mf/provider ctx/current-zoom) {:value zoom} + [:& viewer-wrapper + {:wrapper-size wrapper-size + :scroll @scroll + :orig-frame orig-frame + :orig-viewport-ref orig-viewport-ref + :orig-size orig-size + :page page + :file file + :users users + :current-viewport-ref current-viewport-ref + :size size + :frame frame + :interactions-mode interactions-mode + :overlays overlays + :zoom zoom + :section section + :index index}]]]))]]])) ;; --- Component: Viewer Page diff --git a/frontend/src/app/main/ui/viewer/handoff.cljs b/frontend/src/app/main/ui/viewer/handoff.cljs index 8a238fea6..2eb108de6 100644 --- a/frontend/src/app/main/ui/viewer/handoff.cljs +++ b/frontend/src/app/main/ui/viewer/handoff.cljs @@ -6,13 +6,13 @@ (ns app.main.ui.viewer.handoff (:require - [app.main.data.viewer :as dv] + [app.main.data.viewer :as dv] [app.main.store :as st] [app.main.ui.viewer.handoff.left-sidebar :refer [left-sidebar]] [app.main.ui.viewer.handoff.render :refer [render-frame-svg]] [app.main.ui.viewer.handoff.right-sidebar :refer [right-sidebar]] [app.util.dom :as dom] - [app.util.keyboard :as kbd] + [app.util.keyboard :as kbd] [goog.events :as events] [rumext.alpha :as mf]) (:import goog.events.EventType)) diff --git a/frontend/src/app/main/ui/viewer/handoff/render.cljs b/frontend/src/app/main/ui/viewer/handoff/render.cljs index 3cfb179bf..61d982910 100644 --- a/frontend/src/app/main/ui/viewer/handoff/render.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/render.cljs @@ -188,9 +188,8 @@ (mf/defc render-frame-svg [{:keys [page frame local size]}] - (let [objects (mf/use-memo - (mf/deps page frame) - (prepare-objects page frame size)) + (let [objects (mf/with-memo [page frame size] + (prepare-objects page frame size)) ;; Retrieve frame again with correct modifier frame (get objects (:id frame)) diff --git a/frontend/src/app/main/ui/viewer/header.cljs b/frontend/src/app/main/ui/viewer/header.cljs index 034473649..64f835ee7 100644 --- a/frontend/src/app/main/ui/viewer/header.cljs +++ b/frontend/src/app/main/ui/viewer/header.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.viewer.header (:require + [app.common.data.macros :as dm] [app.main.data.modal :as modal] [app.main.data.viewer :as dv] [app.main.data.viewer.shortcuts :as sc] @@ -19,8 +20,14 @@ [app.main.ui.viewer.interactions :refer [flows-menu interactions-menu]] [app.util.dom :as dom] [app.util.i18n :refer [tr]] + [okulary.core :as l] [rumext.alpha :as mf])) +(def fullscreen-ref + (l/derived (fn [state] + (dm/get-in state [:viewer-local :fullscreen?])) + st/state)) + (defn open-login-dialog [] (modal/show! :login-register {})) @@ -65,7 +72,7 @@ (mf/defc header-options [{:keys [section zoom page file index permissions]}] - (let [fullscreen? (mf/deref refs/viewer-fullscreen?) + (let [fullscreen? (mf/deref fullscreen-ref) toggle-fullscreen (mf/use-callback diff --git a/frontend/src/app/main/ui/viewer/interactions.cljs b/frontend/src/app/main/ui/viewer/interactions.cljs index 32c2a0c0d..3541f1b70 100644 --- a/frontend/src/app/main/ui/viewer/interactions.cljs +++ b/frontend/src/app/main/ui/viewer/interactions.cljs @@ -18,93 +18,122 @@ [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.icons :as i] + [app.main.ui.hooks :as h] [app.main.ui.viewer.shapes :as shapes] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.keyboard :as kbd] + [app.util.object :as obj] [goog.events :as events] [rumext.alpha :as mf])) (defn prepare-objects [page frame size] - (fn [] - (let [objects (:objects page) - frame-id (:id frame) - modifier (-> (gpt/point (:x size) (:y size)) - (gpt/negate) - (gmt/translate-matrix)) + (let [objects (:objects page) + frame-id (:id frame) + modifier (-> (gpt/point (:x size) (:y size)) + (gpt/negate) + (gmt/translate-matrix)) - update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)] + update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)] - (->> (cph/get-children-ids objects frame-id) - (into [frame-id]) - (reduce update-fn objects))))) + (->> (cph/get-children-ids objects frame-id) + (into [frame-id]) + (reduce update-fn objects)))) -(mf/defc viewport - {::mf/wrap [mf/memo]} - [{:keys [page interactions-mode frame base-frame frame-offset size]}] - (let [objects (mf/use-memo - (mf/deps page frame size) - (prepare-objects page frame size)) +(mf/defc viewport-svg + {::mf/wrap [mf/memo] + ::mf/wrap-props false} + [props] + (let [page (unchecked-get props "page") + frame (unchecked-get props "frame") + base (unchecked-get props "base") + offset (unchecked-get props "offset") + size (unchecked-get props "size") - wrapper (mf/use-memo - (mf/deps objects) - #(shapes/frame-container-factory objects)) + vbox (:vbox size) + + objects (mf/with-memo [page frame size] + (prepare-objects page frame size)) + + wrapper (mf/with-memo [objects] + (shapes/frame-container-factory objects)) ;; Retrieve frames again with correct modifier - frame (get objects (:id frame)) - base-frame (get objects (:id base-frame)) + frame (get objects (:id frame)) + base (get objects (:id base))] - on-click - (fn [_] - (when (= interactions-mode :show-on-click) - (st/emit! dv/flash-interactions))) - - on-mouse-wheel - (fn [event] - (when (kbd/mod? event) - (dom/prevent-default event) - (let [event (.getBrowserEvent ^js event) - delta (+ (.-deltaY ^js event) (.-deltaX ^js event))] - (if (pos? delta) - (st/emit! dv/decrease-zoom) - (st/emit! dv/increase-zoom))))) - - on-key-down - (fn [event] - (when (kbd/esc? event) - (st/emit! (dcm/close-thread))))] - - (mf/use-effect - (mf/deps interactions-mode) ;; on-click event depends on interactions-mode - (fn [] - ;; bind with passive=false to allow the event to be cancelled - ;; https://stackoverflow.com/a/57582286/3219895 - (let [key1 (events/listen goog/global "wheel" on-mouse-wheel #js {"passive" false}) - key2 (events/listen js/window "keydown" on-key-down) - key3 (events/listen js/window "click" on-click)] - (fn [] - (events/unlistenByKey key1) - (events/unlistenByKey key2) - (events/unlistenByKey key3))))) - - [:& (mf/provider shapes/base-frame-ctx) {:value base-frame} - [:& (mf/provider shapes/frame-offset-ctx) {:value frame-offset} - [:svg {:view-box (:vbox size) + [:& (mf/provider shapes/base-frame-ctx) {:value base} + [:& (mf/provider shapes/frame-offset-ctx) {:value offset} + [:svg {:view-box vbox :width (:width size) :height (:height size) :version "1.1" :xmlnsXlink "http://www.w3.org/1999/xlink" :xmlns "http://www.w3.org/2000/svg" :fill "none"} - [:& wrapper {:shape frame - :view-box (:vbox size)}]]]])) + [:& wrapper {:shape frame :view-box vbox}]]]])) +(mf/defc viewport + { + ::mf/wrap [mf/memo] + ::mf/wrap-props false} + [props] + (let [;; NOTE: with `use-equal-memo` hook we ensure that all values + ;; conserves the reference identity for avoid unnecesary dummy + ;; rerenders. + mode (h/use-equal-memo (unchecked-get props "interactions-mode")) + offset (h/use-equal-memo (unchecked-get props "frame-offset")) + size (h/use-equal-memo (unchecked-get props "size")) + + page (unchecked-get props "page") + frame (unchecked-get props "frame") + base (unchecked-get props "base-frame")] + + + (mf/with-effect [mode] + (let [on-click + (fn [_] + (when (= mode :show-on-click) + (st/emit! (dv/flash-interactions)))) + + on-mouse-wheel + (fn [event] + (when (kbd/mod? event) + (dom/prevent-default event) + (let [event (dom/event->browser-event event) + delta (+ (.-deltaY ^js event) + (.-deltaX ^js event))] + (if (pos? delta) + (st/emit! dv/decrease-zoom) + (st/emit! dv/increase-zoom))))) + + on-key-down + (fn [event] + (when (kbd/esc? event) + (st/emit! (dcm/close-thread)))) + + + ;; bind with passive=false to allow the event to be cancelled + ;; https://stackoverflow.com/a/57582286/3219895 + key1 (events/listen goog/global "wheel" on-mouse-wheel #js {"passive" false}) + key2 (events/listen goog/global "keydown" on-key-down) + key3 (events/listen goog/global "click" on-click)] + (fn [] + (events/unlistenByKey key1) + (events/unlistenByKey key2) + (events/unlistenByKey key3)))) + + [:& viewport-svg {:page page + :frame frame + :base base + :offset offset + :size size}])) (mf/defc flows-menu {::mf/wrap [mf/memo]} [{:keys [page index]}] - (let [flows (get-in page [:options :flows]) + (let [flows (dm/get-in page [:options :flows]) frames (:frames page) frame (get frames index) current-flow (mf/use-state @@ -135,7 +164,6 @@ [:span.icon i/tick] [:span.label (:name flow)]])]]]))) - (mf/defc interactions-menu [] (let [local (mf/deref refs/viewer-local) diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index 2ffe4f186..563041af7 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -206,19 +206,22 @@ :style {:pointer-events (when frame? "none")} :transform (gsh/transform-str shape)}]))) + +;; TODO: use-memo use-fn + (defn generic-wrapper-factory "Wrap some svg shape and add interaction controls" [component] (mf/fnc generic-wrapper {::mf/wrap-props false} [props] - (let [shape (unchecked-get props "shape") - childs (unchecked-get props "childs") - frame (unchecked-get props "frame") - objects (unchecked-get props "objects") - fixed? (unchecked-get props "fixed?") - delta (unchecked-get props "delta") - base-frame (mf/use-ctx base-frame-ctx) + (let [shape (unchecked-get props "shape") + childs (unchecked-get props "childs") + frame (unchecked-get props "frame") + objects (unchecked-get props "objects") + fixed? (unchecked-get props "fixed?") + delta (unchecked-get props "delta") + base-frame (mf/use-ctx base-frame-ctx) frame-offset (mf/use-ctx frame-offset-ctx) interactions-show? (mf/deref viewer-interactions-show?) @@ -226,20 +229,37 @@ interactions (:interactions shape) svg-element? (and (= :svg-raw (:type shape)) - (not= :svg (get-in shape [:content :tag])))] + (not= :svg (get-in shape [:content :tag]))) - (mf/use-effect - (fn [] - (let [sems (on-load shape base-frame frame-offset objects)] - #(run! tm/dispose! sems)))) + + on-mouse-down + (mf/use-fn (mf/deps shape base-frame frame-offset objects) + #(on-mouse-down % shape base-frame frame-offset objects)) + + on-mouse-up + (mf/use-fn (mf/deps shape base-frame frame-offset objects) + #(on-mouse-up % shape base-frame frame-offset objects)) + + on-mouse-enter + (mf/use-fn (mf/deps shape base-frame frame-offset objects) + #(on-mouse-enter % shape base-frame frame-offset objects)) + + on-mouse-leave + (mf/use-fn (mf/deps shape base-frame frame-offset objects) + #(on-mouse-leave % shape base-frame frame-offset objects))] + + + (mf/with-effect [] + (let [sems (on-load shape base-frame frame-offset objects)] + (partial run! tm/dispose! sems))) (if-not svg-element? [:> shape-container {:shape shape :cursor (when (ctsi/actionable? interactions) "pointer") - :on-mouse-down #(on-mouse-down % shape base-frame frame-offset objects) - :on-mouse-up #(on-mouse-up % shape base-frame frame-offset objects) - :on-mouse-enter #(on-mouse-enter % shape base-frame frame-offset objects) - :on-mouse-leave #(on-mouse-leave % shape base-frame frame-offset objects)} + :on-mouse-down on-mouse-down + :on-mouse-up on-mouse-up + :on-mouse-enter on-mouse-enter + :on-mouse-leave on-mouse-leave} [:& component {:shape shape :frame frame @@ -311,6 +331,7 @@ #js {:shape shape :childs childs :objects objects})] + [:> frame-wrapper props])))) (defn group-container-factory diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index 89f669623..f2a5da6ba 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -37,6 +37,14 @@ (when (some? e) (.-target e))) +(defn event->native-event + [^js e] + (.-nativeEvent e)) + +(defn event->browser-event + [^js e] + (.getBrowserEvent e)) + ;; --- New methods (declare get-elements-by-tag) From a37c1f7fcadc5f466f9a1974fba8a9a1cbada12b Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:23:39 +0200 Subject: [PATCH 14/34] :recycle: Refactor viewer comments related components --- frontend/src/app/main/ui/comments.cljs | 91 ++++---- frontend/src/app/main/ui/viewer/comments.cljs | 203 ++++++++++-------- 2 files changed, 162 insertions(+), 132 deletions(-) diff --git a/frontend/src/app/main/ui/comments.cljs b/frontend/src/app/main/ui/comments.cljs index 14361b96f..31fe47767 100644 --- a/frontend/src/app/main/ui/comments.cljs +++ b/frontend/src/app/main/ui/comments.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.comments (:require + [app.common.geom.point :as gpt] [app.config :as cfg] [app.main.data.comments :as dcm] [app.main.data.modal :as modal] @@ -110,8 +111,10 @@ [:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]])])) (mf/defc draft-thread - [{:keys [draft zoom on-cancel on-submit] :as props}] - (let [position (:position draft) + [{:keys [draft zoom on-cancel on-submit position-modifier]}] + (let [position (cond-> (:position draft) + (some? position-modifier) + (gpt/transform position-modifier)) content (:content draft) pos-x (* (:x position) zoom) pos-y (* (:y position) zoom) @@ -281,9 +284,12 @@ (l/derived (l/in [:comments id]) st/state)) (mf/defc thread-comments - [{:keys [thread zoom users origin]}] + {::mf/wrap [mf/memo]} + [{:keys [thread zoom users origin position-modifier]}] (let [ref (mf/use-ref) - pos (:position thread) + pos (cond-> (:position thread) + (some? position-modifier) + (gpt/transform position-modifier)) pos-x (+ (* (:x pos) zoom) 14) pos-y (- (* (:y pos) zoom) 14) @@ -384,9 +390,12 @@ (mf/defc thread-bubble {::mf/wrap [mf/memo]} - [{:keys [thread zoom open? on-click origin]}] - (let [pos (:position thread) - drag? (mf/use-ref nil) + [{:keys [thread zoom open? on-click origin position-modifier]}] + (let [pos (cond-> (:position thread) + (some? position-modifier) + (gpt/transform position-modifier)) + + drag? (mf/use-ref nil) was-open? (mf/use-ref nil) {:keys [on-pointer-down @@ -398,41 +407,45 @@ pos-x (* (or (:new-position-x @state) (:x pos)) zoom) pos-y (* (or (:new-position-y @state) (:y pos)) zoom) - on-pointer-down* (mf/use-callback - (mf/deps origin was-open? open? drag? on-pointer-down) - (fn [event] - (when (not= origin :viewer) - (mf/set-ref-val! was-open? open?) - (when open? (st/emit! (dcm/close-thread))) - (mf/set-ref-val! drag? false) - (dom/stop-propagation event) - (on-pointer-down event)))) + on-pointer-down* + (mf/use-callback + (mf/deps origin was-open? open? drag? on-pointer-down) + (fn [event] + (when (not= origin :viewer) + (mf/set-ref-val! was-open? open?) + (when open? (st/emit! (dcm/close-thread))) + (mf/set-ref-val! drag? false) + (dom/stop-propagation event) + (on-pointer-down event)))) - on-pointer-up* (mf/use-callback - (mf/deps origin thread was-open? drag? on-pointer-up) - (fn [event] - (when (not= origin :viewer) - (dom/stop-propagation event) - (on-pointer-up event thread) + on-pointer-up* + (mf/use-callback + (mf/deps origin thread was-open? drag? on-pointer-up) + (fn [event] + (when (not= origin :viewer) + (dom/stop-propagation event) + (on-pointer-up event thread) - (when (or (and (mf/ref-val was-open?) (mf/ref-val drag?)) - (and (not (mf/ref-val was-open?)) (not (mf/ref-val drag?)))) - (st/emit! (dcm/open-thread thread)))))) + (when (or (and (mf/ref-val was-open?) (mf/ref-val drag?)) + (and (not (mf/ref-val was-open?)) (not (mf/ref-val drag?)))) + (st/emit! (dcm/open-thread thread)))))) - on-mouse-move* (mf/use-callback - (mf/deps origin drag? on-mouse-move) - (fn [event] - (when (not= origin :viewer) - (mf/set-ref-val! drag? true) - (dom/stop-propagation event) - (on-mouse-move event)))) + on-mouse-move* + (mf/use-callback + (mf/deps origin drag? on-mouse-move) + (fn [event] + (when (not= origin :viewer) + (mf/set-ref-val! drag? true) + (dom/stop-propagation event) + (on-mouse-move event)))) - on-click* (mf/use-callback - (mf/deps origin thread on-click) - (fn [event] - (dom/stop-propagation event) - (when (= origin :viewer) - (on-click thread))))] + on-click* + (mf/use-callback + (mf/deps origin thread on-click) + (fn [event] + (dom/stop-propagation event) + (when (= origin :viewer) + (on-click thread))))] [:div.thread-bubble {:style {:top (str pos-y "px") @@ -448,7 +461,7 @@ [:span (:seqn thread)]])) (mf/defc comment-thread - [{:keys [item users on-click] :as props}] + [{:keys [item users on-click]}] (let [owner (get users (:owner-id item)) on-click* (mf/use-callback diff --git a/frontend/src/app/main/ui/viewer/comments.cljs b/frontend/src/app/main/ui/viewer/comments.cljs index c46147ed9..dc7586d21 100644 --- a/frontend/src/app/main/ui/viewer/comments.cljs +++ b/frontend/src/app/main/ui/viewer/comments.cljs @@ -6,6 +6,8 @@ (ns app.main.ui.viewer.comments (:require + [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] @@ -23,132 +25,145 @@ [rumext.alpha :as mf])) (mf/defc comments-menu + {::mf/wrap [mf/memo] + ::mf/wrap-props false} [] - (let [{cmode :mode cshow :show clist :list} (mf/deref refs/comments-local) + (let [local (mf/deref refs/comments-local) + owner-filter (:owner-filter local) + status-filter (:status-filter local) + show-sidebar? (:show-sidebar? local) show-dropdown? (mf/use-state false) toggle-dropdown (mf/use-fn #(swap! show-dropdown? not)) hide-dropdown (mf/use-fn #(reset! show-dropdown? false)) - update-mode - (mf/use-callback - (fn [mode] - (st/emit! (dcm/update-filters {:mode mode})))) - - update-show - (mf/use-callback - (fn [mode] - (st/emit! (dcm/update-filters {:show mode})))) - - update-list - (mf/use-callback - (fn [show-list] - (st/emit! (dcm/update-filters {:list show-list}))))] + update-option (mf/use-fn + (fn [event] + (let [target (dom/get-current-target event) + key (d/read-string (dom/get-attribute target "data-key")) + val (d/read-string (dom/get-attribute target "data-val"))] + (st/emit! (dcm/update-options {key val})))))] [:div.view-options {:on-click toggle-dropdown} [:span.label (tr "labels.comments")] [:span.icon i/arrow-down] [:& dropdown {:show @show-dropdown? :on-close hide-dropdown} + [:ul.dropdown.with-check - [:li {:class (dom/classnames :selected (= :all cmode)) - :on-click #(update-mode :all)} + [:li {:class (dom/classnames :selected (= :all owner-filter)) + :data-key ":owner-filter" + :data-val ":all" + :on-click update-option} [:span.icon i/tick] [:span.label (tr "labels.show-all-comments")]] - [:li {:class (dom/classnames :selected (= :yours cmode)) - :on-click #(update-mode :yours)} + [:li {:class (dom/classnames :selected (= :yours owner-filter)) + :data-key ":owner-filter" + :data-val ":yours" + :on-click update-option} [:span.icon i/tick] [:span.label (tr "labels.show-your-comments")]] [:hr] - [:li {:class (dom/classnames :selected (= :pending cshow)) - :on-click #(update-show (if (= :pending cshow) :all :pending))} + [:li {:class (dom/classnames :selected (= :pending status-filter)) + :data-key ":status-filter" + :data-val (if (= :pending status-filter) ":all" ":pending") + :on-click update-option} [:span.icon i/tick] [:span.label (tr "labels.hide-resolved-comments")]] [:hr] - - [:li {:class (dom/classnames :selected (= :show clist)) - :on-click #(update-list (if (= :show clist) :hide :show))} + [:li {:class (dom/classnames :selected show-sidebar?) + :data-key ":show-sidebar?" + :data-val (if show-sidebar? "false" "true") + :on-click update-option} [:span.icon i/tick] [:span.label (tr "labels.show-comments-list")]]]]])) -(def threads-ref - (l/derived :comment-threads st/state)) - -(def comments-local-ref - (l/derived :comments-local st/state)) +(defn- update-thread-position [positions {:keys [id] :as thread}] + (if-let [data (get positions id)] + (-> thread + (assoc :position (:position data)) + (assoc :frame-id (:frame-id data))) + thread)) (mf/defc comments-layer [{:keys [zoom file users frame page] :as props}] - (let [profile (mf/deref refs/profile) - threads-position-ref (l/derived (l/in [:viewer :pages (:id page) :options :comment-threads-position]) st/state) - threads-position-map (mf/deref threads-position-ref) - threads-map (mf/deref threads-ref) + (prn "comments-layer") + (let [profile (mf/deref refs/profile) + local (mf/deref refs/comments-local) - frame-corner (-> frame :points gsh/points->selrect gpt/point) - modifier1 (-> (gmt/matrix) - (gmt/translate (gpt/negate frame-corner))) + open-thread-id (:open local) + page-id (:id page) + file-id (:id file) + frame-id (:id frame) - modifier2 (-> (gpt/point frame-corner) - (gmt/translate-matrix)) + tpos-ref (mf/with-memo [page-id] + (-> (l/in [:pages page-id :options :comment-threads-position]) + (l/derived refs/viewer-data))) - cstate (mf/deref refs/comments-local) + positions (mf/deref tpos-ref) + threads-map (mf/deref refs/comment-threads) - update-thread-position (fn update-thread-position [thread] - (if (contains? threads-position-map (:id thread)) - (-> thread - (assoc :position (get-in threads-position-map [(:id thread) :position])) - (assoc :frame-id (get-in threads-position-map [(:id thread) :frame-id]))) - thread)) + frame-corner (mf/with-memo [frame] + (-> frame :points gsh/points->selrect gpt/point)) + + modifier1 (mf/with-memo [frame-corner] + (-> (gmt/matrix) + (gmt/translate (gpt/negate frame-corner)))) + modifier2 (mf/with-memo [frame-corner] + (-> (gpt/point frame-corner) + (gmt/translate-matrix))) + + + threads (mf/with-memo [threads-map positions] + (->> (vals threads-map) + (map (partial update-thread-position positions)) + (filter #(= (:frame-id %) (:id frame))) + (dcm/apply-filters local profile) + (filter (fn [{:keys [position]}] + (gsh/has-point? frame position))))) - threads (->> (vals threads-map) - (map update-thread-position) - (filter #(= (:frame-id %) (:id frame))) - (dcm/apply-filters cstate profile) - (filter (fn [{:keys [position]}] - (gsh/has-point? frame position)))) on-bubble-click - (mf/use-callback - (mf/deps cstate) - (fn [thread] - (if (= (:open cstate) (:id thread)) - (st/emit! (dcm/close-thread)) - (st/emit! (-> (dcm/open-thread thread) + (mf/use-fn + (mf/deps open-thread-id) + (fn [{:keys [id] :as thread}] + (st/emit! (if (= open-thread-id id) + (dcm/close-thread) + (-> (dcm/open-thread thread) (with-meta {::ev/origin "viewer"})))))) on-click - (mf/use-callback - (mf/deps cstate frame page file zoom) + (mf/use-fn + (mf/deps open-thread-id zoom page-id file-id modifier2) (fn [event] (dom/stop-propagation event) - (if (some? (:open cstate)) + (if (some? open-thread-id) (st/emit! (dcm/close-thread)) - (let [event (.-nativeEvent ^js event) - viewport-point (dom/get-offset-position event) - viewport-point (-> viewport-point (update :x #(/ % zoom)) (update :y #(/ % zoom))) - position (gpt/transform viewport-point modifier2) + (let [event (dom/event->native-event event) + position (-> (dom/get-offset-position event) + (update :x #(/ % zoom)) + (update :y #(/ % zoom)) + (gpt/transform modifier2)) params {:position position :page-id (:id page) :file-id (:id file)}] (st/emit! (dcm/create-draft params)))))) on-draft-cancel - (mf/use-callback - (mf/deps cstate) - #(st/emit! (dcm/close-thread))) + (mf/use-fn #(st/emit! (dcm/close-thread))) on-draft-submit - (mf/use-callback - (mf/deps frame) + (mf/use-fn + (mf/deps frame-id modifier2) (fn [draft] (let [params (-> draft - (update :position gpt/transform modifier2) - (assoc :frame-id (:id frame)))] + (update :position gpt/transform modifier2) + (assoc :frame-id frame-id))] (st/emit! (dcm/create-thread-on-viewer params) (dcm/close-thread)))))] @@ -156,35 +171,37 @@ [:div.viewer-comments-container [:div.threads (for [item threads] - (let [item (update item :position gpt/transform modifier1)] - [:& cmt/thread-bubble {:thread item - :zoom zoom - :on-click on-bubble-click - :open? (= (:id item) (:open cstate)) - :key (:seqn item) - :origin :viewer}])) + [:& cmt/thread-bubble + {:thread item + :position-modifier modifier1 + :zoom zoom + :on-click on-bubble-click + :open? (= (:id item) (:open local)) + :key (:seqn item) + :origin :viewer}]) - (when-let [id (:open cstate)] - (when-let [thread (as-> (get threads-map id) $ - (when (some? $) - (update $ :position gpt/transform modifier1)))] - [:& cmt/thread-comments {:thread thread - :users users - :zoom zoom}])) + (when-let [thread (get threads-map open-thread-id)] + [:& cmt/thread-comments + {:thread thread + :position-modifier modifier1 + :users users + :zoom zoom}]) - (when-let [draft (:draft cstate)] - [:& cmt/draft-thread {:draft (update draft :position gpt/transform modifier1) - :on-cancel on-draft-cancel - :on-submit on-draft-submit - :zoom zoom}])]]])) + (when-let [draft (:draft local)] + [:& cmt/draft-thread + {:draft draft + :position-modifier modifier1 + :on-cancel on-draft-cancel + :on-submit on-draft-submit + :zoom zoom}])]]])) (mf/defc comments-sidebar [{:keys [users frame page]}] (let [profile (mf/deref refs/profile) - cstate (mf/deref refs/comments-local) - threads-map (mf/deref threads-ref) + local (mf/deref refs/comments-local) + threads-map (mf/deref refs/comment-threads) threads (->> (vals threads-map) - (dcm/apply-filters cstate profile) + (dcm/apply-filters local profile) (filter (fn [{:keys [position]}] (gsh/has-point? frame position))))] [:aside.settings-bar.settings-bar-right.comments-right-sidebar From 10bb75c1a1356ef6d0118b3ddea91bd00eab7745 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:26:32 +0200 Subject: [PATCH 15/34] :fire: Remove unused code related to remap colors of fo-text component --- frontend/src/app/main/ui/context.cljs | 4 --- .../src/app/main/ui/shapes/text/fo_text.cljs | 25 +------------------ 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index 315324668..ee4c891e4 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -11,10 +11,6 @@ (def render-ctx (mf/create-context nil)) (def def-ctx (mf/create-context false)) -;; This content is used to replace complex colors to simple ones -;; for text shapes in the export process -(def text-plain-colors-ctx (mf/create-context false)) - (def current-route (mf/create-context nil)) (def current-profile (mf/create-context nil)) (def current-team-id (mf/create-context nil)) diff --git a/frontend/src/app/main/ui/shapes/text/fo_text.cljs b/frontend/src/app/main/ui/shapes/text/fo_text.cljs index 158b6c117..b32f9c876 100644 --- a/frontend/src/app/main/ui/shapes/text/fo_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/fo_text.cljs @@ -91,23 +91,6 @@ (recur (uc/next-rgb current-rgb)) current-hex)))) -(defn- remap-colors - "Returns a new content replacing the original colors by their mapped 'simple color'" - [content color-mapping] - - (cond-> content - (and (:fill-opacity content) (< (:fill-opacity content) 1.0)) - (-> (assoc :fill-color (get color-mapping [(:fill-color content) (:fill-opacity content)])) - (assoc :fill-opacity 1.0)) - - (some? (:fill-color-gradient content)) - (-> (assoc :fill-color (get color-mapping (:fill-color-gradient content))) - (assoc :fill-opacity 1.0) - (dissoc :fill-color-gradient)) - - (contains? content :children) - (update :children #(mapv (fn [node] (remap-colors node color-mapping)) %)))) - (defn- fill->color "Given a content node returns the information about that node fill color" [{:keys [fill-color fill-opacity fill-color-gradient]}] @@ -199,13 +182,7 @@ ;; We add 8px to add a padding for the exporter ;; width (+ width 8) - [colors color-mapping color-mapping-inverse] (retrieve-colors shape) - - plain-colors? (mf/use-ctx muc/text-plain-colors-ctx) - - content (cond-> content - plain-colors? - (remap-colors color-mapping))] + [colors color-mapping color-mapping-inverse] (retrieve-colors shape)] [:foreignObject {:x x From 082bcd2bde3df97819b0e31ef9038d0589f520a5 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:27:24 +0200 Subject: [PATCH 16/34] :fire: Remove unused def-ctx react context var --- frontend/src/app/main/ui/context.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index ee4c891e4..012408866 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -9,7 +9,6 @@ [rumext.alpha :as mf])) (def render-ctx (mf/create-context nil)) -(def def-ctx (mf/create-context false)) (def current-route (mf/create-context nil)) (def current-profile (mf/create-context nil)) From 3e3a10b5dd5950d1f3cf984cf603b6920cb7239b Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:32:53 +0200 Subject: [PATCH 17/34] :sparkles: Rename render-ctx to render-id --- frontend/src/app/main/ui/context.cljs | 2 +- frontend/src/app/main/ui/shapes/attrs.cljs | 2 +- frontend/src/app/main/ui/shapes/custom_stroke.cljs | 10 +++++----- frontend/src/app/main/ui/shapes/export.cljs | 4 ++-- frontend/src/app/main/ui/shapes/frame.cljs | 2 +- frontend/src/app/main/ui/shapes/gradients.cljs | 2 +- frontend/src/app/main/ui/shapes/group.cljs | 2 +- frontend/src/app/main/ui/shapes/mask.cljs | 8 ++++---- frontend/src/app/main/ui/shapes/shape.cljs | 2 +- frontend/src/app/main/ui/shapes/text/svg_text.cljs | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index 012408866..ed8079435 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -8,7 +8,7 @@ (:require [rumext.alpha :as mf])) -(def render-ctx (mf/create-context nil)) +(def render-id (mf/create-context nil)) (def current-route (mf/create-context nil)) (def current-profile (mf/create-context nil)) diff --git a/frontend/src/app/main/ui/shapes/attrs.cljs b/frontend/src/app/main/ui/shapes/attrs.cljs index 4b95e4350..f94871a5f 100644 --- a/frontend/src/app/main/ui/shapes/attrs.cljs +++ b/frontend/src/app/main/ui/shapes/attrs.cljs @@ -159,7 +159,7 @@ (defn add-style-attrs ([props shape] - (let [render-id (mf/use-ctx muc/render-ctx)] + (let [render-id (mf/use-ctx muc/render-id)] (add-style-attrs props shape render-id))) ([props shape render-id] diff --git a/frontend/src/app/main/ui/shapes/custom_stroke.cljs b/frontend/src/app/main/ui/shapes/custom_stroke.cljs index c0eb8ddf4..7753c3f32 100644 --- a/frontend/src/app/main/ui/shapes/custom_stroke.cljs +++ b/frontend/src/app/main/ui/shapes/custom_stroke.cljs @@ -211,7 +211,7 @@ {::mf/wrap-props false} [props] - (let [render-id (mf/use-ctx muc/render-ctx) + (let [render-id (mf/use-ctx muc/render-id) child (obj/get props "children") base-props (obj/get child "props") elem-name (obj/get child "type") @@ -253,7 +253,7 @@ (mf/defc inner-stroke {::mf/wrap-props false} [props] - (let [render-id (mf/use-ctx muc/render-ctx) + (let [render-id (mf/use-ctx muc/render-id) child (obj/get props "children") base-props (obj/get child "props") elem-name (obj/get child "type") @@ -292,7 +292,7 @@ (let [child (obj/get props "children") shape (obj/get props "shape") - render-id (mf/use-ctx muc/render-ctx) + render-id (mf/use-ctx muc/render-id) index (obj/get props "index") stroke-width (:stroke-width shape 0) stroke-style (:stroke-style shape :none) @@ -417,7 +417,7 @@ shape (obj/get props "shape") elem-name (obj/get child "type") position (or (obj/get props "position") 0) - render-id (or (obj/get props "render-id") (mf/use-ctx muc/render-ctx))] + render-id (or (obj/get props "render-id") (mf/use-ctx muc/render-id))] [:g {:id (dm/fmt "fills-%" (:id shape))} [:> elem-name (build-fill-props shape child position render-id)]])) @@ -427,7 +427,7 @@ (let [child (obj/get props "children") shape (obj/get props "shape") elem-name (obj/get child "type") - render-id (or (obj/get props "render-id") (mf/use-ctx muc/render-ctx)) + render-id (or (obj/get props "render-id") (mf/use-ctx muc/render-id)) stroke-id (dm/fmt "strokes-%" (:id shape)) stroke-props (-> (obj/create) (obj/set! "id" stroke-id) diff --git a/frontend/src/app/main/ui/shapes/export.cljs b/frontend/src/app/main/ui/shapes/export.cljs index 5f8ceba50..b2453f7e0 100644 --- a/frontend/src/app/main/ui/shapes/export.cljs +++ b/frontend/src/app/main/ui/shapes/export.cljs @@ -286,7 +286,7 @@ (for [[index fill] (d/enumerate fills)] [:> "penpot:fill" #js {:penpot:fill-color (if (some? (:fill-color-gradient fill)) - (str/format "url(#%s)" (str "fill-color-gradient_" (mf/use-ctx muc/render-ctx) "_" index)) + (str/format "url(#%s)" (str "fill-color-gradient_" (mf/use-ctx muc/render-id) "_" index)) (d/name (:fill-color fill))) :penpot:fill-color-ref-file (d/name (:fill-color-ref-file fill)) :penpot:fill-color-ref-id (d/name (:fill-color-ref-id fill)) @@ -299,7 +299,7 @@ (for [[index stroke] (d/enumerate strokes)] [:> "penpot:stroke" #js {:penpot:stroke-color (if (some? (:stroke-color-gradient stroke)) - (str/format "url(#%s)" (str "stroke-color-gradient_" (mf/use-ctx muc/render-ctx) "_" index)) + (str/format "url(#%s)" (str "stroke-color-gradient_" (mf/use-ctx muc/render-id) "_" index)) (d/name (:stroke-color stroke))) :penpot:stroke-color-ref-file (d/name (:stroke-color-ref-file stroke)) :penpot:stroke-color-ref-id (d/name (:stroke-color-ref-id stroke)) diff --git a/frontend/src/app/main/ui/shapes/frame.cljs b/frontend/src/app/main/ui/shapes/frame.cljs index 1aa7a7b5b..ba821a5d7 100644 --- a/frontend/src/app/main/ui/shapes/frame.cljs +++ b/frontend/src/app/main/ui/shapes/frame.cljs @@ -62,7 +62,7 @@ :height height :className "frame-background"})) path? (some? (.-d props)) - render-id (mf/use-ctx muc/render-ctx)] + render-id (mf/use-ctx muc/render-id)] [:* [:g {:clip-path (when (not show-content) (frame-clip-url shape render-id))} diff --git a/frontend/src/app/main/ui/shapes/gradients.cljs b/frontend/src/app/main/ui/shapes/gradients.cljs index a57678bf4..9d45482f4 100644 --- a/frontend/src/app/main/ui/shapes/gradients.cljs +++ b/frontend/src/app/main/ui/shapes/gradients.cljs @@ -104,7 +104,7 @@ (let [attr (obj/get props "attr") shape (obj/get props "shape") id (obj/get props "id") - id' (mf/use-ctx muc/render-ctx) + id' (mf/use-ctx muc/render-id) id (or id (dm/str (name attr) "_" id')) gradient (get shape attr) gradient-props #js {:id id diff --git a/frontend/src/app/main/ui/shapes/group.cljs b/frontend/src/app/main/ui/shapes/group.cljs index 88dc6186d..664c4e834 100644 --- a/frontend/src/app/main/ui/shapes/group.cljs +++ b/frontend/src/app/main/ui/shapes/group.cljs @@ -21,7 +21,7 @@ (let [shape (unchecked-get props "shape") childs (unchecked-get props "childs") objects (unchecked-get props "objects") - render-id (mf/use-ctx muc/render-ctx) + render-id (mf/use-ctx muc/render-id) masked-group? (:masked-group? shape) [mask childs] (if masked-group? diff --git a/frontend/src/app/main/ui/shapes/mask.cljs b/frontend/src/app/main/ui/shapes/mask.cljs index 5c353d120..c43b12a60 100644 --- a/frontend/src/app/main/ui/shapes/mask.cljs +++ b/frontend/src/app/main/ui/shapes/mask.cljs @@ -47,18 +47,18 @@ {::mf/wrap-props false} [props] (let [mask (unchecked-get props "mask") - render-id (mf/use-ctx muc/render-ctx) + render-id (mf/use-ctx muc/render-id) svg-text? (and (= :text (:type mask)) (some? (:position-data mask))) ;; This factory is generic, it's used for viewer, workspace and handoff. - ;; These props are generated in viewer wrappers only, in the rest of the - ;; cases these props will be nil, not affecting the code. + ;; These props are generated in viewer wrappers only, in the rest of the + ;; cases these props will be nil, not affecting the code. fixed? (unchecked-get props "fixed?") delta (unchecked-get props "delta") mask-bb (-> (gsh/transform-shape mask) (cond-> fixed? (gsh/move delta)) (:points)) - + mask-bb-rect (gsh/points->rect mask-bb)] [:defs [:filter {:id (filter-id render-id mask)} diff --git a/frontend/src/app/main/ui/shapes/shape.cljs b/frontend/src/app/main/ui/shapes/shape.cljs index 3b868ca9d..9743204d0 100644 --- a/frontend/src/app/main/ui/shapes/shape.cljs +++ b/frontend/src/app/main/ui/shapes/shape.cljs @@ -93,7 +93,7 @@ svg-group? (propagate-wrapper-styles wrapper-props))] - [:& (mf/provider muc/render-ctx) {:value render-id} + [:& (mf/provider muc/render-id) {:value render-id} [:> :g wrapper-props (when include-metadata? [:& ed/export-data {:shape shape}]) diff --git a/frontend/src/app/main/ui/shapes/text/svg_text.cljs b/frontend/src/app/main/ui/shapes/text/svg_text.cljs index b4585b532..3f90c6cd3 100644 --- a/frontend/src/app/main/ui/shapes/text/svg_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/svg_text.cljs @@ -53,7 +53,7 @@ ::mf/wrap [mf/memo]} [props] - (let [render-id (mf/use-ctx muc/render-ctx) + (let [render-id (mf/use-ctx muc/render-id) shape (obj/get props "shape") shape (cond-> shape (:is-mask? shape) set-white-fill) @@ -106,6 +106,6 @@ (obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))}) shape (assoc shape :fills (:fills data))] - [:& (mf/provider muc/render-ctx) {:key index :value (str render-id "_" (:id shape) "_" index)} + [:& (mf/provider muc/render-id) {:key index :value (str render-id "_" (:id shape) "_" index)} [:& shape-custom-strokes {:shape shape :position index :render-id render-id} [:> :text props (:text data)]]]))]])) From b9f767a614437a14e305402d303b685e7a0286b9 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:34:23 +0200 Subject: [PATCH 18/34] :sparkles: Rename active-frames-ctx to active-frames --- frontend/src/app/main/ui/context.cljs | 2 +- frontend/src/app/main/ui/workspace/shapes.cljs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/context.cljs b/frontend/src/app/main/ui/context.cljs index ed8079435..92a01bb6b 100644 --- a/frontend/src/app/main/ui/context.cljs +++ b/frontend/src/app/main/ui/context.cljs @@ -19,5 +19,5 @@ (def current-scroll (mf/create-context nil)) (def current-zoom (mf/create-context nil)) -(def active-frames-ctx (mf/create-context nil)) +(def active-frames (mf/create-context nil)) (def render-thumbnails (mf/create-context nil)) diff --git a/frontend/src/app/main/ui/workspace/shapes.cljs b/frontend/src/app/main/ui/workspace/shapes.cljs index 293492c83..0c93d33ed 100644 --- a/frontend/src/app/main/ui/workspace/shapes.cljs +++ b/frontend/src/app/main/ui/workspace/shapes.cljs @@ -54,7 +54,7 @@ (mf/deps objects) #(cph/objects-by-frame objects))] - [:& (mf/provider ctx/active-frames-ctx) {:value active-frames} + [:& (mf/provider ctx/active-frames) {:value active-frames} ;; Render font faces only for shapes that are part of the root ;; frame but don't belongs to any other frame. (let [xform (comp @@ -79,7 +79,7 @@ (let [shape (obj/get props "shape") active-frames - (when (cph/root-frame? shape) (mf/use-ctx ctx/active-frames-ctx)) + (when (cph/root-frame? shape) (mf/use-ctx ctx/active-frames)) thumbnail? (and (some? active-frames) From f9b44ccc5c8820ebfc61fba52c61a1b3f1219b7c Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 07:46:35 +0200 Subject: [PATCH 19/34] :zap: Refactor viewer shape-container component Still need a rething for the fixed position shapes feature because watching scroll position on all shapes is killing viewer performance. --- frontend/src/app/main/ui/viewer/shapes.cljs | 45 +++++++++++++-------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index 563041af7..ae280e215 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -383,31 +383,43 @@ image-wrapper (image-wrapper) circle-wrapper (circle-wrapper)] (mf/fnc shape-container - {::mf/wrap-props false} + {::mf/wrap-props false + ::mf/wrap [mf/memo]} [props] - (let [scroll (mf/use-ctx ctx/scroll-ctx) - local (mf/deref refs/viewer-local) - zoom (:zoom local) - shape (unchecked-get props "shape") - parents (map (d/getf objects) (cph/get-parent-ids objects (:id shape))) - fixed? (or (:fixed-scroll shape) (some :fixed-scroll parents)) + (let [shape (unchecked-get props "shape") frame (unchecked-get props "frame") - delta {:x (/ (:scroll-left scroll) zoom) :y (/ (:scroll-top scroll) zoom)} + + ;; TODO: this watch of scroll position is killing + ;; performance of the viewer. + scroll (mf/use-ctx ctx/current-scroll) + zoom (mf/use-ctx ctx/current-zoom) + + fixed? (mf/with-memo [shape objects] + (->> (cph/get-parent-ids objects (:id shape)) + (map (d/getf objects)) + (concat [shape]) + (some :fixed-scroll))) + + delta {:x (/ (:scroll-left scroll) zoom) + :y (/ (:scroll-top scroll) zoom)} + group-container - (mf/use-memo (mf/deps objects) - #(group-container-factory objects)) + (mf/with-memo [objects] + (group-container-factory objects)) frame-container - (mf/use-memo (mf/deps objects) - #(frame-container-factory objects)) + (mf/with-memo [objects] + (frame-container-factory objects)) bool-container - (mf/use-memo (mf/deps objects) - #(bool-container-factory objects)) + (mf/with-memo [objects] + (bool-container-factory objects)) svg-raw-container - (mf/use-memo (mf/deps objects) - #(svg-raw-container-factory objects))] + (mf/with-memo [objects] + (svg-raw-container-factory objects)) + + ] (when (and shape (not (:hidden shape))) (let [shape (-> (gsh/transform-shape shape) (gsh/translate-to-frame frame) @@ -425,4 +437,3 @@ :group [:> group-container {:shape shape :frame frame :objects objects :fixed? fixed? :delta delta}] :bool [:> bool-container {:shape shape :frame frame :objects objects}] :svg-raw [:> svg-raw-container {:shape shape :frame frame :objects objects}]))))))) - From 1649ca4ff76411ae735f0e706a95f118391cc501 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 08:00:42 +0200 Subject: [PATCH 20/34] :paperclip: Fix linter issues --- frontend/src/app/main/ui/shapes/shape.cljs | 1 - frontend/src/app/main/ui/shapes/text/fo_text.cljs | 3 +-- frontend/src/app/main/ui/viewer.cljs | 10 +++------- frontend/src/app/main/ui/viewer/comments.cljs | 1 - frontend/src/app/main/ui/viewer/header.cljs | 1 - frontend/src/app/main/ui/viewer/interactions.cljs | 7 ++----- 6 files changed, 6 insertions(+), 17 deletions(-) diff --git a/frontend/src/app/main/ui/shapes/shape.cljs b/frontend/src/app/main/ui/shapes/shape.cljs index 9743204d0..a457534a7 100644 --- a/frontend/src/app/main/ui/shapes/shape.cljs +++ b/frontend/src/app/main/ui/shapes/shape.cljs @@ -9,7 +9,6 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.pages.helpers :as cph] - [app.common.uuid :as uuid] [app.main.ui.context :as muc] [app.main.ui.hooks :as h] [app.main.ui.shapes.attrs :as attrs] diff --git a/frontend/src/app/main/ui/shapes/text/fo_text.cljs b/frontend/src/app/main/ui/shapes/text/fo_text.cljs index b32f9c876..eb5908c68 100644 --- a/frontend/src/app/main/ui/shapes/text/fo_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/fo_text.cljs @@ -9,7 +9,6 @@ [app.common.colors :as clr] [app.common.data :as d] [app.common.geom.shapes :as gsh] - [app.main.ui.context :as muc] [app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.text.styles :as sts] [app.util.color :as uc] @@ -182,7 +181,7 @@ ;; We add 8px to add a padding for the exporter ;; width (+ width 8) - [colors color-mapping color-mapping-inverse] (retrieve-colors shape)] + [colors _color-mapping color-mapping-inverse] (retrieve-colors shape)] [:foreignObject {:x x diff --git a/frontend/src/app/main/ui/viewer.cljs b/frontend/src/app/main/ui/viewer.cljs index a066c1388..ced7b3c6a 100644 --- a/frontend/src/app/main/ui/viewer.cljs +++ b/frontend/src/app/main/ui/viewer.cljs @@ -83,7 +83,7 @@ (mf/defc viewer-pagination-and-sidebar {::mf/wrap [mf/memo]} - [{:keys [section index frames users frame page]}] + [{:keys [section index users frame page]}] (let [comments-local (mf/deref refs/comments-local) show-sidebar? (and (= section :comments) (:show-sidebar? comments-local))] [:* @@ -99,7 +99,7 @@ :page page}])])) (mf/defc viewer-overlay - [{:keys [overlay file page frame zoom wrapper-size close-overlay interactions-mode]}] + [{:keys [overlay page frame zoom wrapper-size close-overlay interactions-mode]}] (let [close-click-outside? (:close-click-outside overlay) background-overlay? (:background-overlay overlay) overlay-frame (:frame overlay) @@ -144,7 +144,7 @@ (mf/defc viewer-wrapper - [{:keys [wrapper-size scroll orig-frame orig-viewport-ref orig-size page file users current-viewport-ref + [{:keys [wrapper-size orig-frame orig-viewport-ref orig-size page file users current-viewport-ref size frame interactions-mode overlays zoom close-overlay section index] :as props}] [:* [:& viewer-pagination-and-sidebar @@ -171,7 +171,6 @@ :frame-offset (gpt/point 0 0) :size orig-size :page page - :file file :users users :interactions-mode :hide}]]) @@ -191,7 +190,6 @@ (for [overlay overlays] [:& viewer-overlay {:overlay overlay - :file file :key (dm/str (:id overlay)) :page page :frame frame @@ -254,7 +252,6 @@ frame (get frames index) fullscreen? (mf/deref header/fullscreen-ref) - overlays (:overlays local) overlays (mf/deref current-overlays-ref) scroll (mf/use-state nil) @@ -464,7 +461,6 @@ [:& (mf/provider ctx/current-zoom) {:value zoom} [:& viewer-wrapper {:wrapper-size wrapper-size - :scroll @scroll :orig-frame orig-frame :orig-viewport-ref orig-viewport-ref :orig-size orig-size diff --git a/frontend/src/app/main/ui/viewer/comments.cljs b/frontend/src/app/main/ui/viewer/comments.cljs index dc7586d21..96c44b262 100644 --- a/frontend/src/app/main/ui/viewer/comments.cljs +++ b/frontend/src/app/main/ui/viewer/comments.cljs @@ -7,7 +7,6 @@ (ns app.main.ui.viewer.comments (:require [app.common.data :as d] - [app.common.data.macros :as dm] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] diff --git a/frontend/src/app/main/ui/viewer/header.cljs b/frontend/src/app/main/ui/viewer/header.cljs index 64f835ee7..2fbf99e51 100644 --- a/frontend/src/app/main/ui/viewer/header.cljs +++ b/frontend/src/app/main/ui/viewer/header.cljs @@ -10,7 +10,6 @@ [app.main.data.modal :as modal] [app.main.data.viewer :as dv] [app.main.data.viewer.shortcuts :as sc] - [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.export :refer [export-progress-widget]] diff --git a/frontend/src/app/main/ui/viewer/interactions.cljs b/frontend/src/app/main/ui/viewer/interactions.cljs index 3541f1b70..aa479c9cb 100644 --- a/frontend/src/app/main/ui/viewer/interactions.cljs +++ b/frontend/src/app/main/ui/viewer/interactions.cljs @@ -17,13 +17,12 @@ [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.dropdown :refer [dropdown]] - [app.main.ui.icons :as i] [app.main.ui.hooks :as h] + [app.main.ui.icons :as i] [app.main.ui.viewer.shapes :as shapes] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.keyboard :as kbd] - [app.util.object :as obj] [goog.events :as events] [rumext.alpha :as mf])) @@ -75,8 +74,7 @@ [:& wrapper {:shape frame :view-box vbox}]]]])) (mf/defc viewport - { - ::mf/wrap [mf/memo] + {::mf/wrap [mf/memo] ::mf/wrap-props false} [props] (let [;; NOTE: with `use-equal-memo` hook we ensure that all values @@ -90,7 +88,6 @@ frame (unchecked-get props "frame") base (unchecked-get props "base-frame")] - (mf/with-effect [mode] (let [on-click (fn [_] From 7af914eef07fce0d23b6de2556b8bb72f8adbeef Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 08:01:31 +0200 Subject: [PATCH 21/34] :paperclip: Properly print on console UI related errors --- frontend/src/app/main/ui.cljs | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index fd65d7569..768a86f1f 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -29,6 +29,7 @@ (mf/defc on-main-error [{:keys [error] :as props}] (mf/with-effect + (js/console.log error) (st/emit! (rt/assign-exception error))) [:span "Internal application error"]) From 1b42e324a2c52a5368cf2448ac0c78da6161e3e4 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 28 Jul 2022 09:37:50 +0200 Subject: [PATCH 22/34] :sparkles: Avoid recursive rerender and react warning --- .../app/main/ui/workspace/context_menu.cljs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index 11003df3a..54a440d12 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -8,6 +8,7 @@ "A workspace specific context menu (mouse right click)." (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.pages.helpers :as cph] [app.common.types.page :as ctp] [app.main.data.events :as ev] @@ -123,17 +124,25 @@ [:& menu-separator]])) (mf/defc context-menu-layer-position - [{:keys [hover-objs shapes]}] - (let [do-bring-forward #(st/emit! (dw/vertical-order-selected :up)) - do-bring-to-front #(st/emit! (dw/vertical-order-selected :top)) - do-send-backward #(st/emit! (dw/vertical-order-selected :down)) - do-send-to-back #(st/emit! (dw/vertical-order-selected :bottom)) - select-shapes (fn [id] #(st/emit! (dws/select-shape id)))] + [{:keys [shapes]}] + (let [do-bring-forward (mf/use-fn #(st/emit! (dw/vertical-order-selected :up))) + do-bring-to-front (mf/use-fn #(st/emit! (dw/vertical-order-selected :top))) + do-send-backward (mf/use-fn #(st/emit! (dw/vertical-order-selected :down))) + do-send-to-back (mf/use-fn #(st/emit! (dw/vertical-order-selected :bottom))) + select-shapes (fn [id] #(st/emit! (dws/select-shape id))) + + ;; NOTE: we use deref instead of mf/deref on objects because + ;; we really don't want rerender on object changes + hover-ids (deref refs/current-hover-ids) + objects (deref refs/workspace-page-objects) + hover-objs (into [] (keep (d/getf objects)) hover-ids)] + [:* (when (> (count hover-objs) 1) [:& menu-entry {:title (tr "workspace.shape.menu.select-layer")} (for [object hover-objs] [:& menu-entry {:title (:name object) + :key (dm/str (:id object)) :selected? (some #(= object %) shapes) :on-click (select-shapes (:id object)) :icon (si/element-icon {:shape object})}])]) @@ -435,14 +444,11 @@ :on-click do-delete}])) (mf/defc shape-context-menu + {::mf/wrap [mf/memo]} [{:keys [mdata] :as props}] (let [{:keys [disable-booleans? disable-flatten?]} mdata shapes (mf/deref refs/selected-objects) - hover-ids (mf/deref refs/current-hover-ids) - hover-objs (mf/deref (refs/objects-by-id hover-ids)) - props #js {:shapes shapes - :hover-objs hover-objs :disable-booleans? disable-booleans? :disable-flatten? disable-flatten?}] (when-not (empty? shapes) From c1348189d49f7b399127c4d9aad38002164d141d Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 23 Aug 2022 08:43:06 +0200 Subject: [PATCH 23/34] :bug: Fix path with images on binfile importation --- backend/src/app/rpc/commands/binfile.clj | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/src/app/rpc/commands/binfile.clj b/backend/src/app/rpc/commands/binfile.clj index 6885f5cf5..764f0651e 100644 --- a/backend/src/app/rpc/commands/binfile.clj +++ b/backend/src/app/rpc/commands/binfile.clj @@ -728,11 +728,16 @@ [data] (letfn [(process-map-form [form] (cond-> form - ;; Relink Image Shapes + ;; Relink image shapes (and (map? (:metadata form)) (= :image (:type form))) (update-in [:metadata :id] lookup-index) + ;; Relink paths with fill image + (and (map? (:fill-image form)) + (= :path (:type form))) + (update-in [:fill-image :id] lookup-index) + ;; This covers old shapes and the new :fills. (uuid? (:fill-color-ref-file form)) (update :fill-color-ref-file lookup-index) From 29223e8db8a0d3655a41236fbc8bd299340686e4 Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Tue, 23 Aug 2022 17:24:58 +0200 Subject: [PATCH 24/34] :bug: Fix multiselection with shift not working inside a library group --- CHANGES.md | 1 + .../src/app/main/ui/workspace/sidebar/assets.cljs | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 225d24b97..35cd26fef 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -54,6 +54,7 @@ - Fix props preserving on copy&paste texts [Taiga #3629](https://tree.taiga.io/project/penpot/issue/3629) by @andrewzhurov - Fix unexpected layers ungrouping on moving it [Taiga #3932](https://tree.taiga.io/project/penpot/issue/3932) by @andrewzhurov - Fix unexpected exception and behavior on colorpicker with gradients [Taiga #3448](https://tree.taiga.io/project/penpot/issue/3448) +- Fix multiselection with shift not working inside a library group [Taiga #3532](https://tree.taiga.io/project/penpot/issue/3532) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 8e408c060..68ace7369 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -1940,13 +1940,11 @@ (fn [asset-type asset-groups asset-id] (letfn [(flatten-groups [groups] - (concat - (get groups "" []) - (reduce concat - (into [] - (->> (filter #(seq (first %)) groups) - (map second) - (mapcat flatten-groups))))))] + (reduce concat [(get groups "" []) + (into [] + (->> (filter #(seq (first %)) groups) + (map second) + (mapcat flatten-groups)))]))] (let [selected-assets-type (get selected-assets asset-type) count-assets (count selected-assets-type)] (if (<= count-assets 0) From cb064358f86a236941c13b9e9283abe9f97b5303 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 24 Aug 2022 10:26:08 +0200 Subject: [PATCH 25/34] :bug: Fix permissions when moving comments --- backend/src/app/rpc/commands/comments.clj | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/backend/src/app/rpc/commands/comments.clj b/backend/src/app/rpc/commands/comments.clj index f7bf9e521..576f6599c 100644 --- a/backend/src/app/rpc/commands/comments.clj +++ b/backend/src/app/rpc/commands/comments.clj @@ -496,16 +496,14 @@ ;; --- COMMAND: Update comment thread position (s/def ::update-comment-thread-position - (s/keys :req-un [::profile-id ::id ::position ::frame-id])) + (s/keys :req-un [::profile-id ::id ::position ::frame-id ::share-id])) (sv/defmethod ::update-comment-thread-position {::doc/added "1.15"} - [{:keys [pool] :as cfg} {:keys [profile-id id position frame-id] :as params}] + [{:keys [pool] :as cfg} {:keys [profile-id id position frame-id share-id] :as params}] (db/with-atomic [conn pool] (let [thread (db/get-by-id conn :comment-thread id {:for-update true})] - (when-not (= (:owner-id thread) profile-id) - (ex/raise :type :validation - :code :not-allowed)) + (files/check-comment-permissions! conn profile-id (:file-id thread) share-id) (db/update! conn :comment-thread {:modified-at (dt/now) :position (db/pgpoint position) @@ -516,16 +514,14 @@ ;; --- COMMAND: Update comment frame (s/def ::update-comment-thread-frame - (s/keys :req-un [::profile-id ::id ::frame-id])) + (s/keys :req-un [::profile-id ::id ::frame-id ::share-id])) (sv/defmethod ::update-comment-thread-frame {::doc/added "1.15"} - [{:keys [pool] :as cfg} {:keys [profile-id id frame-id] :as params}] + [{:keys [pool] :as cfg} {:keys [profile-id id frame-id share-id] :as params}] (db/with-atomic [conn pool] (let [thread (db/get-by-id conn :comment-thread id {:for-update true})] - (when-not (= (:owner-id thread) profile-id) - (ex/raise :type :validation - :code :not-allowed)) + (files/check-comment-permissions! conn profile-id (:file-id thread) share-id) (db/update! conn :comment-thread {:modified-at (dt/now) :frame-id frame-id} From 8dfd74547ae3d917fb6a38f8ce1b533f298da6a2 Mon Sep 17 00:00:00 2001 From: Eva Date: Thu, 28 Jul 2022 09:30:17 +0200 Subject: [PATCH 26/34] :lipstick: Change some styles in viewer mode --- CHANGES.md | 1 + .../styles/main/layouts/handoff.scss | 50 +++++++++++++++++-- .../resources/styles/main/layouts/viewer.scss | 45 ++++++++++++++++- .../styles/main/partials/viewer-header.scss | 3 +- .../styles/main/partials/viewer.scss | 14 +++--- frontend/src/app/main/ui/viewer.cljs | 34 +++++++++---- frontend/src/app/main/ui/viewer/handoff.cljs | 12 ++++- 7 files changed, 135 insertions(+), 24 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c713129b5..04cbee7f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,6 +24,7 @@ ### :sparkles: New features +- Add some cosmetic changes in viewer mode [Taiga #3688](https://tree.taiga.io/project/penpot/us/3688) - Allow for nested and rotated boards inside other boards and groups [Taiga #2874](https://tree.taiga.io/project/penpot/us/2874?milestone=319982) - View mode improvements to enable access and use in different conditions [Taiga #3023](https://tree.taiga.io/project/penpot/us/3023) - Improved share link options. Now you can allow non-team members to comment and/or inspect [Taiga #3056] (https://tree.taiga.io/project/penpot/us/3056) diff --git a/frontend/resources/styles/main/layouts/handoff.scss b/frontend/resources/styles/main/layouts/handoff.scss index 3f8b6f151..ce61123d2 100644 --- a/frontend/resources/styles/main/layouts/handoff.scss +++ b/frontend/resources/styles/main/layouts/handoff.scss @@ -19,14 +19,35 @@ $width-settings-bar: 256px; } } +.fullscreen.handoff-layout.force-visible { + display: grid; + grid-template-rows: 1fr; + + & .viewer-header { + position: fixed; + top: 0; + transition: top 400ms ease 300ms; + margin-bottom: 0; + z-index: 2; + } + + & .viewer-bottom { + position: fixed; + bottom: 0; + transition: bottom 400ms ease 300ms; + z-index: 2; + } +} + .fullscreen.handoff-layout:not(.force-visible) { - .viewer-header { + & .viewer-header { width: 100%; position: fixed; top: -48px; left: 0; transition: top 400ms ease 300ms; - z-index: 25; + z-index: 2; + margin-bottom: 48px; &::after { content: " "; @@ -43,7 +64,29 @@ $width-settings-bar: 256px; transition: top 200ms; } - .viewer-content { + & .viewer-bottom { + width: 100%; + position: fixed; + bottom: -48px; + left: 0; + transition: bottom 400ms ease 300ms; + z-index: 2; + &::after { + content: " "; + position: absolute; + width: 100%; + height: 1rem; + left: 0; + bottom: 0px; + } + } + + & .viewer-bottom:hover { + bottom: 0px; + transition: bottom 200ms; + } + + & .viewer-content { grid-row: 1 / span 2; } } @@ -51,6 +94,7 @@ $width-settings-bar: 256px; .handoff-layout { .viewer-section { flex-wrap: nowrap; + margin-top: 0; &.fullscreen { .settings-bar, .settings-bar { diff --git a/frontend/resources/styles/main/layouts/viewer.scss b/frontend/resources/styles/main/layouts/viewer.scss index 28a817ad7..840c2b559 100644 --- a/frontend/resources/styles/main/layouts/viewer.scss +++ b/frontend/resources/styles/main/layouts/viewer.scss @@ -1,4 +1,5 @@ .viewer-layout { + height: 100vh; display: grid; grid-template-rows: 48px auto; grid-template-columns: 1fr; @@ -15,14 +16,34 @@ } } +.fullscreen.viewer-layout.force-visible { + grid-template-rows: 1fr; + & .viewer-header { + position: fixed; + top: 0; + transition: top 400ms ease 300ms; + margin-bottom: 0; + z-index: 2; + } + + & .viewer-bottom { + position: fixed; + bottom: 0; + transition: bottom 400ms ease 300ms; + z-index: 2; + } +} + .fullscreen.viewer-layout:not(.force-visible) { + grid-template-rows: 1fr; & .viewer-header { width: 100%; position: fixed; top: -48px; left: 0; transition: top 400ms ease 300ms; - z-index: 1; + z-index: 2; + margin-bottom: 48px; &::after { content: " "; position: absolute; @@ -38,6 +59,28 @@ transition: top 200ms; } + & .viewer-bottom { + width: 100%; + position: fixed; + bottom: -48px; + left: 0; + transition: bottom 400ms ease 300ms; + z-index: 2; + &::after { + content: " "; + position: absolute; + width: 100%; + height: 1rem; + left: 0; + bottom: 0px; + } + } + + & .viewer-bottom:hover { + bottom: 0px; + transition: bottom 200ms; + } + & .viewer-content { grid-row: 1 / span 2; } diff --git a/frontend/resources/styles/main/partials/viewer-header.scss b/frontend/resources/styles/main/partials/viewer-header.scss index 11871eee2..b8b3a5ccc 100644 --- a/frontend/resources/styles/main/partials/viewer-header.scss +++ b/frontend/resources/styles/main/partials/viewer-header.scss @@ -6,7 +6,8 @@ grid-template-columns: 45% 10% 45%; height: 48px; padding: 0 $size-4 0 55px; - position: relative; + top: 0; + position: absolute; justify-content: space-between; width: 100vw; diff --git a/frontend/resources/styles/main/partials/viewer.scss b/frontend/resources/styles/main/partials/viewer.scss index 00a0c14bc..30845460a 100644 --- a/frontend/resources/styles/main/partials/viewer.scss +++ b/frontend/resources/styles/main/partials/viewer.scss @@ -1,6 +1,5 @@ .viewer-content { background-color: black; - display: grid; grid-template-rows: 232px auto; grid-template-columns: 1fr; @@ -8,19 +7,19 @@ .viewer-section { height: calc(100vh - 48px); - &.fullscreen { - height: 100vh; - } grid-row: 1 / span 2; grid-column: 1 / span 1; - display: flex; justify-content: center; align-items: center; flex-flow: wrap; - overflow: auto; + &.fullscreen { + height: 100vh; + margin-top: 0px; + } + & .viewer-go-prev, & .viewer-go-next { position: absolute; @@ -28,7 +27,7 @@ display: flex; align-items: center; width: 53px; - + z-index: 2; .arrow { display: none; align-items: center; @@ -87,6 +86,7 @@ width: 100%; display: flex; justify-content: space-between; + align-items: center; &.left-bar { width: calc(100% - 512px); diff --git a/frontend/src/app/main/ui/viewer.cljs b/frontend/src/app/main/ui/viewer.cljs index ced7b3c6a..0ccf2d9bb 100644 --- a/frontend/src/app/main/ui/viewer.cljs +++ b/frontend/src/app/main/ui/viewer.cljs @@ -275,6 +275,19 @@ interactions-mode (:interactions-mode local) + click-on-screen + (mf/use-callback + (fn [event] + (let [origin (dom/get-target event) + over-section? (dom/class? origin "viewer-section") + layout (dom/get-element "viewer-layout") + has-force? (dom/class? layout "force-visible")] + + (when over-section? + (if has-force? + (dom/remove-class! layout "force-visible") + (dom/add-class! layout "force-visible")))))) + on-click (mf/use-fn (mf/deps section) @@ -414,17 +427,15 @@ :handoff-layout (= section :handoff) :fullscreen fullscreen?)} - [:& header/header - {:project project - :index index - :file file - :page page - :frame frame - :permissions permissions - :zoom zoom - :section section}] - [:div.viewer-content + [:& header/header {:project project + :index index + :file file + :page page + :frame frame + :permissions permissions + :zoom zoom + :section section}] [:div.thumbnail-close {:on-click #(st/emit! dv/close-thumbnails-panel) :class (dom/classnames :invisible (not (:show-thumbnails local false)))}] [:& thumbnails-panel {:frames frames @@ -434,7 +445,8 @@ :thumbnail-data (:thumbnails file)}] [:section.viewer-section {:id "viewer-section" :ref viewer-section-ref - :class (if fullscreen? "fullscreen" "")} + :class (if fullscreen? "fullscreen" "") + :on-click click-on-screen} (cond (empty? frames) [:section.empty-state diff --git a/frontend/src/app/main/ui/viewer/handoff.cljs b/frontend/src/app/main/ui/viewer/handoff.cljs index 2eb108de6..bb488fdba 100644 --- a/frontend/src/app/main/ui/viewer/handoff.cljs +++ b/frontend/src/app/main/ui/viewer/handoff.cljs @@ -22,7 +22,17 @@ (fn [event] (dom/prevent-default event) (dom/stop-propagation event) - (st/emit! (dv/select-shape (:id frame))))) + (st/emit! (dv/select-shape (:id frame))) + + (let [origin (dom/get-target event) + over-section? (dom/class? origin "handoff-svg-container") + layout (dom/get-element "viewer-layout") + has-force? (dom/class? layout "force-visible")] + + (when over-section? + (if has-force? + (dom/remove-class! layout "force-visible") + (dom/add-class! layout "force-visible")))))) (mf/defc viewport [{:keys [local file page frame index viewer-pagination size]}] From be1c19e71845a9f50165c373009c7c52fffeca86 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 24 Aug 2022 10:59:38 +0200 Subject: [PATCH 27/34] :bug: Fix comments positioning on viewer (regression) --- frontend/src/app/main/ui/viewer/comments.cljs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/frontend/src/app/main/ui/viewer/comments.cljs b/frontend/src/app/main/ui/viewer/comments.cljs index 96c44b262..8b1cf5c16 100644 --- a/frontend/src/app/main/ui/viewer/comments.cljs +++ b/frontend/src/app/main/ui/viewer/comments.cljs @@ -91,7 +91,6 @@ (mf/defc comments-layer [{:keys [zoom file users frame page] :as props}] - (prn "comments-layer") (let [profile (mf/deref refs/profile) local (mf/deref refs/comments-local) @@ -113,12 +112,12 @@ modifier1 (mf/with-memo [frame-corner] (-> (gmt/matrix) (gmt/translate (gpt/negate frame-corner)))) + modifier2 (mf/with-memo [frame-corner] (-> (gpt/point frame-corner) (gmt/translate-matrix))) - - threads (mf/with-memo [threads-map positions] + threads (mf/with-memo [threads-map positions frame local profile] (->> (vals threads-map) (map (partial update-thread-position positions)) (filter #(= (:frame-id %) (:id frame))) @@ -126,7 +125,6 @@ (filter (fn [{:keys [position]}] (gsh/has-point? frame position))))) - on-bubble-click (mf/use-fn (mf/deps open-thread-id) @@ -160,9 +158,7 @@ (mf/use-fn (mf/deps frame-id modifier2) (fn [draft] - (let [params (-> draft - (update :position gpt/transform modifier2) - (assoc :frame-id frame-id))] + (let [params (assoc draft :frame-id frame-id)] (st/emit! (dcm/create-thread-on-viewer params) (dcm/close-thread)))))] From 8ce8b3fdefbce19a96754beb1013b75948e3d0d2 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 24 Aug 2022 10:59:56 +0200 Subject: [PATCH 28/34] :paperclip: Update docker images related files --- docker/devenv/Dockerfile | 2 +- docker/images/Dockerfile.exporter | 2 +- docker/images/files/config.js | 11 ----------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/docker/devenv/Dockerfile b/docker/devenv/Dockerfile index d3af5c86a..3a7138921 100644 --- a/docker/devenv/Dockerfile +++ b/docker/devenv/Dockerfile @@ -3,7 +3,7 @@ LABEL maintainer="Andrey Antukh " ARG DEBIAN_FRONTEND=noninteractive -ENV NODE_VERSION=v16.16.0 \ +ENV NODE_VERSION=v16.17.0 \ CLOJURE_VERSION=1.11.1.1149 \ CLJKONDO_VERSION=2022.06.22 \ BABASHKA_VERSION=0.8.156 \ diff --git a/docker/images/Dockerfile.exporter b/docker/images/Dockerfile.exporter index 5b1e90458..144b5a9c1 100644 --- a/docker/images/Dockerfile.exporter +++ b/docker/images/Dockerfile.exporter @@ -5,7 +5,7 @@ ARG DEBIAN_FRONTEND=noninteractive ENV LANG=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \ - NODE_VERSION=v16.15.1 + NODE_VERSION=v16.17.0 RUN set -ex; \ mkdir -p /etc/resolvconf/resolv.conf.d; \ diff --git a/docker/images/files/config.js b/docker/images/files/config.js index ef86caa0e..7bc9ce940 100644 --- a/docker/images/files/config.js +++ b/docker/images/files/config.js @@ -1,13 +1,2 @@ // Frontend configuration - -//var penpotPublicURI = "https://penpot.example.com"; -//var penpotDemoWarning = ; -//var penpotAllowDemoUsers = ; -//var penpotGoogleClientID = ""; -//var penpotGitlabClientID = ""; -//var penpotGithubClientID = ""; -//var penpotOIDCClientID = ""; -//var penpotLoginWithLDAP = ; -//var penpotRegistrationEnabled = ; -//var penpotAnalyticsEnabled = ; //var penpotFlags = ""; From 8a33a63f9115279af16fb9fab523ac36901c024b Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 24 Aug 2022 12:08:38 +0200 Subject: [PATCH 29/34] :bug: Fix permissions when moving comments --- backend/src/app/rpc/commands/comments.clj | 6 ++++-- frontend/src/app/main/ui/workspace.cljs | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/src/app/rpc/commands/comments.clj b/backend/src/app/rpc/commands/comments.clj index 576f6599c..0e4ce7ff6 100644 --- a/backend/src/app/rpc/commands/comments.clj +++ b/backend/src/app/rpc/commands/comments.clj @@ -496,7 +496,8 @@ ;; --- COMMAND: Update comment thread position (s/def ::update-comment-thread-position - (s/keys :req-un [::profile-id ::id ::position ::frame-id ::share-id])) + (s/keys :req-un [::profile-id ::id ::position ::frame-id] + :opt-un [::share-id])) (sv/defmethod ::update-comment-thread-position {::doc/added "1.15"} @@ -514,7 +515,8 @@ ;; --- COMMAND: Update comment frame (s/def ::update-comment-thread-frame - (s/keys :req-un [::profile-id ::id ::frame-id ::share-id])) + (s/keys :req-un [::profile-id ::id ::frame-id] + :opt-un [::share-id])) (sv/defmethod ::update-comment-thread-frame {::doc/added "1.15"} diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index 17b1fce61..808ee67f0 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -8,6 +8,7 @@ (:require [app.common.colors :as clr] [app.common.data.macros :as dm] + [app.main.data.comments :as dcm] [app.main.data.messages :as msg] [app.main.data.workspace :as dw] [app.main.data.workspace.persistence :as dwp] @@ -127,6 +128,7 @@ (mf/with-effect [project-id file-id] (st/emit! (dw/initialize-file project-id file-id)) + (st/emit! (dcm/retrieve-comment-threads file-id)) (fn [] (st/emit! ::dwp/force-persist (dw/finalize-file project-id file-id)))) From 44330ffb3bea1149351273bacd7e8f7c4576e60f Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 24 Aug 2022 12:16:54 +0200 Subject: [PATCH 30/34] :bug: Fix permissions when moving comments --- frontend/src/app/main/data/workspace.cljs | 4 +++- frontend/src/app/main/ui/workspace.cljs | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index c333f8874..b31a77e6d 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -22,6 +22,7 @@ [app.common.types.shape :as cts] [app.common.uuid :as uuid] [app.config :as cfg] + [app.main.data.comments :as dcm] [app.main.data.events :as ev] [app.main.data.messages :as msg] [app.main.data.users :as du] @@ -113,7 +114,8 @@ ptk/WatchEvent (watch [_ _ stream] (rx/merge - (rx/of (dwp/fetch-bundle project-id file-id)) + (rx/of (dwp/fetch-bundle project-id file-id) + (dcm/retrieve-comment-threads file-id)) ;; Initialize notifications (websocket connection) and the file persistence (->> stream diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index 808ee67f0..17b1fce61 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -8,7 +8,6 @@ (:require [app.common.colors :as clr] [app.common.data.macros :as dm] - [app.main.data.comments :as dcm] [app.main.data.messages :as msg] [app.main.data.workspace :as dw] [app.main.data.workspace.persistence :as dwp] @@ -128,7 +127,6 @@ (mf/with-effect [project-id file-id] (st/emit! (dw/initialize-file project-id file-id)) - (st/emit! (dcm/retrieve-comment-threads file-id)) (fn [] (st/emit! ::dwp/force-persist (dw/finalize-file project-id file-id)))) From aa4344a76f652b36c15ed69ff7a07c6d6b43e8fd Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Wed, 24 Aug 2022 09:39:39 +0200 Subject: [PATCH 31/34] :bug: Fix drag and drop graphic assets in groups --- CHANGES.md | 1 + .../src/app/main/ui/workspace/sidebar/assets.cljs | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 04cbee7f2..2fe22e810 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -56,6 +56,7 @@ - Fix unexpected layers ungrouping on moving it [Taiga #3932](https://tree.taiga.io/project/penpot/issue/3932) by @andrewzhurov - Fix unexpected exception and behavior on colorpicker with gradients [Taiga #3448](https://tree.taiga.io/project/penpot/issue/3448) - Fix multiselection with shift not working inside a library group [Taiga #3532](https://tree.taiga.io/project/penpot/issue/3532) +- Fix drag and drop graphic assets in groups [Taiga #4002](https://tree.taiga.io/project/penpot/issue/4002) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index aab1c95a6..ed2dcc426 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -892,6 +892,17 @@ (seq (:colors selected-assets)) (seq (:typographies selected-assets))) + extract-path-if-missing + (fn [graphic] + (let [[path name] (cph/parse-path-name (:name graphic))] + (if (and + (= (:name graphic) name) + (contains? graphic :path)) + graphic + (assoc graphic :path path :name name)))) + + objects (->> objects + (map extract-path-if-missing)) groups (group-assets objects reverse-sort?) @@ -1626,7 +1637,9 @@ extract-path-if-missing (fn [typography] (let [[path name] (cph/parse-path-name (:name typography))] - (if (= (:name typography) name) + (if (and + (= (:name typography) name) + (contains? typography :path)) typography (assoc typography :path path :name name)))) From 08ccd7be70b17662beee41be1e5db5f1a0e1c6fb Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 24 Aug 2022 14:03:38 +0200 Subject: [PATCH 32/34] :bug: Fix drag and drop boards --- frontend/src/app/main/data/workspace/transforms.cljs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 02d8d7fc8..0cf7664d3 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -16,6 +16,7 @@ [app.common.pages.common :as cpc] [app.common.pages.helpers :as cph] [app.common.spec :as us] + [app.common.uuid :as uuid] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.collapse :as dwc] [app.main.data.workspace.comments :as dwcm] @@ -876,7 +877,15 @@ changes (-> (pcb/empty-changes it page-id) (pcb/with-objects objects) - (pcb/update-shapes moving-frames (fn [shape] (assoc shape :hide-in-viewer true))) + (pcb/update-shapes moving-frames (fn [shape] + ;; Hide in viwer must be enabled just when a board is moved inside another artboard an nested to it, we have to avoid situations like: + ;; - Moving inside the same frame + ;; - Moving outside the frame + (cond-> shape + (and (not= frame-id (:id shape)) + (not= frame-id (:frame-id shape)) + (not= frame-id uuid/zero)) + (assoc :hide-in-viewer true)))) (pcb/change-parent frame-id moving-shapes))] (when-not (empty? changes) From a1654aeb0eacb74f5e078ce63063c290c507ebd4 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 25 Aug 2022 09:11:00 +0200 Subject: [PATCH 33/34] :bug: Fix viewer scroll problems --- CHANGES.md | 1 + frontend/resources/styles/main/partials/viewer.scss | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2fe22e810..c4cd604ba 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -36,6 +36,7 @@ ### :bug: Bugs fixed +- Fix viewer scroll problems [Taiga 3403](https://tree.taiga.io/project/penpot/issue/3403) - Fix hide html options on handoff [Taiga 3533](https://tree.taiga.io/project/penpot/issue/3533) - Fix share prototypes overlay and stroke [Taiga #3994](https://tree.taiga.io/project/penpot/issue/3994) - Fix border radious on boolean operations [Taiga #3959](https://tree.taiga.io/project/penpot/issue/3959) diff --git a/frontend/resources/styles/main/partials/viewer.scss b/frontend/resources/styles/main/partials/viewer.scss index 30845460a..4fa9b3de1 100644 --- a/frontend/resources/styles/main/partials/viewer.scss +++ b/frontend/resources/styles/main/partials/viewer.scss @@ -10,7 +10,6 @@ grid-row: 1 / span 2; grid-column: 1 / span 1; display: flex; - justify-content: center; align-items: center; flex-flow: wrap; overflow: auto; @@ -56,8 +55,8 @@ } & .viewer-go-next { - right: 0; - padding-right: 29px; + right: 8px; + width: 46px; svg { margin-left: 2px; } @@ -81,12 +80,13 @@ & .viewer-bottom { position: absolute; - bottom: 0; - height: 50px; + bottom: 8px; + height: 30px; width: 100%; display: flex; justify-content: space-between; align-items: center; + z-index: 2; &.left-bar { width: calc(100% - 512px); @@ -128,6 +128,8 @@ } & .viewer-wrapper { + margin-left: auto; + margin-right: auto; position: relative; } From 85ec1668f3ad12ca7978f39592b7b33d862b22d0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 25 Aug 2022 11:46:32 +0200 Subject: [PATCH 34/34] :bug: Add missing rpc-command definition on metrics --- backend/src/app/metrics.clj | 6 ++++++ backend/src/app/rpc.clj | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/src/app/metrics.clj b/backend/src/app/metrics.clj index 2ae0223dc..4c5e10e19 100644 --- a/backend/src/app/metrics.clj +++ b/backend/src/app/metrics.clj @@ -52,6 +52,12 @@ :labels ["name"] :type :histogram} + :rpc-command-timing + {:name "rpc_command_timing" + :help "RPC command method call timming." + :labels ["name"] + :type :histogram} + :rpc-query-timing {:name "rpc_query_timing" :help "RPC query method call timing." diff --git a/backend/src/app/rpc.clj b/backend/src/app/rpc.clj index 804a62412..66ffacc52 100644 --- a/backend/src/app/rpc.clj +++ b/backend/src/app/rpc.clj @@ -204,7 +204,6 @@ (defn- process-method [cfg vfn] (let [mdata (meta vfn)] - ;; (prn mdata) [(keyword (::sv/name mdata)) (wrap cfg vfn mdata)]))