0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-26 06:31:26 -05:00

🐛 Fix problem with grid components thumbnails

This commit is contained in:
alonso.torres 2023-12-07 14:24:19 +01:00
parent 39b41d7037
commit f6c2d0646d
4 changed files with 89 additions and 26 deletions

View file

@ -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]}

View file

@ -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}])))]])))

View file

@ -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)

View file

@ -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]