From 87eb91f80532134b83fd4e3eb08a09456eb5585b Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 12 Jun 2026 10:29:58 +0200 Subject: [PATCH] :recycle: Migrate viewer WASM viewport to modern syntax (#10106) --- .../src/app/main/ui/viewer/interactions.cljs | 22 ++-- frontend/src/app/main/ui/viewer/shapes.cljs | 24 ++-- .../src/app/main/ui/viewer/viewport_wasm.cljs | 105 +++++++++--------- 3 files changed, 69 insertions(+), 82 deletions(-) diff --git a/frontend/src/app/main/ui/viewer/interactions.cljs b/frontend/src/app/main/ui/viewer/interactions.cljs index 495b7fa8e1..19059f5fde 100644 --- a/frontend/src/app/main/ui/viewer/interactions.cljs +++ b/frontend/src/app/main/ui/viewer/interactions.cljs @@ -34,6 +34,7 @@ [{:keys [page frame base offset size is-fixed delta]}] (let [delta (or delta (gpt/point 0 0)) vbox (:vbox size) + is-fixed (true? is-fixed) frame (cond-> frame is-fixed (assoc :fixed-scroll true)) @@ -135,12 +136,7 @@ mode (h/use-equal-memo interactions-mode) offset (h/use-equal-memo frame-offset) size (h/use-equal-memo size) - delta (h/use-equal-memo delta) - - page (h/use-equal-memo page) - frame (h/use-equal-memo frame) - base (h/use-equal-memo base-frame) - is-fixed (h/use-equal-memo is-fixed) + base base-frame render-wasm? (and (features/use-feature "render-wasm/v1") (contains? cf/flags :available-viewer-wasm))] @@ -179,13 +175,13 @@ (events/unlistenByKey key3)))) (if ^boolean render-wasm? - [:& viewport.wasm/viewport-wasm {:page page - :frame frame - :base base - :offset offset - :size size - :delta delta - :fixed? is-fixed}] + [:> viewport.wasm/viewport-wasm* {:page page + :frame frame + :base base + :offset offset + :size size + :delta delta + :is-fixed is-fixed}] [:> viewport-svg* {:page page :frame frame :base base diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index 9f407b6714..425ed01d18 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -301,11 +301,8 @@ ;; wired to the same interaction handlers as the regular SVG tree. (mf/defc hotspot* - {::mf/wrap-props false} - [props] - (let [shape (unchecked-get props "shape") - all-objects (unchecked-get props "all-objects") - base-frame (mf/use-ctx base-frame-ctx) + [{:keys [shape all-objects]}] + (let [base-frame (mf/use-ctx base-frame-ctx) frame-offset (mf/use-ctx frame-offset-ctx) show-interactions (mf/deref ref:viewer-show-interactions) overlays (mf/deref refs/viewer-overlays) @@ -350,12 +347,8 @@ Optional `shape-filter` is a predicate that receives the shape id and returns true when it should be included (used to split fixed-scroll vs normal layers)." - {::mf/wrap-props false} - [props] - (let [objects (unchecked-get props "objects") - all-objects (or (unchecked-get props "all-objects") objects) - shape-filter (unchecked-get props "shape-filter") - frame (unchecked-get props "frame") + [{:keys [objects all-objects shape-filter frame]}] + (let [all-objects (or all-objects objects) frame-id (:id frame) ids (cond->> (cons frame-id (cfh/get-children-ids objects frame-id)) shape-filter (filter shape-filter)) @@ -363,10 +356,11 @@ (keep #(get objects %)) (filter (fn [s] (and (not (:hidden s)) (seq (:interactions s))))))] - [:* (for [shape hotspots] - [:& hotspot* {:key (str (:id shape)) - :shape shape - :all-objects all-objects}])])) + [:g {} + (for [shape hotspots] + [:> hotspot* {:key (str (:id shape)) + :shape shape + :all-objects all-objects}])])) ;; TODO: use-memo use-fn diff --git a/frontend/src/app/main/ui/viewer/viewport_wasm.cljs b/frontend/src/app/main/ui/viewer/viewport_wasm.cljs index 2c9b5a31e4..50f97f5cbf 100644 --- a/frontend/src/app/main/ui/viewer/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/viewer/viewport_wasm.cljs @@ -12,7 +12,6 @@ [app.main.render-viewer-wasm :as rwv] [app.main.ui.viewer.shapes :as shapes] [app.main.ui.viewer.viewport-common :as vpc] - [app.util.object :as obj] [rumext.v2 :as mf])) (defn- canvas-dimensions @@ -20,17 +19,7 @@ {:width (js/Math.round (* scale (:base-width size))) :height (js/Math.round (* scale (:base-height size)))}) -(defn- frame-hotspots-props - "frame-hotspots* uses ::mf/wrap-props false and expects string keys." - [prepared prepared-all prepared-frame shape-filter] - (let [props #js {"objects" prepared - "all-objects" prepared-all - "frame" prepared-frame}] - (when shape-filter - (obj/set! props "shape-filter" shape-filter)) - props)) - -(mf/defc wasm-hotspots-svg +(mf/defc wasm-hotspots-svg* [{:keys [vbox size class prepared prepared-all prepared-frame shape-filter]}] [:svg {:view-box vbox :width (:width size) @@ -43,11 +32,15 @@ :top 0 :left 0} :class class} - [:& shapes/frame-hotspots* - (frame-hotspots-props prepared prepared-all prepared-frame shape-filter)]]) + [:> shapes/frame-hotspots* + {:objects prepared + :all-objects prepared-all + :frame prepared-frame + :shape-filter shape-filter}]]) -(mf/defc wasm-layer - [{:keys [canvas-ref scale size vbox svg-props]}] +(mf/defc wasm-layer* + [{:keys [canvas-ref scale size vbox + prepared prepared-all prepared-frame class shape-filter]}] (let [{:keys [width height]} (canvas-dimensions scale size)] [:div {:style {:position "absolute" :top 0 @@ -56,7 +49,13 @@ :height "100%" :background "transparent" :pointer-events "none"}}] - [:& wasm-hotspots-svg (assoc svg-props :vbox vbox :size size)]])) + [:> wasm-hotspots-svg* {:vbox vbox + :size size + :class class + :prepared prepared + :prepared-all prepared-all + :prepared-frame prepared-frame + :shape-filter shape-filter}]])) (defn- fixed-scroll-layer-ids [objects frame-id has-fixed?] @@ -79,18 +78,12 @@ :fixed-include-ids fixed-include-ids :fixed-clear-fills-ids fixed-clear-fills-ids})) -(mf/defc viewport-wasm - {::mf/wrap [mf/memo] - ::mf/wrap-props false} - [props] - (let [page (unchecked-get props "page") - frame (unchecked-get props "frame") - base (unchecked-get props "base") - offset (unchecked-get props "offset") - size (unchecked-get props "size") - delta (or (unchecked-get props "delta") (gpt/point 0 0)) - vbox (:vbox size) - fixed? (true? (unchecked-get props "fixed?")) +(mf/defc viewport-wasm* + {::mf/wrap [mf/memo]} + [{:keys [page frame base offset size delta is-fixed]}] + (let [delta (or delta (gpt/point 0 0)) + vbox (:vbox size) + is-fixed (true? is-fixed) fixed-layer-ref (mf/use-ref nil) not-fixed-wasm-ref (mf/use-ref nil) @@ -101,11 +94,11 @@ scale (vpc/viewer-scale size) page-id (:id page) - frame (cond-> frame fixed? (assoc :fixed-scroll true)) - objects (cond-> objects fixed? (assoc-in [frame-id :fixed-scroll] true)) + frame (cond-> frame is-fixed (assoc :fixed-scroll true)) + objects (cond-> objects is-fixed (assoc-in [frame-id :fixed-scroll] true)) has-fixed? - (and (not fixed?) + (and (not is-fixed) (some #(cfh/fixed-scroll? (get objects %)) (cfh/get-children-ids objects frame-id))) @@ -123,9 +116,30 @@ prepared-frame (get prepared frame-id) - svg-base {:prepared prepared - :prepared-all prepared-all - :prepared-frame prepared-frame}] + not-fixed-props + (mf/props {:prepared prepared + :prepared-all prepared-all + :prepared-frame prepared-frame + :canvas-ref not-fixed-wasm-ref + :scale scale + :size size + :vbox vbox + :class (if has-fixed? + (stl/css :not-fixed) + (when is-fixed (stl/css :fixed))) + :shape-filter (when has-fixed? + #(not (contains? fixed-mask-set %)))}) + + fixed-props + (mf/props {:prepared prepared + :prepared-all prepared-all + :prepared-frame prepared-frame + :canvas-ref fixed-wasm-ref + :scale scale + :size size + :vbox vbox + :class (stl/css :not-fixed) + :shape-filter #(contains? fixed-mask-set %)})] (rwv/use-viewer-wasm-viewport! page-id objects size scale frame-id @@ -136,25 +150,8 @@ [:& (mf/provider shapes/base-frame-ctx) {:value (get prepared-all (:id base))} [:& (mf/provider shapes/frame-offset-ctx) {:value offset} [:* - [:& wasm-layer - {:canvas-ref not-fixed-wasm-ref - :scale scale - :size size - :vbox vbox - :svg-props (assoc svg-base - :class (if has-fixed? - (stl/css :not-fixed) - (when fixed? (stl/css :fixed))) - :shape-filter (when has-fixed? - #(not (contains? fixed-mask-set %))))}] + [:> wasm-layer* not-fixed-props] (when has-fixed? [:div {:ref fixed-layer-ref} - [:& wasm-layer - {:canvas-ref fixed-wasm-ref - :scale scale - :size size - :vbox vbox - :svg-props (assoc svg-base - :class (stl/css :not-fixed) - :shape-filter #(contains? fixed-mask-set %))}]])]]])) + [:> wasm-layer* fixed-props]])]]]))