0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-11 23:31:21 -05:00

Fix nested frames with thumbnails

This commit is contained in:
alonso.torres 2022-06-10 15:17:20 +02:00
parent a37233be1e
commit cab2b8469e
4 changed files with 85 additions and 62 deletions

View file

@ -674,3 +674,12 @@
(into selected
(mapcat #(get-children-ids objects %))
selected))
(defn get-shape-id-root-frame
[objects shape-id]
(->> (get-parents-seq objects shape-id)
(map (d/getf objects))
(d/seek #(and (= :frame (:type %))
(= uuid/zero (:frame-id %))))
:id))

View file

@ -10,6 +10,7 @@
[app.common.logging :as log]
[app.common.pages :as cp]
[app.common.pages.changes-builder :as pcb]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.spec.change :as spec.change]
[app.common.uuid :as uuid]
@ -126,9 +127,7 @@
[]))]
(into #{}
(comp (mapcat change->ids)
(keep #(if (= :frame (get-in objects [% :type]))
%
(get-in objects [% :frame-id])))
(keep #(cph/get-shape-id-root-frame objects %))
(remove #(= uuid/zero %)))
changes)))

View file

@ -70,6 +70,14 @@
selected (dm/get-in state [:workspace-local :selected])]
(process-selected-shapes objects selected options))))
(defn lookup-shape
([state id]
(lookup-shape state (:current-page-id state) id))
([state page-id id]
(let [objects (lookup-page-objects state page-id)]
(get objects id))))
(defn lookup-shapes
([state ids]
(lookup-shapes state (:current-page-id state) ids))

View file

@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.thumbnails :as dwt]
@ -58,77 +59,83 @@
::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
thumbnail? (unchecked-get props "thumbnail?")
objects (wsh/lookup-page-objects @st/state)
render-id (mf/use-memo #(str (uuid/next)))
fonts (mf/use-memo (mf/deps shape objects) #(ff/shape->fonts shape objects))
fonts (-> fonts (hooks/use-equal-memo))
force-render (mf/use-state false)
;; Thumbnail data
(let [shape (unchecked-get props "shape")
frame-id (:id shape)
page-id (mf/use-ctx ctx/current-page-id)
;; References to the current rendered node and the its parentn
node-ref (mf/use-var nil)
;; when `true` we've called the mount for the frame
rendered? (mf/use-var false)
objects (wsh/lookup-page-objects @st/state)
;; Modifiers
modifiers-ref (mf/use-memo (mf/deps frame-id) #(refs/workspace-modifiers-by-frame-id frame-id))
modifiers (mf/deref modifiers-ref)
disable-thumbnail? (d/not-empty? (dm/get-in modifiers [(:id shape) :modifiers]))
[on-load-frame-dom render-frame? thumbnail-renderer]
(ftr/use-render-thumbnail page-id shape node-ref rendered? disable-thumbnail? @force-render)
[on-frame-load in-memory?]
(fns/use-node-store thumbnail? node-ref rendered? render-frame?)]
modifiers (mf/deref modifiers-ref)]
(fdm/use-dynamic-modifiers objects @node-ref modifiers)
(mf/use-effect
(mf/deps fonts)
(fn []
(->> (rx/from fonts)
(rx/merge-map fonts/fetch-font-css)
(rx/ignore))))
(if-not (cph/root-frame? shape)
[:& frame-shape {:shape shape :ref node-ref}]
(mf/use-effect
(fn []
;; When a change in the data is received a "force-render" event is emited
;; that will force the component to be mounted in memory
(let [sub
(->> (dwt/force-render-stream (:id shape))
(rx/take-while #(not @rendered?))
(rx/subs #(reset! force-render true)))]
#(when sub
(rx/dispose! sub)))))
;; If the current shape is root we handle its thumbnail and the dynamic modifiers
(let [thumbnail? (unchecked-get props "thumbnail?")
(mf/use-effect
(mf/deps shape fonts thumbnail? on-load-frame-dom @force-render render-frame?)
(fn []
(when (and (some? @node-ref) (or @rendered? (not thumbnail?) @force-render render-frame?))
(mf/mount
(mf/element frame-shape
#js {:ref on-load-frame-dom :shape shape :fonts fonts})
render-id (mf/use-memo #(str (uuid/next)))
fonts (mf/use-memo (mf/deps shape objects) #(ff/shape->fonts shape objects))
fonts (-> fonts (hooks/use-equal-memo))
@node-ref)
(when (not @rendered?) (reset! rendered? true)))))
force-render (mf/use-state false)
[:& (mf/provider ctx/render-ctx) {:value render-id}
[:g.frame-container {:id (dm/str "frame-container-" (:id shape))
:key "frame-container"
:ref on-frame-load
:opacity (when (:hidden shape) 0)}
[:& ff/fontfaces-style {:fonts fonts}]
[:g.frame-thumbnail-wrapper
{:id (dm/str "thumbnail-container-" (:id shape))
;; Hide the thumbnail when not displaying
:opacity (when (and @rendered? (not thumbnail?) (not render-frame?) (not in-memory?)) 0)}
thumbnail-renderer]]]))))
;; Thumbnail data
page-id (mf/use-ctx ctx/current-page-id)
;; when `true` we've called the mount for the frame
rendered? (mf/use-var false)
disable-thumbnail? (d/not-empty? (dm/get-in modifiers [(:id shape) :modifiers]))
[on-load-frame-dom render-frame? thumbnail-renderer]
(ftr/use-render-thumbnail page-id shape node-ref rendered? disable-thumbnail? @force-render)
[on-frame-load in-memory?]
(fns/use-node-store thumbnail? node-ref rendered? render-frame?)]
(mf/use-effect
(mf/deps fonts)
(fn []
(->> (rx/from fonts)
(rx/merge-map fonts/fetch-font-css)
(rx/ignore))))
(mf/use-effect
(fn []
;; When a change in the data is received a "force-render" event is emited
;; that will force the component to be mounted in memory
(let [sub
(->> (dwt/force-render-stream (:id shape))
(rx/take-while #(not @rendered?))
(rx/subs #(reset! force-render true)))]
#(when sub
(rx/dispose! sub)))))
(mf/use-effect
(mf/deps shape fonts thumbnail? on-load-frame-dom @force-render render-frame?)
(fn []
(when (and (some? @node-ref) (or @rendered? (not thumbnail?) @force-render render-frame?))
(mf/mount
(mf/element frame-shape
#js {:ref on-load-frame-dom :shape shape :fonts fonts})
@node-ref)
(when (not @rendered?) (reset! rendered? true)))))
[:& (mf/provider ctx/render-ctx) {:value render-id}
[:g.frame-container {:id (dm/str "frame-container-" (:id shape))
:key "frame-container"
:ref on-frame-load
:opacity (when (:hidden shape) 0)}
[:& ff/fontfaces-style {:fonts fonts}]
[:g.frame-thumbnail-wrapper
{:id (dm/str "thumbnail-container-" (:id shape))
;; Hide the thumbnail when not displaying
:opacity (when (and @rendered? (not thumbnail?) (not render-frame?) (not in-memory?)) 0)}
thumbnail-renderer]]]))))))