mirror of
https://github.com/penpot/penpot.git
synced 2025-03-12 15:51:37 -05:00
✨ Fix nested frames with thumbnails
This commit is contained in:
parent
a37233be1e
commit
cab2b8469e
4 changed files with 85 additions and 62 deletions
|
@ -674,3 +674,12 @@
|
||||||
(into selected
|
(into selected
|
||||||
(mapcat #(get-children-ids objects %))
|
(mapcat #(get-children-ids objects %))
|
||||||
selected))
|
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))
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.common.pages.changes-builder :as pcb]
|
[app.common.pages.changes-builder :as pcb]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.spec.change :as spec.change]
|
[app.common.spec.change :as spec.change]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
@ -126,9 +127,7 @@
|
||||||
[]))]
|
[]))]
|
||||||
(into #{}
|
(into #{}
|
||||||
(comp (mapcat change->ids)
|
(comp (mapcat change->ids)
|
||||||
(keep #(if (= :frame (get-in objects [% :type]))
|
(keep #(cph/get-shape-id-root-frame objects %))
|
||||||
%
|
|
||||||
(get-in objects [% :frame-id])))
|
|
||||||
(remove #(= uuid/zero %)))
|
(remove #(= uuid/zero %)))
|
||||||
changes)))
|
changes)))
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,14 @@
|
||||||
selected (dm/get-in state [:workspace-local :selected])]
|
selected (dm/get-in state [:workspace-local :selected])]
|
||||||
(process-selected-shapes objects selected options))))
|
(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
|
(defn lookup-shapes
|
||||||
([state ids]
|
([state ids]
|
||||||
(lookup-shapes state (:current-page-id state) ids))
|
(lookup-shapes state (:current-page-id state) ids))
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.data.workspace.thumbnails :as dwt]
|
[app.main.data.workspace.thumbnails :as dwt]
|
||||||
|
@ -58,77 +59,83 @@
|
||||||
::mf/wrap-props false}
|
::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
|
|
||||||
(let [shape (unchecked-get props "shape")
|
(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
|
|
||||||
frame-id (:id shape)
|
frame-id (:id shape)
|
||||||
page-id (mf/use-ctx ctx/current-page-id)
|
|
||||||
|
|
||||||
;; References to the current rendered node and the its parentn
|
;; References to the current rendered node and the its parentn
|
||||||
node-ref (mf/use-var nil)
|
node-ref (mf/use-var nil)
|
||||||
|
|
||||||
;; when `true` we've called the mount for the frame
|
objects (wsh/lookup-page-objects @st/state)
|
||||||
rendered? (mf/use-var false)
|
|
||||||
|
|
||||||
;; Modifiers
|
;; Modifiers
|
||||||
modifiers-ref (mf/use-memo (mf/deps frame-id) #(refs/workspace-modifiers-by-frame-id frame-id))
|
modifiers-ref (mf/use-memo (mf/deps frame-id) #(refs/workspace-modifiers-by-frame-id frame-id))
|
||||||
modifiers (mf/deref modifiers-ref)
|
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?)]
|
|
||||||
|
|
||||||
(fdm/use-dynamic-modifiers objects @node-ref modifiers)
|
(fdm/use-dynamic-modifiers objects @node-ref modifiers)
|
||||||
|
|
||||||
(mf/use-effect
|
(if-not (cph/root-frame? shape)
|
||||||
(mf/deps fonts)
|
[:& frame-shape {:shape shape :ref node-ref}]
|
||||||
(fn []
|
|
||||||
(->> (rx/from fonts)
|
|
||||||
(rx/merge-map fonts/fetch-font-css)
|
|
||||||
(rx/ignore))))
|
|
||||||
|
|
||||||
(mf/use-effect
|
;; If the current shape is root we handle its thumbnail and the dynamic modifiers
|
||||||
(fn []
|
(let [thumbnail? (unchecked-get props "thumbnail?")
|
||||||
;; 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
|
render-id (mf/use-memo #(str (uuid/next)))
|
||||||
(mf/deps shape fonts thumbnail? on-load-frame-dom @force-render render-frame?)
|
fonts (mf/use-memo (mf/deps shape objects) #(ff/shape->fonts shape objects))
|
||||||
(fn []
|
fonts (-> fonts (hooks/use-equal-memo))
|
||||||
(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)
|
force-render (mf/use-state false)
|
||||||
(when (not @rendered?) (reset! rendered? true)))))
|
|
||||||
|
|
||||||
[:& (mf/provider ctx/render-ctx) {:value render-id}
|
;; Thumbnail data
|
||||||
[:g.frame-container {:id (dm/str "frame-container-" (:id shape))
|
page-id (mf/use-ctx ctx/current-page-id)
|
||||||
:key "frame-container"
|
|
||||||
:ref on-frame-load
|
;; when `true` we've called the mount for the frame
|
||||||
:opacity (when (:hidden shape) 0)}
|
rendered? (mf/use-var false)
|
||||||
[:& ff/fontfaces-style {:fonts fonts}]
|
|
||||||
[:g.frame-thumbnail-wrapper
|
disable-thumbnail? (d/not-empty? (dm/get-in modifiers [(:id shape) :modifiers]))
|
||||||
{:id (dm/str "thumbnail-container-" (:id shape))
|
|
||||||
;; Hide the thumbnail when not displaying
|
[on-load-frame-dom render-frame? thumbnail-renderer]
|
||||||
:opacity (when (and @rendered? (not thumbnail?) (not render-frame?) (not in-memory?)) 0)}
|
(ftr/use-render-thumbnail page-id shape node-ref rendered? disable-thumbnail? @force-render)
|
||||||
thumbnail-renderer]]]))))
|
|
||||||
|
[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]]]))))))
|
||||||
|
|
Loading…
Add table
Reference in a new issue