mirror of
https://github.com/penpot/penpot.git
synced 2026-06-01 05:00:17 +00:00
Merge pull request #9509 from penpot/elenatorro-14038-fix-component-thumbnail-update
🐛 Fix component thumbnail sync
This commit is contained in:
commit
97c8fcd4ad
@ -96,12 +96,14 @@
|
|||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(update state :thumbnails
|
(-> state
|
||||||
(fn [thumbs]
|
(update :thumbnails
|
||||||
(if-let [uri (get thumbs object-id)]
|
(fn [thumbs]
|
||||||
(do (vreset! pending uri)
|
(if-let [uri (get thumbs object-id)]
|
||||||
(dissoc thumbs object-id))
|
(do (vreset! pending uri)
|
||||||
thumbs))))
|
(dissoc thumbs object-id))
|
||||||
|
thumbs)))
|
||||||
|
(update :thumbnails-meta dissoc object-id)))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
@ -124,10 +126,13 @@
|
|||||||
(ptk/reify ::assoc-thumbnail
|
(ptk/reify ::assoc-thumbnail
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [prev-uri (dm/get-in state [:thumbnails object-id])]
|
(let [prev-uri (dm/get-in state [:thumbnails object-id])
|
||||||
|
now (.now js/Date)]
|
||||||
(some->> prev-uri (vreset! prev-uri*))
|
(some->> prev-uri (vreset! prev-uri*))
|
||||||
(l/trc :hint "assoc thumbnail" :object-id object-id :uri uri)
|
(l/trc :hint "assoc thumbnail" :object-id object-id :uri uri)
|
||||||
(update state :thumbnails assoc object-id uri)))
|
(-> state
|
||||||
|
(update :thumbnails assoc object-id uri)
|
||||||
|
(update :thumbnails-meta assoc object-id {:rendered-at now}))))
|
||||||
|
|
||||||
ptk/EffectEvent
|
ptk/EffectEvent
|
||||||
(effect [_ _ _]
|
(effect [_ _ _]
|
||||||
|
|||||||
@ -63,8 +63,9 @@
|
|||||||
(try
|
(try
|
||||||
(let [objects (dsh/lookup-page-objects @st/state file-id page-id)]
|
(let [objects (dsh/lookup-page-objects @st/state file-id page-id)]
|
||||||
(if-let [frame (get objects frame-id)]
|
(if-let [frame (get objects frame-id)]
|
||||||
(let [{:keys [width height]} (:selrect frame)
|
(let [{ext-w :width ext-h :height} (wasm.api/get-shape-extrect frame-id)
|
||||||
max-size (mth/max width height)
|
{sel-w :width sel-h :height} (:selrect frame)
|
||||||
|
max-size (mth/max (or ext-w sel-w) (or ext-h sel-h))
|
||||||
scale (mth/max 1 (/ target-size max-size))
|
scale (mth/max 1 (/ target-size max-size))
|
||||||
png-bytes (wasm.api/render-shape-pixels frame-id scale)]
|
png-bytes (wasm.api/render-shape-pixels frame-id scale)]
|
||||||
(if (or (nil? png-bytes) (zero? (.-length png-bytes)))
|
(if (or (nil? png-bytes) (zero? (.-length png-bytes)))
|
||||||
|
|||||||
@ -588,6 +588,12 @@
|
|||||||
(cf/resolve-media)))
|
(cf/resolve-media)))
|
||||||
st/state))
|
st/state))
|
||||||
|
|
||||||
|
(defn workspace-thumbnail-rendered-at
|
||||||
|
[object-id]
|
||||||
|
(l/derived
|
||||||
|
#(dm/get-in % [:thumbnails-meta object-id :rendered-at])
|
||||||
|
st/state))
|
||||||
|
|
||||||
(def workspace-text-modifier
|
(def workspace-text-modifier
|
||||||
(l/derived :workspace-text-modifier st/state))
|
(l/derived :workspace-text-modifier st/state))
|
||||||
|
|
||||||
|
|||||||
@ -324,14 +324,35 @@
|
|||||||
current-page-id (mf/deref refs/current-page-id)
|
current-page-id (mf/deref refs/current-page-id)
|
||||||
thumbnail-requested? (mf/use-ref false)
|
thumbnail-requested? (mf/use-ref false)
|
||||||
|
|
||||||
thumbnail-uri*
|
object-id
|
||||||
(mf/with-memo [file-id page-id root-id]
|
(mf/with-memo [file-id page-id root-id]
|
||||||
(let [object-id (thc/fmt-object-id file-id page-id root-id "component")]
|
(thc/fmt-object-id file-id page-id root-id "component"))
|
||||||
(refs/workspace-thumbnail-by-id object-id)))
|
|
||||||
|
thumbnail-uri*
|
||||||
|
(mf/with-memo [object-id]
|
||||||
|
(refs/workspace-thumbnail-by-id object-id))
|
||||||
|
|
||||||
thumbnail-uri
|
thumbnail-uri
|
||||||
(mf/deref thumbnail-uri*)
|
(mf/deref thumbnail-uri*)
|
||||||
|
|
||||||
|
rendered-at*
|
||||||
|
(mf/with-memo [object-id]
|
||||||
|
(refs/workspace-thumbnail-rendered-at object-id))
|
||||||
|
|
||||||
|
rendered-at
|
||||||
|
(mf/deref rendered-at*)
|
||||||
|
|
||||||
|
modified-at
|
||||||
|
(some-> (:modified-at component) (.getTime))
|
||||||
|
|
||||||
|
;; Stale if there's no in-session render record
|
||||||
|
;; or the component was modified after the last render
|
||||||
|
stale?
|
||||||
|
(and (some? thumbnail-uri)
|
||||||
|
(or (nil? rendered-at)
|
||||||
|
(and (some? modified-at)
|
||||||
|
(> modified-at rendered-at))))
|
||||||
|
|
||||||
on-error
|
on-error
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps @retry)
|
(mf/deps @retry)
|
||||||
@ -340,20 +361,21 @@
|
|||||||
(inc retry))))]
|
(inc retry))))]
|
||||||
|
|
||||||
;; Lazy WASM thumbnail rendering: when the component becomes
|
;; Lazy WASM thumbnail rendering: when the component becomes
|
||||||
;; visible, has no cached thumbnail, and lives on the current page
|
;; visible and either has no cached thumbnail or the cached one is
|
||||||
;; trigger a render. Ref is used to avoid triggering multiple renders
|
;; stale relative to the last recorded edit, trigger a render. Ref
|
||||||
;; while the component is still not rendered and the thumbnail URI
|
;; is used to avoid triggering multiple renders while the previous
|
||||||
;; is not available.
|
;; render is in flight.
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps is-hidden thumbnail-uri wasm? current-page-id file-id page-id)
|
(mf/deps is-hidden thumbnail-uri stale? wasm? current-page-id file-id page-id)
|
||||||
(fn []
|
(fn []
|
||||||
(if (some? thumbnail-uri)
|
(if (and (some? thumbnail-uri) (not stale?))
|
||||||
(mf/set-ref-val! thumbnail-requested? false)
|
(mf/set-ref-val! thumbnail-requested? false)
|
||||||
(when (and wasm? (not is-hidden) (not (mf/ref-val thumbnail-requested?)) (= page-id current-page-id))
|
(when (and wasm? (not is-hidden) (not (mf/ref-val thumbnail-requested?)) (= page-id current-page-id))
|
||||||
(mf/set-ref-val! thumbnail-requested? true)
|
(mf/set-ref-val! thumbnail-requested? true)
|
||||||
(st/emit! (dwt.wasm/render-thumbnail file-id page-id root-id))))))
|
(st/emit! (dwt.wasm/render-thumbnail file-id page-id root-id))))))
|
||||||
|
|
||||||
(if (and (some? thumbnail-uri)
|
(if (and (some? thumbnail-uri)
|
||||||
|
(not stale?)
|
||||||
(or (contains? cf/flags :component-thumbnails)
|
(or (contains? cf/flags :component-thumbnails)
|
||||||
wasm?))
|
wasm?))
|
||||||
[:& component-svg-thumbnail
|
[:& component-svg-thumbnail
|
||||||
|
|||||||
@ -2172,6 +2172,24 @@
|
|||||||
(mem/free)
|
(mem/free)
|
||||||
result))
|
result))
|
||||||
|
|
||||||
|
(defn get-shape-extrect
|
||||||
|
[shape-id]
|
||||||
|
(let [buffer (uuid/get-u32 shape-id)
|
||||||
|
offset (h/call wasm/internal-module "_get_shape_extrect"
|
||||||
|
(aget buffer 0)
|
||||||
|
(aget buffer 1)
|
||||||
|
(aget buffer 2)
|
||||||
|
(aget buffer 3))]
|
||||||
|
(when (and (number? offset) (pos? offset))
|
||||||
|
(let [heapf32 (mem/get-heap-f32)
|
||||||
|
base (mem/->offset-32 offset)
|
||||||
|
x (aget heapf32 base)
|
||||||
|
y (aget heapf32 (+ base 1))
|
||||||
|
w (aget heapf32 (+ base 2))
|
||||||
|
h (aget heapf32 (+ base 3))]
|
||||||
|
(mem/free)
|
||||||
|
{:x x :y y :width w :height h}))))
|
||||||
|
|
||||||
(defn init-wasm-module
|
(defn init-wasm-module
|
||||||
[module]
|
[module]
|
||||||
(let [default-fn (unchecked-get module "default")
|
(let [default-fn (unchecked-get module "default")
|
||||||
|
|||||||
@ -878,6 +878,25 @@ pub extern "C" fn end_temp_objects() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[wasm_error]
|
||||||
|
pub extern "C" fn get_shape_extrect(a: u32, b: u32, c: u32, d: u32) -> Result<*mut u8> {
|
||||||
|
let id = uuid_from_u32_quartet(a, b, c, d);
|
||||||
|
|
||||||
|
with_state!(state, {
|
||||||
|
let Some(shape) = state.shapes.get(&id) else {
|
||||||
|
return Err(Error::CriticalError("Shape not found".to_string()));
|
||||||
|
};
|
||||||
|
let extrect = get_render_state().get_cached_extrect(shape, &state.shapes, 1.0);
|
||||||
|
let mut buf = Vec::with_capacity(16);
|
||||||
|
buf.extend_from_slice(&extrect.x().to_le_bytes());
|
||||||
|
buf.extend_from_slice(&extrect.y().to_le_bytes());
|
||||||
|
buf.extend_from_slice(&extrect.width().to_le_bytes());
|
||||||
|
buf.extend_from_slice(&extrect.height().to_le_bytes());
|
||||||
|
Ok(mem::write_bytes(buf))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[wasm_error]
|
#[wasm_error]
|
||||||
pub extern "C" fn render_shape_pixels(
|
pub extern "C" fn render_shape_pixels(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user