mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
🐛 Fix problem with component thumbnails
This commit is contained in:
parent
f07b954b7e
commit
1d8299a919
@ -411,9 +411,16 @@
|
||||
(when id-ref
|
||||
(reset! id-ref component-id))
|
||||
(when-not (empty? (:redo-changes changes))
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(dws/select-shapes (d/ordered-set (:id root)))
|
||||
(ptk/data-event :layout/update {:ids parents}))))))))))
|
||||
(rx/concat
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(dws/select-shapes (d/ordered-set (:id root)))
|
||||
(ptk/data-event :layout/update {:ids parents}))
|
||||
|
||||
;; When activated the wasm rendering we need to recreate its thumbnail on creation
|
||||
(if (features/active-feature? state "render-wasm/v1")
|
||||
(rx/of (dwt.wasm/render-thumbnail file-id page-id (:id root))
|
||||
(dwt.wasm/persist-thumbnail file-id page-id (:id root)))
|
||||
(rx/empty)))))))))))
|
||||
|
||||
(defn add-component
|
||||
"Add a new component to current file library, from the currently selected shapes.
|
||||
|
||||
@ -15,11 +15,15 @@
|
||||
- persist-thumbnail: pushes current data-uri to the server (debounced)"
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.logging :as l]
|
||||
[app.common.math :as mth]
|
||||
[app.common.thumbnails :as thc]
|
||||
[app.common.time :as ct]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.data.workspace.thumbnails :as dwt]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.render-wasm.api :as wasm.api]
|
||||
[app.util.webapi :as wapi]
|
||||
[beicon.v2.core :as rx]
|
||||
@ -41,27 +45,38 @@
|
||||
(fn [e] (reject e)))
|
||||
(.readAsDataURL reader blob)))))
|
||||
|
||||
;; This constant stores the target thumbnail minimum max-size so
|
||||
;; the images doesn't lose quality when rendered
|
||||
(def target-size 200)
|
||||
|
||||
(defn- render-component-pixels
|
||||
"Renders a component frame using the workspace WASM context.
|
||||
Returns an observable that emits a data-uri string.
|
||||
Deferred by one animation frame so that process-shape-changes!
|
||||
has time to sync all child shapes to WASM memory first."
|
||||
[frame-id]
|
||||
[file-id page-id frame-id]
|
||||
(rx/create
|
||||
(fn [subs]
|
||||
(js/requestAnimationFrame
|
||||
(fn [_]
|
||||
(try
|
||||
(let [png-bytes (wasm.api/render-shape-pixels frame-id 1)]
|
||||
(let [objects (dsh/lookup-page-objects @st/state file-id page-id)
|
||||
frame (get objects frame-id)
|
||||
{:keys [width height]} (:selrect frame)
|
||||
max-size (mth/max width height)
|
||||
scale (mth/max 1 (/ target-size max-size))
|
||||
png-bytes (wasm.api/render-shape-pixels frame-id scale)]
|
||||
(if (or (nil? png-bytes) (zero? (.-length png-bytes)))
|
||||
(do (js/console.error "[thumbnails] render-shape-pixels returned empty for" (str frame-id))
|
||||
(rx/end! subs))
|
||||
(.then (png-bytes->data-uri png-bytes)
|
||||
(fn [data-uri]
|
||||
(rx/push! subs data-uri)
|
||||
(rx/end! subs))
|
||||
(fn [err]
|
||||
(rx/error! subs err)))))
|
||||
(do
|
||||
(js/console.error "[thumbnails] render-shape-pixels returned empty for" (str frame-id))
|
||||
(rx/end! subs))
|
||||
(.then
|
||||
(png-bytes->data-uri png-bytes)
|
||||
(fn [data-uri]
|
||||
(rx/push! subs data-uri)
|
||||
(rx/end! subs))
|
||||
(fn [err]
|
||||
(rx/error! subs err)))))
|
||||
(catch :default err
|
||||
(rx/error! subs err)))))
|
||||
nil)))
|
||||
@ -71,29 +86,57 @@
|
||||
Does NOT persist to the server — persistence is handled separately
|
||||
by `persist-thumbnail` on a debounced schedule."
|
||||
[file-id page-id frame-id]
|
||||
|
||||
(let [object-id (thc/fmt-object-id file-id page-id frame-id "component")]
|
||||
(ptk/reify ::render-thumbnail
|
||||
cljs.core/IDeref
|
||||
(-deref [_] object-id)
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [tp (ct/tpoint-ms)]
|
||||
(->> (render-component-pixels frame-id)
|
||||
(rx/map
|
||||
(fn [data-uri]
|
||||
(l/dbg :hint "component thumbnail rendered (wasm)"
|
||||
:elapsed (dm/str (tp) "ms"))
|
||||
(dwt/assoc-thumbnail object-id data-uri)))
|
||||
(watch [_ state stream]
|
||||
;; When the component is removed it can arrived a render
|
||||
;; request with frame-id=null
|
||||
(when (some? frame-id)
|
||||
(letfn [(load-objects-stream
|
||||
[]
|
||||
(rx/create
|
||||
(fn [subs]
|
||||
(let [objects (dsh/lookup-page-objects state file-id page-id)
|
||||
|
||||
(rx/catch (fn [err]
|
||||
(js/console.error "[thumbnails] error rendering component thumbnail" err)
|
||||
(rx/empty)))
|
||||
;; retrieves a subtree with only the id and its children
|
||||
;; to be loaded before rendering the thumbnail
|
||||
subtree
|
||||
(into {}
|
||||
(map #(vector (:id %) %))
|
||||
(cfh/get-children-with-self objects frame-id))]
|
||||
(try
|
||||
(wasm.api/set-objects subtree #(rx/push! subs %))
|
||||
(catch :default err
|
||||
(rx/error! subs err)))))))
|
||||
|
||||
(rx/take-until
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::dwt/clear-thumbnail))
|
||||
(rx/filter #(= (deref %) object-id))))))))))
|
||||
(do-render-thumbnail
|
||||
[]
|
||||
(let [tp (ct/tpoint-ms)]
|
||||
(->> (render-component-pixels file-id page-id frame-id)
|
||||
(rx/map
|
||||
(fn [data-uri]
|
||||
(l/dbg :hint "component thumbnail rendered (wasm)"
|
||||
:elapsed (dm/str (tp) "ms"))
|
||||
(dwt/assoc-thumbnail object-id data-uri)))
|
||||
|
||||
(rx/catch (fn [err]
|
||||
(js/console.error "[thumbnails] error rendering component thumbnail" err)
|
||||
(rx/empty)))
|
||||
|
||||
(rx/take-until
|
||||
(->> stream
|
||||
(rx/filter (ptk/type? ::dwt/clear-thumbnail))
|
||||
(rx/filter #(= (deref %) object-id)))))))]
|
||||
|
||||
(if (not= page-id (:current-page-id state))
|
||||
(->> (load-objects-stream)
|
||||
(rx/mapcat do-render-thumbnail))
|
||||
(do-render-thumbnail))))))))
|
||||
|
||||
(defn persist-thumbnail
|
||||
"Persists the current component thumbnail data-uri to the server.
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
cause-sym (gensym "cause")]
|
||||
`(let [~fn-sym (cljs.core/unchecked-get ~module ~name)]
|
||||
(try
|
||||
;; (prn ~name ~@params)
|
||||
(~fn-sym ~@params)
|
||||
(catch :default ~cause-sym
|
||||
(let [read-code-fn# (cljs.core/unchecked-get ~module "_read_error_code")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user