From f6c2d0646dc32a361635e9c5ea288fe1afd494a1 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 7 Dec 2023 14:24:19 +0100 Subject: [PATCH] :bug: Fix problem with grid components thumbnails --- frontend/src/app/main/render.cljs | 71 +++++++++++++++++-- frontend/src/app/main/ui/shapes/frame.cljs | 8 +-- .../main/ui/shapes/grid_layout_viewer.cljs | 4 +- .../ui/workspace/sidebar/assets/common.cljs | 32 +++++---- 4 files changed, 89 insertions(+), 26 deletions(-) diff --git a/frontend/src/app/main/render.cljs b/frontend/src/app/main/render.cljs index 89f1e3288..8e46f895a 100644 --- a/frontend/src/app/main/render.cljs +++ b/frontend/src/app/main/render.cljs @@ -26,6 +26,7 @@ [app.common.types.file :as ctf] [app.common.types.modifiers :as ctm] [app.common.types.shape-tree :as ctst] + [app.common.types.shape.layout :as ctl] [app.config :as cfg] [app.main.fonts :as fonts] [app.main.ui.context :as muc] @@ -34,6 +35,7 @@ [app.main.ui.shapes.embed :as embed] [app.main.ui.shapes.export :as export] [app.main.ui.shapes.frame :as frame] + [app.main.ui.shapes.grid-layout-viewer :refer [grid-layout-viewer]] [app.main.ui.shapes.group :as group] [app.main.ui.shapes.image :as image] [app.main.ui.shapes.path :as path] @@ -304,11 +306,22 @@ :fill "none"} [:& shape-wrapper {:shape frame}]]])) +(mf/defc empty-grids + {::mf/wrap-props false} + [{:keys [root-shape-id objects]}] + (let [empty-grids + (->> (cons root-shape-id (cfh/get-children-ids objects root-shape-id)) + (filter #(ctl/grid-layout? objects %)) + (map #(get objects %)) + (filter #(empty? (:shapes %))))] + (for [grid empty-grids] + [:& grid-layout-viewer {:shape grid :objects objects}]))) + ;; Component for rendering a thumbnail of a single componenent. Mainly ;; used to render thumbnails on assets panel. (mf/defc component-svg {::mf/wrap [mf/memo #(mf/deferred % ts/idle-then-raf)]} - [{:keys [objects root-shape zoom] :or {zoom 1} :as props}] + [{:keys [objects root-shape show-grids? zoom] :or {zoom 1} :as props}] (when root-shape (let [root-shape-id (:id root-shape) include-metadata (mf/use-ctx export/include-metadata-ctx) @@ -350,9 +363,59 @@ :xmlns:penpot (when include-metadata "https://penpot.app/xmlns") :fill "none"} - [:> shape-container {:shape root-shape'} - [:& (mf/provider muc/is-component?) {:value true} - [:& root-shape-wrapper {:shape root-shape' :view-box vbox}]]]]))) + [:* + [:> shape-container {:shape root-shape'} + [:& (mf/provider muc/is-component?) {:value true} + [:& root-shape-wrapper {:shape root-shape' :view-box vbox}]]] + + (when show-grids? + [:& empty-grids {:root-shape-id root-shape-id :objects objects}])]]))) + +(mf/defc component-svg-thumbnail + {::mf/wrap [mf/memo #(mf/deferred % ts/idle-then-raf)]} + [{:keys [thumbnail-uri on-error show-grids? + objects root-shape zoom] :or {zoom 1} :as props}] + + (when root-shape + (let [root-shape-id (:id root-shape) + + vector + (mf/use-memo + (mf/deps (:x root-shape) (:y root-shape)) + (fn [] + (-> (gpt/point (:x root-shape) (:y root-shape)) + (gpt/negate)))) + + objects + (mf/use-memo + (mf/deps vector objects root-shape-id) + (fn [] + (let [children-ids (cons root-shape-id (cfh/get-children-ids objects root-shape-id)) + update-fn #(update %1 %2 gsh/transform-shape (ctm/move-modifiers vector))] + (reduce update-fn objects children-ids)))) + + root-shape' (get objects root-shape-id) + + width (:width root-shape' 0) + height (:height root-shape' 0) + width-zoom (* (:width root-shape') zoom) + height-zoom (* (:height root-shape') zoom) + vbox (format-viewbox {:width width :height height})] + + [:svg {:view-box vbox + :width (ust/format-precision width-zoom viewbox-decimal-precision) + :height (ust/format-precision height-zoom viewbox-decimal-precision) + :version "1.1" + :xmlns "http://www.w3.org/2000/svg" + :xmlnsXlink "http://www.w3.org/1999/xlink" + :fill "none"} + [:foreignObject {:x 0 :y 0 :width width :height height } + [:img {:src thumbnail-uri + :on-error on-error + :loading "lazy" + :decoding "async"}]] + (when show-grids? + [:& empty-grids {:root-shape-id root-shape-id :objects objects}])]))) (mf/defc object-svg {::mf/wrap [mf/memo]} diff --git a/frontend/src/app/main/ui/shapes/frame.cljs b/frontend/src/app/main/ui/shapes/frame.cljs index 6d8753c12..c7398d130 100644 --- a/frontend/src/app/main/ui/shapes/frame.cljs +++ b/frontend/src/app/main/ui/shapes/frame.cljs @@ -15,7 +15,6 @@ [app.main.ui.context :as muc] [app.main.ui.shapes.attrs :as attrs] [app.main.ui.shapes.custom-stroke :refer [shape-fills shape-strokes]] - [app.main.ui.shapes.grid-layout-viewer :refer [grid-layout-viewer]] [app.util.debug :as dbg] [app.util.object :as obj] [rumext.v2 :as mf])) @@ -165,7 +164,6 @@ [props] (let [shape (unchecked-get props "shape") childs (unchecked-get props "childs") - is-component? (mf/use-ctx muc/is-component?) childs (cond-> childs (ctl/any-layout? shape) (cfh/sort-layout-children-z-index))] @@ -175,9 +173,5 @@ (for [item childs] (let [id (dm/get-prop item :id)] (when (some? id) - [:& shape-wrapper {:key (dm/str id) :shape item}])))] - - (when (and ^boolean is-component? - ^boolean (empty? childs)) - [:& grid-layout-viewer {:shape shape :childs childs}])]))) + [:& shape-wrapper {:key (dm/str id) :shape item}])))]]))) diff --git a/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs b/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs index a5d7486a3..6138d81ac 100644 --- a/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs +++ b/frontend/src/app/main/ui/shapes/grid_layout_viewer.cljs @@ -15,7 +15,6 @@ [app.common.geom.shapes.grid-layout :as gsg] [app.common.geom.shapes.points :as gpo] [app.common.types.shape.layout :as ctl] - [app.main.refs :as refs] [rumext.v2 :as mf])) (mf/defc grid-cell-area-label @@ -85,9 +84,8 @@ {::mf/wrap-props false} [props] (let [shape (unchecked-get props "shape") - objects (mf/deref refs/workspace-page-objects) + objects (unchecked-get props "objects") bounds (d/lazy-map (keys objects) #(gsh/shape->points (get objects %))) - children (->> (cfh/get-immediate-children objects (:id shape)) (remove :hidden) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs index 0409d4445..53cd48ac6 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs @@ -19,7 +19,7 @@ [app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.undo :as dwu] [app.main.refs :as refs] - [app.main.render :refer [component-svg]] + [app.main.render :refer [component-svg component-svg-thumbnail]] [app.main.store :as st] [app.main.ui.components.context-menu :refer [context-menu]] [app.main.ui.components.context-menu-a11y :refer [context-menu-a11y]] @@ -283,18 +283,26 @@ {::mf/wrap-props false} [{:keys [file-id root-shape component container]}] (let [retry (mf/use-state 0) - thumbnail-uri (get-component-thumbnail-uri file-id component)] - (if (some? thumbnail-uri) - [:img {:src thumbnail-uri - :on-error (fn [] - (when (@retry < 3) - (inc retry))) - :loading "lazy" - :decoding "async" - :class (dom/classnames (css :thumbnail) true)}] - [:& component-svg {:root-shape root-shape - :objects (:objects container)}]))) + thumbnail-uri (get-component-thumbnail-uri file-id component) + handle-error + (mf/use-fn + (mf/deps @retry) + (fn [] + (when (@retry < 3) + (inc retry))))] + (if (some? thumbnail-uri) + [:& component-svg-thumbnail + {:thumbnail-uri thumbnail-uri + :on-error handle-error + :root-shape root-shape + :objects (:objects container) + :show-grids? true}] + + [:& component-svg + {:root-shape root-shape + :objects (:objects container) + :show-grids? true}]))) (defn generate-components-menu-entries [shapes components-v2]