diff --git a/frontend/src/app/main/data/profile.cljs b/frontend/src/app/main/data/profile.cljs index 66ded6fc8b..82ecbcbb36 100644 --- a/frontend/src/app/main/data/profile.cljs +++ b/frontend/src/app/main/data/profile.cljs @@ -15,6 +15,7 @@ [app.main.data.media :as di] [app.main.data.notifications :as ntf] [app.main.data.team :as-alias dtm] + [app.main.features :as features] [app.main.repo :as rp] [app.main.router :as rt] [app.plugins.register :as plugins.register] @@ -291,8 +292,13 @@ ;; FIXME ptk/WatchEvent (watch [_ _ _] - (->> (rp/cmd! :update-profile-props {:props props}) - (rx/map (constantly (refresh-profile))))))) + (let [refresh-profile$ (->> (rp/cmd! :update-profile-props {:props props}) + (rx/map (constantly (refresh-profile)))) + recompute$ (when (contains? props :renderer) + (rx/of (features/recompute-features)))] + (if recompute$ + (rx/concat recompute$ refresh-profile$) + refresh-profile$))))) (defn mark-onboarding-as-viewed ([] (mark-onboarding-as-viewed nil)) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 412f1a7e3d..37bdd54a03 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -72,6 +72,7 @@ [app.main.refs :as refs] [app.main.repo :as rp] [app.main.router :as rt] + [app.main.store :as st] [app.render-wasm :as wasm] [app.render-wasm.api :as wasm.api] [app.util.dom :as dom] @@ -318,7 +319,7 @@ (let [stoper-s (rx/filter (ptk/type? ::finalize-workspace) stream) rparams (rt/get-params state) features (features/get-enabled-features state team-id) - render-wasm? (contains? features "render-wasm/v1")] + render-wasm? #(features/active-feature? @st/state "render-wasm/v1")] (log/debug :hint "initialize-workspace" :team-id (dm/str team-id) @@ -329,7 +330,7 @@ (rx/concat ;; Fetch all essential data that should be loaded before the file (rx/merge - (if ^boolean render-wasm? + (if ^boolean (render-wasm?) (->> (rx/from @wasm/module) (rx/filter true?) (rx/tap (fn [_] @@ -405,72 +406,72 @@ (rx/take 1) (rx/map #(dwcm/navigate-to-comment-id comment-id)))) - (when render-wasm? - (->> stream - (rx/filter dch/commit?) - (rx/map deref) - (rx/mapcat - (fn [{:keys [redo-changes]}] - (let [added (->> redo-changes - (filter #(= (:type %) :add-obj)) - (map :id))] - (->> (rx/from added) - (rx/map process-wasm-object))))))) + (->> stream + (rx/filter dch/commit?) + (rx/filter (fn [_] (render-wasm?))) + (rx/map deref) + (rx/mapcat + (fn [{:keys [redo-changes]}] + (let [added (->> redo-changes + (filter #(= (:type %) :add-obj)) + (map :id))] + (->> (rx/from added) + (rx/map process-wasm-object)))))) - (when render-wasm? - (let [local-commits-s - (->> stream - (rx/filter dch/commit?) - (rx/map deref) - (rx/filter #(and (= :local (:source %)) - (not (contains? (:tags %) :position-data)))) - (rx/filter (complement empty?))) + (let [local-commits-s + (->> stream + (rx/filter dch/commit?) + (rx/filter (fn [_] (render-wasm?))) + (rx/map deref) + (rx/filter #(and (= :local (:source %)) + (not (contains? (:tags %) :position-data)))) + (rx/filter (complement empty?))) - notifier-s - (rx/merge - (->> local-commits-s (rx/debounce 1000)) - (->> stream (rx/filter dps/force-persist?))) + notifier-s + (rx/merge + (->> local-commits-s (rx/debounce 1000)) + (->> stream (rx/filter dps/force-persist?))) - objects-s - (rx/from-atom refs/workspace-page-objects {:emit-current-value? true}) + objects-s + (rx/from-atom refs/workspace-page-objects {:emit-current-value? true}) - current-page-id-s - (rx/from-atom refs/current-page-id {:emit-current-value? true})] + current-page-id-s + (rx/from-atom refs/current-page-id {:emit-current-value? true})] - (->> local-commits-s - (rx/buffer-until notifier-s) - (rx/with-latest-from objects-s) - (rx/map - (fn [[commits objects]] - (->> commits - (mapcat :redo-changes) - (filter #(contains? #{:mod-obj :add-obj} (:type %))) - (filter #(cfh/text-shape? objects (:id %))) - (map #(vector - (:id %) - (wasm.api/calculate-position-data (get objects (:id %)))))))) + (->> local-commits-s + (rx/buffer-until notifier-s) + (rx/with-latest-from objects-s) + (rx/map + (fn [[commits objects]] + (->> commits + (mapcat :redo-changes) + (filter #(contains? #{:mod-obj :add-obj} (:type %))) + (filter #(cfh/text-shape? objects (:id %))) + (map #(vector + (:id %) + (wasm.api/calculate-position-data (get objects (:id %)))))))) - (rx/with-latest-from current-page-id-s) - (rx/map - (fn [[text-position-data page-id]] - (let [changes - (->> text-position-data - (mapv (fn [[id position-data]] - {:type :mod-obj - :id id - :page-id page-id - :operations - [{:type :set - :attr :position-data - :val position-data - :ignore-touched true - :ignore-geometry true}]})))] - (when (d/not-empty? changes) - (dch/commit-changes - {:redo-changes changes :undo-changes [] - :save-undo? false - :tags #{:position-data}}))))) - (rx/take-until stoper-s)))) + (rx/with-latest-from current-page-id-s) + (rx/map + (fn [[text-position-data page-id]] + (let [changes + (->> text-position-data + (mapv (fn [[id position-data]] + {:type :mod-obj + :id id + :page-id page-id + :operations + [{:type :set + :attr :position-data + :val position-data + :ignore-touched true + :ignore-geometry true}]})))] + (when (d/not-empty? changes) + (dch/commit-changes + {:redo-changes changes :undo-changes [] + :save-undo? false + :tags #{:position-data}}))))) + (rx/take-until stoper-s))) (->> stream (rx/filter dch/commit?) diff --git a/frontend/src/app/main/features.cljs b/frontend/src/app/main/features.cljs index c912ef5e35..b3592ede4b 100644 --- a/frontend/src/app/main/features.cljs +++ b/frontend/src/app/main/features.cljs @@ -30,9 +30,9 @@ [features state] (let [params (rt/get-params state) wasm (get params :wasm) - enable-wasm (= "true" wasm) renderer (-> state :profile :props :renderer) - disable-wasm (or (= "false" wasm) (= renderer :svg)) + enable-wasm (or (= "true" wasm) (and (= renderer :wasm) (not= "false" wasm))) + disable-wasm (or (= "false" wasm) (and (= renderer :svg) (not= "true" wasm))) features (cond-> features enable-wasm (conj "render-wasm/v1") disable-wasm (disj "render-wasm/v1"))] @@ -178,3 +178,24 @@ (log/inf :hint "initialized" :enabled (str/join " " features)))))) + +(defn recompute-features + [] + (ptk/reify ::recompute-features + ptk/UpdateEvent + (update [_ state] + (let [previous (or (get state :features) #{}) + features (setup-wasm-features previous state)] + (if (= previous features) + state + (assoc state :features features)))) + + ptk/EffectEvent + (effect [_ state _] + (let [features (get state :features)] + (if (contains? features "render-wasm/v1") + (wasm/initialize true) + (wasm/initialize false)) + + (log/inf :hint "recomputed features" + :enabled (str/join " " features)))))) diff --git a/frontend/src/app/main/ui/workspace/main_menu.cljs b/frontend/src/app/main/ui/workspace/main_menu.cljs index cae6e65ad4..d69cda1192 100644 --- a/frontend/src/app/main/ui/workspace/main_menu.cljs +++ b/frontend/src/app/main/ui/workspace/main_menu.cljs @@ -902,6 +902,7 @@ toggle-render (mf/use-fn + (mf/deps profile) (fn [event] (dom/stop-propagation event) (let [renderer (or (-> profile :props :renderer) :svg) diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index 225dde4fd9..02f86b21e7 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -31,6 +31,7 @@ [app.main.ui.workspace.viewport.utils :as utils] [app.main.worker :as mw] [app.render-wasm.api :as wasm.api] + [app.render-wasm.wasm :as wasm] [app.util.debug :as dbg] [app.util.dom :as dom] [app.util.globals :as globals] diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs index b95962c4c5..e3837b59e2 100644 --- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs +++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs @@ -375,6 +375,7 @@ (vreset! unmounted? true) (when-let [timeout-id @timeout-id-ref] (js/clearTimeout timeout-id)) + (wasm.api/end-page-transition!) (wasm.api/clear-canvas))))) (mf/with-effect [show-text-editor? workspace-editor-state edition] diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 96c3253c64..e7321c80ad 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -1075,16 +1075,18 @@ (defn intersect-position-in-shape [id position] - (let [buffer (uuid/get-u32 id) - result - (h/call wasm/internal-module "_intersect_position_in_shape" - (aget buffer 0) - (aget buffer 1) - (aget buffer 2) - (aget buffer 3) - (:x position) - (:y position))] - (= result 1))) + (if (and wasm/context-initialized? (not @wasm/context-lost?)) + (let [buffer (uuid/get-u32 id) + result + (h/call wasm/internal-module "_intersect_position_in_shape" + (aget buffer 0) + (aget buffer 1) + (aget buffer 2) + (aget buffer 3) + (:x position) + (:y position))] + (= result 1)) + false)) (def render-finish (letfn [(do-render []