Update to React 18

This commit is contained in:
Aitor 2023-08-16 14:09:53 +02:00 committed by Andrey Antukh
parent 5ea9a52e69
commit 4b8ee8ef84
30 changed files with 396 additions and 250 deletions

View file

@ -13,8 +13,8 @@
funcool/tubax {:mvn/version "2021.05.20-0"} funcool/tubax {:mvn/version "2021.05.20-0"}
funcool/rumext funcool/rumext
{:git/tag "v2.6" {:git/tag "v2.7"
:git/sha "97203a5" :git/sha "37fa860"
:git/url "https://github.com/funcool/rumext.git" :git/url "https://github.com/funcool/rumext.git"
} }

View file

@ -64,8 +64,8 @@
"opentype.js": "^1.3.4", "opentype.js": "^1.3.4",
"postcss-modules": "^6.0.0", "postcss-modules": "^6.0.0",
"randomcolor": "^0.6.2", "randomcolor": "^0.6.2",
"react": "~17.0.2", "react": "^18.2.0",
"react-dom": "~17.0.2", "react-dom": "^18.2.0",
"react-virtualized": "^9.22.3", "react-virtualized": "^9.22.3",
"rxjs": "~7.8.1", "rxjs": "~7.8.1",
"sax": "^1.2.4", "sax": "^1.2.4",

View file

@ -45,10 +45,18 @@
(declare reinit) (declare reinit)
(defonce app-root
(let [el (dom/get-element "app")]
(mf/create-root el)))
(defonce modal-root
(let [el (dom/get-element "modal")]
(mf/create-root el)))
(defn init-ui (defn init-ui
[] []
(mf/mount (mf/element ui/app) (dom/get-element "app")) (mf/render! app-root (mf/element ui/app))
(mf/mount (mf/element modal) (dom/get-element "modal"))) (mf/render! modal-root (mf/element modal)))
(defn- initialize-profile (defn- initialize-profile
"Event used mainly on application bootstrap; it fetches the profile "Event used mainly on application bootstrap; it fetches the profile
@ -110,9 +118,15 @@
(defn ^:export reinit (defn ^:export reinit
[] []
#_(mf/unmount (dom/get-element "app")) ;; NOTE: in cases of some strange behavior after hot-reload,
#_(mf/unmount (dom/get-element "modal")) ;; uncomment this lines; they make a hard-rerender instead
#_(st/emit! (ev/initialize)) ;; soft-rerender.
;;
;; (mf/unmount! app-root)
;; (mf/unmount! modal-root)
;; (set! app-root (mf/create-root (dom/get-element "app")))
;; (set! modal-root (mf/create-root (dom/get-element "modal")))
(st/emit! (ev/initialize))
(init-ui)) (init-ui))
(defn ^:dev/after-load after-load (defn ^:dev/after-load after-load

View file

@ -43,6 +43,7 @@
shapes (cph/get-immediate-children objects) shapes (cph/get-immediate-children objects)
srect (gsh/shapes->rect shapes) srect (gsh/shapes->rect shapes)
local (assoc local :vport size :zoom 1 :zoom-inverse 1)] local (assoc local :vport size :zoom 1 :zoom-inverse 1)]
(cond (cond
(or (not (d/num? (:width srect))) (or (not (d/num? (:width srect)))
(not (d/num? (:height srect)))) (not (d/num? (:height srect))))
@ -52,6 +53,7 @@
(> (:height srect) height)) (> (:height srect) height))
(let [srect (gal/adjust-to-viewport size srect {:padding 40}) (let [srect (gal/adjust-to-viewport size srect {:padding 40})
zoom (/ (:width size) (:width srect))] zoom (/ (:width size) (:width srect))]
(-> local (-> local
(assoc :zoom zoom) (assoc :zoom zoom)
(assoc :zoom-inverse (/ 1 zoom)) (assoc :zoom-inverse (/ 1 zoom))

View file

@ -229,10 +229,16 @@
edition? (mf/use-state false) edition? (mf/use-state false)
on-show-options on-show-options
(mf/use-fn #(reset! options true)) (mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! options true)))
on-hide-options on-hide-options
(mf/use-fn #(reset! options false)) (mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! options false)))
on-edit-clicked on-edit-clicked
(mf/use-fn (mf/use-fn

View file

@ -97,21 +97,17 @@
(dom/focus! (dom/get-element next-id)))) (dom/focus! (dom/get-element next-id))))
(when (kbd/tab? event) (when (kbd/tab? event)
(on-close)))) (on-close))))]
on-mount (mf/with-effect []
(fn []
(let [keys [(events/listen globals/document EventType.CLICK on-click) (let [keys [(events/listen globals/document EventType.CLICK on-click)
(events/listen globals/document EventType.CONTEXTMENU on-click) (events/listen globals/document EventType.CONTEXTMENU on-click)
(events/listen globals/document EventType.KEYUP on-keyup) (events/listen globals/document EventType.KEYUP on-keyup)
(events/listen globals/document EventType.KEYDOWN on-key-down)]] (events/listen globals/document EventType.KEYDOWN on-key-down)]]
#(doseq [key keys] #(doseq [key keys]
(events/unlistenByKey key))))] (events/unlistenByKey key))))
(mf/use-effect on-mount) [:ul {:class list-class :role "menu"} children]))
[:ul {:class list-class
:role "menu"}
children]))
(mf/defc dropdown-menu (mf/defc dropdown-menu
{::mf/wrap-props false} {::mf/wrap-props false}

View file

@ -32,8 +32,14 @@
emit-blur? (mf/use-ref nil) emit-blur? (mf/use-ref nil)
font-size-wrapper-ref (mf/use-ref) font-size-wrapper-ref (mf/use-ref)
open-dropdown #(swap! state assoc :is-open? true) open-dropdown
close-dropdown #(swap! state assoc :is-open? false) (fn [event]
(dom/stop-propagation event)
(swap! state assoc :is-open? true))
close-dropdown
(fn [event]
(dom/stop-propagation event)
(swap! state assoc :is-open? false))
select-item (fn [value] select-item (fn [value]
(fn [_] (fn [_]
(swap! state assoc :current-value value) (swap! state assoc :current-value value)

View file

@ -39,8 +39,15 @@
current-label (get label-index current-value) current-label (get label-index current-value)
is-open? (:is-open? state) is-open? (:is-open? state)
open-dropdown (mf/use-fn #(swap! state* assoc :is-open? true)) open-dropdown (mf/use-fn
close-dropdown (mf/use-fn #(swap! state* assoc :is-open? false)) (fn [event]
(dom/stop-propagation event)
(swap! state* assoc :is-open? true)))
close-dropdown (mf/use-fn
(fn [event]
(dom/stop-propagation event)
(swap! state* assoc :is-open? false)))
select-item select-item
(mf/use-fn (mf/use-fn
@ -77,7 +84,8 @@
(mf/with-effect [default-value] (mf/with-effect [default-value]
(swap! state* assoc :current-value default-value)) (swap! state* assoc :current-value default-value))
(if new-css-system (if new-css-system
[:div {:on-click open-dropdown :class (dom/classnames (css class) true [:div {:on-click open-dropdown
:class (dom/classnames (css class) true
(css :custom-select) true)} (css :custom-select) true)}
[:span {:class (css :current-label)} current-label] [:span {:class (css :current-label)} current-label]
[:span {:class (css :dropdown-button)} i/arrow-refactor] [:span {:class (css :dropdown-button)} i/arrow-refactor]

View file

@ -227,6 +227,7 @@
i/search])])) i/search])]))
(mf/defc teams-selector-dropdown-items (mf/defc teams-selector-dropdown-items
{::mf/wrap-props false}
[{:keys [team profile teams] :as props}] [{:keys [team profile teams] :as props}]
(let [on-create-clicked (let [on-create-clicked
(mf/use-callback (mf/use-callback
@ -257,6 +258,7 @@
(team-selected (:id team-item) event))) (team-selected (:id team-item) event)))
:id (str "teams-selector-" (:id team-item)) :id (str "teams-selector-" (:id team-item))
:klass "team-name" :klass "team-name"
:key (str "teams-selector-" (:id team-item))
:unique-key (dm/str (:id team-item))} :unique-key (dm/str (:id team-item))}
[:span.team-icon [:span.team-icon
[:img {:src (cf/resolve-team-photo-url team-item) [:img {:src (cf/resolve-team-photo-url team-item)
@ -472,7 +474,9 @@
[:div.sidebar-team-switch [:div.sidebar-team-switch
[:div.switch-content [:div.switch-content
[:button.current-team {:tab-index "0" [:button.current-team {:tab-index "0"
:on-click #(reset! show-teams-ddwn? true) :on-click (fn [event]
(dom/stop-propagation event)
(reset! show-teams-ddwn? true))
:on-key-down (fn [event] :on-key-down (fn [event]
(when (or (kbd/space? event) (kbd/enter? event)) (when (or (kbd/space? event) (kbd/enter? event))
(dom/prevent-default event) (dom/prevent-default event)
@ -496,7 +500,9 @@
i/arrow-down]] i/arrow-down]]
(when-not (:is-default team) (when-not (:is-default team)
[:button.switch-options {:on-click #(reset! show-team-opts-ddwn? true) [:button.switch-options {:on-click (fn [event]
(dom/stop-propagation event)
(reset! show-team-opts-ddwn? true))
:tab-index "0" :tab-index "0"
:on-key-down (fn [event] :on-key-down (fn [event]
(when (or (kbd/space? event) (kbd/enter? event)) (when (or (kbd/space? event) (kbd/enter? event))
@ -674,6 +680,7 @@
(mf/use-callback (mf/use-callback
(fn [section event] (fn [section event]
(dom/stop-propagation event) (dom/stop-propagation event)
(reset! show false)
(if (keyword? section) (if (keyword? section)
(st/emit! (rt/nav section)) (st/emit! (rt/nav section))
(st/emit! section)))) (st/emit! section))))
@ -689,7 +696,9 @@
[:div.profile-section [:div.profile-section
[:div.profile {:tab-index "0" [:div.profile {:tab-index "0"
:on-click #(reset! show true) :on-click (fn [event]
(dom/stop-propagation event)
(reset! show true))
:on-key-down (fn [event] :on-key-down (fn [event]
(when (kbd/enter? event) (when (kbd/enter? event)
(reset! show true))) (reset! show true)))
@ -698,7 +707,9 @@
:alt (:fullname profile)}] :alt (:fullname profile)}]
[:span (:fullname profile)]] [:span (:fullname profile)]]
[:& dropdown-menu {:on-close #(reset! show false) [:& dropdown-menu {:on-close (fn [event]
(dom/stop-propagation event)
(reset! show false))
:show @show} :show @show}
[:ul.dropdown [:ul.dropdown
[:li {:tab-index (if show [:li {:tab-index (if show

View file

@ -226,6 +226,13 @@
(reset! ptr value)) (reset! ptr value))
ptr)) ptr))
(defn use-update-ref
[value]
(let [ref (mf/use-ref value)]
(mf/with-effect [value]
(mf/set-ref-val! ref value))
ref))
(defn use-ref-callback (defn use-ref-callback
"Returns a stable callback pointer what calls the interned "Returns a stable callback pointer what calls the interned
callback. The interned callback will be automatically updated on callback. The interned callback will be automatically updated on

View file

@ -82,11 +82,11 @@
:modal-wrapper (not new-css-system))} :modal-wrapper (not new-css-system))}
(mf/element component (:props data))]))) (mf/element component (:props data))])))
(def modal-ref (def modal-ref
(l/derived ::dm/modal st/state)) (l/derived ::dm/modal st/state))
(mf/defc modal (mf/defc modal
{::mf/wrap-props false}
[] []
(let [modal (mf/deref modal-ref) (let [modal (mf/deref modal-ref)
new-css-system (features/use-feature :new-css-system)] new-css-system (features/use-feature :new-css-system)]

View file

@ -115,4 +115,5 @@
[:& filters/filters {:shape shape-without-shadows :filter-id (dm/fmt "filter_blur_%" render-id)}] [:& filters/filters {:shape shape-without-shadows :filter-id (dm/fmt "filter_blur_%" render-id)}]
[:& fills/fills {:shape shape :render-id render-id}] [:& fills/fills {:shape shape :render-id render-id}]
[:& frame/frame-clip-def {:shape shape :render-id render-id}]] [:& frame/frame-clip-def {:shape shape :render-id render-id}]]
children]])) children]]))

View file

@ -42,7 +42,10 @@
on-zoom-fill] on-zoom-fill]
:as props}] :as props}]
(let [show-dropdown? (mf/use-state false)] (let [show-dropdown? (mf/use-state false)]
[:div.zoom-widget {:on-click #(reset! show-dropdown? true)} [:div.zoom-widget {:on-click
(fn [event]
(dom/stop-propagation event)
(reset! show-dropdown? true))}
[:span.label (fmt/format-percent zoom)] [:span.label (fmt/format-percent zoom)]
[:span.icon i/arrow-down] [:span.icon i/arrow-down]
[:& dropdown {:show @show-dropdown? [:& dropdown {:show @show-dropdown?

View file

@ -272,7 +272,6 @@
:transform (gsh/transform-str shape)}]))) :transform (gsh/transform-str shape)}])))
;; TODO: use-memo use-fn ;; TODO: use-memo use-fn
(defn generic-wrapper-factory (defn generic-wrapper-factory

View file

@ -154,7 +154,10 @@
:color color}])]]]] :color color}])]]]]
[:div.color-palette-actions [:div.color-palette-actions
{:on-click #(swap! state assoc :show-menu true)} {:on-click
(fn [event]
(dom/stop-propagation event)
(swap! state assoc :show-menu true))}
[:div.color-palette-actions-button i/actions]] [:div.color-palette-actions-button i/actions]]
[:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide] [:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]

View file

@ -92,7 +92,10 @@
[:div.comments-section.comment-threads-section [:div.comments-section.comment-threads-section
[:div.workspace-comment-threads-sidebar-header [:div.workspace-comment-threads-sidebar-header
[:div.label (tr "labels.comments")] [:div.label (tr "labels.comments")]
[:div.options {:on-click #(reset! options? true)} [:div.options {:on-click
(fn [event]
(dom/stop-propagation event)
(reset! options? true))}
[:div.label (case (:mode local) [:div.label (case (:mode local)
(nil :all) (tr "labels.all") (nil :all) (tr "labels.all")
:yours (tr "labels.only-yours"))] :yours (tr "labels.only-yours"))]

View file

@ -79,10 +79,16 @@
open? (deref open*) open? (deref open*)
open-dropdown open-dropdown
(mf/use-fn #(reset! open* true)) (mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! open* true)))
close-dropdown close-dropdown
(mf/use-fn #(reset! open* false)) (mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! open* false)))
on-increase on-increase
(mf/use-fn (mf/use-fn
@ -449,9 +455,23 @@
sub-menu* (mf/use-state false) sub-menu* (mf/use-state false)
sub-menu (deref sub-menu*) sub-menu (deref sub-menu*)
open-menu (mf/use-fn #(reset! show-menu* true)) open-menu
close-menu (mf/use-fn #(reset! show-menu* false)) (mf/use-fn
close-sub-menu (mf/use-fn #(reset! sub-menu* nil)) (fn [event]
(dom/stop-propagation event)
(reset! show-menu* true)))
close-menu
(mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! show-menu* false)))
close-sub-menu
(mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! sub-menu* nil)))
on-menu-click on-menu-click
(mf/use-fn (mf/use-fn
@ -465,6 +485,7 @@
toggle-flag toggle-flag
(mf/use-fn (mf/use-fn
(fn [event] (fn [event]
(dom/stop-propagation event)
(let [flag (-> (dom/get-current-target event) (let [flag (-> (dom/get-current-target event)
(dom/get-data "flag") (dom/get-data "flag")
(keyword))] (keyword))]

View file

@ -613,9 +613,23 @@
sub-menu* (mf/use-state false) sub-menu* (mf/use-state false)
sub-menu (deref sub-menu*) sub-menu (deref sub-menu*)
open-menu (mf/use-fn #(reset! show-menu* true)) open-menu
close-menu (mf/use-fn #(reset! show-menu* false)) (mf/use-fn
close-sub-menu (mf/use-fn #(reset! sub-menu* nil)) (fn [event]
(dom/stop-propagation event)
(reset! show-menu* true)))
close-menu
(mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! show-menu* false)))
close-sub-menu
(mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! sub-menu* nil)))
on-menu-click on-menu-click
(mf/use-fn (mf/use-fn
@ -629,6 +643,7 @@
toggle-flag toggle-flag
(mf/use-fn (mf/use-fn
(fn [event] (fn [event]
(dom/stop-propagation event)
(let [flag (-> (dom/get-current-target event) (let [flag (-> (dom/get-current-target event)
(dom/get-data "test") (dom/get-data "test")
(keyword))] (keyword))]

View file

@ -72,10 +72,16 @@
open? (deref open*) open? (deref open*)
open-dropdown open-dropdown
(mf/use-fn #(reset! open* true)) (mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! open* true)))
close-dropdown close-dropdown
(mf/use-fn #(reset! open* false)) (mf/use-fn
(fn [event]
(dom/stop-propagation event)
(reset! open* false)))
on-increase on-increase
(mf/use-fn (mf/use-fn

View file

@ -57,15 +57,14 @@
{::mf/wrap [#(mf/memo' % check-props)] {::mf/wrap [#(mf/memo' % check-props)]
::mf/wrap-props false} ::mf/wrap-props false}
[props] [props]
(let [shape (unchecked-get props "shape") (let [shape (unchecked-get props "shape")
frame-id (:id shape) frame-id (:id shape)
objects (wsh/lookup-page-objects @st/state) objects (wsh/lookup-page-objects @st/state)
node-ref (mf/use-var nil) node-ref (mf/use-ref nil)
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)]
(fdm/use-dynamic-modifiers objects @node-ref modifiers) (fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers)
(let [shape (unchecked-get props "shape")] (let [shape (unchecked-get props "shape")]
[:& frame-shape {:shape shape :ref node-ref}]))))) [:& frame-shape {:shape shape :ref node-ref}])))))
@ -86,53 +85,62 @@
objects (wsh/lookup-page-objects @st/state) objects (wsh/lookup-page-objects @st/state)
node* (mf/use-var nil) node-ref (mf/use-ref nil)
root-ref (mf/use-ref nil)
force-render* (mf/use-state false) force-render* (mf/use-state false)
force-render? (deref force-render*) force-render? (deref force-render*)
;; when `true` we've called the mount for the frame ;; when `true` we've called the mount for the frame
rendered* (mf/use-var false) rendered-ref (mf/use-ref false)
modifiers-ref (mf/with-memo [frame-id] modifiers-ref (mf/with-memo [frame-id]
(refs/workspace-modifiers-by-frame-id frame-id)) (refs/workspace-modifiers-by-frame-id frame-id))
modifiers (mf/deref modifiers-ref) modifiers (mf/deref modifiers-ref)
fonts (mf/with-memo [shape objects] fonts (mf/with-memo [shape objects]
(ff/shape->fonts shape objects)) (ff/shape->fonts shape objects))
fonts (hooks/use-equal-memo fonts) fonts (hooks/use-equal-memo fonts)
disable-thumbnail? (d/not-empty? (dm/get-in modifiers [frame-id :modifiers])) disable-thumbnail? (d/not-empty? (dm/get-in modifiers [frame-id :modifiers]))
[on-load-frame-dom render-frame? thumbnail-renderer] [on-load-frame-dom render-frame? children]
(ftr/use-render-thumbnail page-id shape node* rendered* disable-thumbnail? force-render?) (ftr/use-render-thumbnail page-id shape root-ref node-ref rendered-ref disable-thumbnail? force-render?)
on-frame-load on-frame-load
(fns/use-node-store thumbnail? node* rendered* render-frame?)] (fns/use-node-store node-ref rendered-ref thumbnail? render-frame?)
]
(fdm/use-dynamic-modifiers objects @node* modifiers) (fdm/use-dynamic-modifiers objects (mf/ref-val node-ref) modifiers)
(mf/with-effect [] (mf/with-effect []
;; When a change in the data is received a "force-render" event is emitted ;; When a change in the data is received a "force-render" event is emitted
;; that will force the component to be mounted in memory ;; that will force the component to be mounted in memory
(let [sub (->> (dwt/force-render-stream frame-id) (let [sub (->> (dwt/force-render-stream frame-id)
(rx/take-while #(not @rendered*)) (rx/take-while #(not (mf/ref-val rendered-ref)))
(rx/subs #(reset! force-render* true)))] (rx/subs #(reset! force-render* true)))]
#(some-> sub rx/dispose!))) #(some-> sub rx/dispose!)))
(mf/with-effect [shape fonts thumbnail? on-load-frame-dom force-render? render-frame?] (mf/with-effect [shape fonts thumbnail? on-load-frame-dom force-render? render-frame?]
(when (and (some? @node*) (when (and (some? (mf/ref-val node-ref))
(or @rendered* (or (mf/ref-val rendered-ref)
(not thumbnail?) (false? thumbnail?)
force-render? (true? force-render?)
render-frame?)) (true? render-frame?)))
(let [elem (mf/element frame-shape #js {:ref on-load-frame-dom :shape shape :fonts fonts})]
(mf/mount elem @node*) (when (false? (mf/ref-val rendered-ref))
(when (not @rendered*) (when-let [node (mf/ref-val node-ref)]
(reset! rendered* true))))) (mf/set-ref-val! root-ref (mf/create-root node))
(mf/set-ref-val! rendered-ref true)))
(when-let [root (mf/ref-val root-ref)]
(mf/render! root (mf/element frame-shape #js {:ref on-load-frame-dom :shape shape :fonts fonts})))
(constantly nil)))
[:& shape-container {:shape shape} [:& shape-container {:shape shape}
[:g.frame-container {:id (dm/str "frame-container-" frame-id) [:g.frame-container
{:id (dm/str "frame-container-" frame-id)
:key "frame-container" :key "frame-container"
:ref on-frame-load :ref on-frame-load
:opacity (when (:hidden shape) 0)} :opacity (when (:hidden shape) 0)}
@ -141,7 +149,7 @@
{:id (dm/str "thumbnail-container-" frame-id) {:id (dm/str "thumbnail-container-" frame-id)
;; Hide the thumbnail when not displaying ;; Hide the thumbnail when not displaying
:opacity (when-not thumbnail? 0)} :opacity (when-not thumbnail? 0)}
thumbnail-renderer]] children]]
])))) ]))))

View file

@ -18,7 +18,7 @@
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
[app.main.ui.workspace.viewport.utils :as vwu] [app.main.ui.workspace.viewport.utils :as vwu]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.globals :as globals] [app.util.timers :as ts]
[debug :refer [debug?]] [debug :refer [debug?]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -230,11 +230,8 @@
(defn use-dynamic-modifiers (defn use-dynamic-modifiers
[objects node modifiers] [objects node modifiers]
(let [transforms (let [transforms
(mf/use-memo (mf/with-memo [modifiers]
(mf/deps modifiers)
(fn []
(when (some? modifiers) (when (some? modifiers)
(d/mapm (fn [id {current-modifiers :modifiers}] (d/mapm (fn [id {current-modifiers :modifiers}]
(let [shape (get objects id) (let [shape (get objects id)
@ -245,42 +242,43 @@
adapt-text? adapt-text?
(adapt-text-modifiers shape))] (adapt-text-modifiers shape))]
(ctm/modifiers->transform current-modifiers))) (ctm/modifiers->transform current-modifiers)))
modifiers)))) modifiers)))
add-children (mf/use-memo (mf/deps modifiers) #(ctm/added-children-frames modifiers)) add-children
add-children (hooks/use-equal-memo add-children) (mf/with-memo [modifiers]
add-children-prev (hooks/use-previous add-children) (ctm/added-children-frames modifiers))
shapes shapes
(mf/use-memo (mf/with-memo [transforms]
(mf/deps transforms)
(fn []
(->> (keys transforms) (->> (keys transforms)
(filter #(some? (get transforms %))) (filter #(some? (get transforms %)))
(mapv (comp (add-masking-child? objects) (d/getf objects)))))) (mapv (comp (add-masking-child? objects) (d/getf objects)))))
add-children (hooks/use-equal-memo add-children)
add-children-prev (hooks/use-previous add-children)
prev-shapes (mf/use-var nil) prev-shapes (mf/use-var nil)
prev-modifiers (mf/use-var nil) prev-modifiers (mf/use-var nil)
prev-transforms (mf/use-var nil)] prev-transforms (mf/use-var nil)]
(mf/use-effect (mf/with-effect [add-children]
(mf/deps add-children) (ts/raf
(fn [] #(doseq [{:keys [shape]} add-children-prev]
(doseq [{:keys [shape]} add-children-prev]
(let [shape-node (get-shape-node shape) (let [shape-node (get-shape-node shape)
mirror-node (dom/query (dm/fmt ".mirror-shape[href='#shape-%'" shape))] mirror-node (dom/query (dm/fmt ".mirror-shape[href='#shape-%'" shape))]
(when mirror-node (.remove mirror-node)) (when mirror-node (.remove mirror-node))
(dom/remove-attribute! (dom/get-parent shape-node) "display"))) (dom/remove-attribute! (dom/get-parent shape-node) "display"))))
(doseq [{:keys [frame shape]} add-children] (ts/raf
#(doseq [{:keys [frame shape]} add-children]
(let [frame-node (get-shape-node frame) (let [frame-node (get-shape-node frame)
shape-node (get-shape-node shape) shape-node (get-shape-node shape)
clip-id clip-id
(dom/get-attribute (dom/query frame-node ":scope > defs > .frame-clip-def") "id") (-> (dom/query frame-node ":scope > defs > .frame-clip-def")
(dom/get-attribute "id"))
use-node use-node
(.createElementNS globals/document "http://www.w3.org/2000/svg" "use") (dom/create-element "http://www.w3.org/2000/svg" "use")
contents-node contents-node
(or (dom/query frame-node ".frame-children") frame-node)] (or (dom/query frame-node ".frame-children") frame-node)]
@ -291,24 +289,28 @@
(dom/append-child! contents-node use-node) (dom/append-child! contents-node use-node)
(dom/set-attribute! (dom/get-parent shape-node) "display" "none"))))) (dom/set-attribute! (dom/get-parent shape-node) "display" "none")))))
(mf/use-layout-effect (mf/with-effect [transforms]
(mf/deps transforms)
(fn []
(let [curr-shapes-set (into #{} (map :id) shapes) (let [curr-shapes-set (into #{} (map :id) shapes)
prev-shapes-set (into #{} (map :id) @prev-shapes) prev-shapes-set (into #{} (map :id) @prev-shapes)
new-shapes (->> shapes (remove #(contains? prev-shapes-set (:id %)))) new-shapes (->> shapes (remove #(contains? prev-shapes-set (:id %))))
removed-shapes (->> @prev-shapes (remove #(contains? curr-shapes-set (:id %))))] removed-shapes (->> @prev-shapes (remove #(contains? curr-shapes-set (:id %))))]
;; NOTE: we schedule the dom modifications to be executed
;; asynchronously for avoid component flickering when react18
;; is used.
(when (d/not-empty? new-shapes) (when (d/not-empty? new-shapes)
(start-transform! node new-shapes)) (ts/raf #(start-transform! node new-shapes)))
(when (d/not-empty? shapes) (when (d/not-empty? shapes)
(update-transform! node shapes transforms modifiers)) (ts/raf #(update-transform! node shapes transforms modifiers)))
(when (d/not-empty? removed-shapes) (when (d/not-empty? removed-shapes)
(remove-transform! node removed-shapes))) (ts/raf #(remove-transform! node removed-shapes))))
(reset! prev-modifiers modifiers) (reset! prev-modifiers modifiers)
(reset! prev-transforms transforms) (reset! prev-transforms transforms)
(reset! prev-shapes shapes))))) (reset! prev-shapes shapes))
))

View file

@ -7,40 +7,49 @@
(ns app.main.ui.workspace.shapes.frame.node-store (ns app.main.ui.workspace.shapes.frame.node-store
(:require (:require
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.globals :as globals]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(defn use-node-store (defn use-node-store
"Hook responsible of storing the rendered DOM node in memory while not being used" "Hook responsible of storing the rendered DOM node in memory while not being used"
[thumbnail? node-ref rendered? render-frame?] [node-ref rendered-ref thumbnail? render-frame?]
(let [;; when `true` the node is in memory (let [re-render* (mf/use-state 0)
in-memory? (mf/use-state true) parent-ref (mf/use-ref nil)
present-ref (mf/use-ref false)
;; State just for re-rendering
re-render (mf/use-state 0)
parent-ref (mf/use-var nil)
on-frame-load on-frame-load
(mf/use-callback (mf/use-fn
(fn [node] (fn [node]
(when (and (some? node) (nil? @node-ref)) (when (and (some? node)
(let [content (-> (.createElementNS globals/document "http://www.w3.org/2000/svg" "g") (nil? (mf/ref-val node-ref)))
(let [content (-> (dom/create-element "http://www.w3.org/2000/svg" "g")
(dom/add-class! "frame-content"))] (dom/add-class! "frame-content"))]
(reset! node-ref content) (mf/set-ref-val! node-ref content)
(reset! parent-ref node) (mf/set-ref-val! parent-ref node)
(swap! re-render inc)))))] (swap! re-render* inc)))))]
(mf/use-layout-effect (mf/with-effect [thumbnail? render-frame?]
(mf/deps thumbnail? render-frame?) (let [rendered? (mf/ref-val rendered-ref)
(fn [] present? (mf/ref-val present-ref)]
(when (and (some? @parent-ref) (some? @node-ref) @rendered? (and thumbnail? (not render-frame?)))
(.removeChild @parent-ref @node-ref)
(reset! in-memory? true))
(when (and (some? @node-ref) @in-memory? (or (not thumbnail?) render-frame?)) (when (and (true? rendered?)
(.appendChild @parent-ref @node-ref) (true? thumbnail?)
(reset! in-memory? false)))) (false? render-frame?)
(true? present?))
(when-let [parent (mf/ref-val parent-ref)]
(when-let [node (mf/ref-val node-ref)]
(dom/remove-child! parent node)
(mf/set-ref-val! present-ref false)
(swap! re-render* inc))))
(when (and (false? present?)
(or (false? thumbnail?)
(true? render-frame?)))
(when-let [parent (mf/ref-val parent-ref)]
(when-let [node (mf/ref-val node-ref)]
(when-not (dom/child? parent node)
(dom/append-child! parent node)
(mf/set-ref-val! present-ref true)
(swap! re-render* inc)))))))
on-frame-load)) on-frame-load))

View file

@ -66,18 +66,17 @@
(defn use-render-thumbnail (defn use-render-thumbnail
"Hook that will create the thumbnail data" "Hook that will create the thumbnail data"
[page-id {:keys [id] :as shape} node-ref rendered? disable? force-render] [page-id {:keys [id] :as shape} root-ref node-ref rendered-ref disable? force-render]
(let [frame-image-ref (mf/use-ref nil) (let [frame-image-ref (mf/use-ref nil)
disable* (mf/use-var disable?) disable-ref (mf/use-ref disable?)
regenerate* (mf/use-var false) regenerate-ref (mf/use-ref false)
all-children-ref (mf/with-memo [id] all-children-ref (mf/with-memo [id]
(refs/all-children-objects id)) (refs/all-children-objects id))
all-children (mf/deref all-children-ref) all-children (mf/deref all-children-ref)
;; FIXME: performance rect
bounds bounds
(if (:show-content shape) (if (:show-content shape)
(gsh/shapes->rect (cons shape all-children)) (gsh/shapes->rect (cons shape all-children))
@ -89,37 +88,44 @@
height (dm/get-prop bounds :height) height (dm/get-prop bounds :height)
svg-uri* (mf/use-state nil) svg-uri* (mf/use-state nil)
bitmap-uri* (mf/use-state nil) svg-uri (deref svg-uri*)
observer* (mf/use-var nil)
bounds* (hooks/use-update-var bounds) bitmap-uri* (mf/use-state nil)
bitmap-uri (deref bitmap-uri*)
observer-ref (mf/use-ref nil)
bounds-ref (hooks/use-update-ref bounds)
updates-s (mf/use-memo rx/subject) updates-s (mf/use-memo rx/subject)
thumbnail-uri-ref (mf/with-memo [page-id id] thumbnail-uri* (mf/with-memo [page-id id]
(refs/thumbnail-frame-data page-id id)) (refs/thumbnail-frame-data page-id id))
thumbnail-uri (mf/deref thumbnail-uri-ref) thumbnail-uri (mf/deref thumbnail-uri*)
;; State to indicate to the parent that should render the frame ;; State to indicate to the parent that should render the frame
render-frame* (mf/use-state (not thumbnail-uri)) render-frame* (mf/use-state (not thumbnail-uri))
render-frame? (deref render-frame*)
debug? (debug? :thumbnails) debug? (debug? :thumbnails)
on-bitmap-load on-bitmap-load
(mf/use-fn (mf/use-fn
(mf/deps svg-uri)
(fn [] (fn []
;; We revoke the SVG Blob URI to free memory only when we ;; We revoke the SVG Blob URI to free memory only when we
;; are sure that it is not used anymore. ;; are sure that it is not used anymore.
(wapi/revoke-uri @svg-uri*) (some-> svg-uri wapi/revoke-uri)
(reset! svg-uri* nil))) (reset! svg-uri* nil)))
on-svg-load on-svg-load
(mf/use-callback (mf/use-fn
(mf/deps thumbnail-uri)
(fn [] (fn []
(let [image-node (mf/ref-val frame-image-ref)] (let [image-node (mf/ref-val frame-image-ref)]
(dom/set-data! image-node "ready" "true") (dom/set-data! image-node "ready" "true")
;; If we don't have the thumbnail data saved (normally the first load) we update the data ;; If we don't have the thumbnail data saved (normally the first load) we update the data
;; when available ;; when available
(when (not ^boolean @thumbnail-uri-ref) (when-not (some? thumbnail-uri)
(st/emit! (dwt/update-thumbnail page-id id))) (st/emit! (dwt/update-thumbnail page-id id)))
(reset! render-frame* false)))) (reset! render-frame* false))))
@ -131,34 +137,37 @@
(try (try
;; When starting generating the canvas we mark it as not ready so its not send to back until ;; When starting generating the canvas we mark it as not ready so its not send to back until
;; we have time to update it ;; we have time to update it
(let [node @node-ref]
(when-let [node (mf/ref-val node-ref)]
(if (dom/has-children? node) (if (dom/has-children? node)
;; The frame-content need to have children in order to generate the thumbnail ;; The frame-content need to have children in order to generate the thumbnail
(let [style-node (dom/query (dm/str "#frame-container-" id " style")) (let [style-node (dom/query (dm/str "#frame-container-" id " style"))
url (create-svg-blob-uri-from @bounds* node style-node)] bounds (mf/ref-val bounds-ref)
url (create-svg-blob-uri-from bounds node style-node)]
(reset! svg-uri* url)) (reset! svg-uri* url))
;; Node not yet ready, we schedule a new generation ;; Node not yet ready, we schedule a new generation
(ts/raf generate-thumbnail))) (ts/raf generate-thumbnail)))
(catch :default e (catch :default e
(.error js/console e))))) (.error js/console e)))))
on-change-frame on-change-frame
(mf/use-fn (mf/use-fn
(mf/deps id) (mf/deps id generate-thumbnail)
(fn [] (fn []
(when (and ^boolean @node-ref (when (and (some? (mf/ref-val node-ref))
^boolean @rendered? (some? (mf/ref-val rendered-ref))
^boolean @regenerate*) (some? (mf/ref-val regenerate-ref)))
(let [loading-images? (some? (dom/query @node-ref "[data-loading='true']")) (let [node (mf/ref-val node-ref)
loading-images? (some? (dom/query node "[data-loading='true']"))
loading-fonts? (some? (dom/query (dm/str "#frame-container-" id " > style[data-loading='true']")))] loading-fonts? (some? (dom/query (dm/str "#frame-container-" id " > style[data-loading='true']")))]
(when (and (not loading-images?) (when (and (not loading-images?)
(not loading-fonts?)) (not loading-fonts?))
(reset! svg-uri* nil) (reset! svg-uri* nil)
(reset! bitmap-uri* nil) (reset! bitmap-uri* nil)
(generate-thumbnail) (generate-thumbnail)
(reset! regenerate* false)))))) (mf/set-ref-val! regenerate-ref false))))))
;; When the frame is updated, it is marked as not ready ;; When the frame is updated, it is marked as not ready
;; so that it is not sent to the background until ;; so that it is not sent to the background until
@ -169,23 +178,27 @@
(let [image-node (mf/ref-val frame-image-ref)] (let [image-node (mf/ref-val frame-image-ref)]
(when (not= "false" (dom/get-data image-node "ready")) (when (not= "false" (dom/get-data image-node "ready"))
(dom/set-data! image-node "ready" "false"))) (dom/set-data! image-node "ready" "false")))
(when-not ^boolean @disable*
(when-not ^boolean (mf/ref-val disable-ref)
(reset! svg-uri* nil) (reset! svg-uri* nil)
(reset! bitmap-uri* nil) (reset! bitmap-uri* nil)
(reset! render-frame* true) (reset! render-frame* true)
(reset! regenerate* true)))) (mf/set-ref-val! regenerate-ref true))))
on-load-frame-dom on-load-frame-dom
(mf/use-fn (mf/use-fn
(fn [node] (fn [node]
(when (and (some? node) (when (and (nil? (mf/ref-val observer-ref)) (some? node))
(nil? @observer*)) (when-not (some? @thumbnail-uri*)
(when-not (some? @thumbnail-uri-ref)
(rx/push! updates-s :update)) (rx/push! updates-s :update))
(let [observer (js/MutationObserver. (partial rx/push! updates-s))] (let [observer (js/MutationObserver. (partial rx/push! updates-s))]
(.observe observer node #js {:childList true :attributes true :attributeOldValue true :characterData true :subtree true}) (.observe observer node #js {:childList true
(reset! observer* observer)))))] :attributes true
:attributeOldValue true
:characterData true
:subtree true})
(mf/set-ref-val! observer-ref observer)))))]
(mf/with-effect [thumbnail-uri] (mf/with-effect [thumbnail-uri]
(when (some? thumbnail-uri) (when (some? thumbnail-uri)
@ -213,25 +226,30 @@
(partial rx/dispose! subid))) (partial rx/dispose! subid)))
(mf/with-effect [disable?] (mf/with-effect [disable?]
(when (and ^boolean disable? (when (and ^boolean disable? (not (mf/ref-val disable-ref)))
(not @disable*))
(rx/push! updates-s :update)) (rx/push! updates-s :update))
(reset! disable* disable?)
(mf/set-ref-val! disable-ref disable?)
nil) nil)
(mf/with-effect [] (mf/with-effect []
(fn [] (fn []
(when (and (some? @node-ref) (when (and (some? (mf/ref-val node-ref))
^boolean @rendered?) (true? (mf/ref-val rendered-ref)))
(mf/unmount @node-ref) (when-let [root (mf/ref-val root-ref)]
(reset! node-ref nil) ;; NOTE: the unmount should be always scheduled to be
(reset! rendered? false) ;; executed asynchronously of the current flow (react
(when (some? @observer*) ;; rules).
(.disconnect @observer*) (ts/schedule #(mf/unmount! ^js root)))
(reset! observer* nil)))))
[on-load-frame-dom (mf/set-ref-val! node-ref nil)
@render-frame* (mf/set-ref-val! rendered-ref false)
(when-let [observer (mf/ref-val observer-ref)]
(.disconnect ^js observer)
(mf/set-ref-val! observer-ref nil)))))
[on-load-frame-dom render-frame?
(mf/html (mf/html
[:& frame/frame-container {:bounds bounds :shape shape} [:& frame/frame-container {:bounds bounds :shape shape}
@ -251,18 +269,18 @@
;; to be rendered on screen. Then we remove the ;; to be rendered on screen. Then we remove the
;; svg and keep the bitmap one. ;; svg and keep the bitmap one.
;; This is the "buffer" that keeps the bitmap image. ;; This is the "buffer" that keeps the bitmap image.
(when ^boolean @bitmap-uri* (when (some? bitmap-uri)
[:image.thumbnail-bitmap [:image.thumbnail-bitmap
{:x x {:x x
:y y :y y
:width width :width width
:height height :height height
:href @bitmap-uri* :href bitmap-uri
:style {:filter (when ^boolean debug? "sepia(1)")} :style {:filter (when ^boolean debug? "sepia(1)")}
:on-load on-bitmap-load}]) :on-load on-bitmap-load}])
;; This is the "buffer" that keeps the SVG image. ;; This is the "buffer" that keeps the SVG image.
(when ^boolean @svg-uri* (when (some? svg-uri)
[:image.thumbnail-canvas [:image.thumbnail-canvas
{:x x {:x x
:y y :y y
@ -271,6 +289,6 @@
:width width :width width
:height height :height height
:ref frame-image-ref :ref frame-image-ref
:href @svg-uri* :href svg-uri
:style {:filter (when ^boolean debug? "sepia(0.5)")} :style {:filter (when ^boolean debug? "sepia(0.5)")}
:on-load on-svg-load}])])])) :on-load on-svg-load}])])]))

View file

@ -124,7 +124,10 @@
(str/format " (%s)" (count file-typographies)))]]]] (str/format " (%s)" (count file-typographies)))]]]]
[:div.color-palette-actions [:div.color-palette-actions
{:on-click #(swap! state assoc :show-menu true)} {:on-click
(fn [event]
(dom/stop-propagation event)
(swap! state assoc :show-menu true))}
[:div.color-palette-actions-button i/actions]] [:div.color-palette-actions-button i/actions]]
[:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide] [:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]

View file

@ -69,7 +69,7 @@
selected)) selected))
(mf/defc viewport (mf/defc viewport
[{:keys [wlocal wglobal selected layout file] :as props}] [{:keys [selected wglobal wlocal layout file] :as props}]
(let [;; When adding data from workspace-local revisit `app.main.ui.workspace` to check (let [;; When adding data from workspace-local revisit `app.main.ui.workspace` to check
;; that the new parameter is sent ;; that the new parameter is sent
{:keys [edit-path {:keys [edit-path

View file

@ -12,7 +12,9 @@
[app.main.ui.css-cursors :as cur] [app.main.ui.css-cursors :as cur]
[app.main.ui.formats :refer [format-number]])) [app.main.ui.formats :refer [format-number]]))
(defn format-viewbox [vbox] (defn format-viewbox
"Format a viewbox to a string"
[vbox]
(dm/str (format-number(:x vbox 0)) " " (dm/str (format-number(:x vbox 0)) " "
(format-number (:y vbox 0)) " " (format-number (:y vbox 0)) " "
(format-number (:width vbox 0)) " " (format-number (:width vbox 0)) " "

View file

@ -32,6 +32,10 @@
(l/setup! {:app :info}) (l/setup! {:app :info})
(defonce app-root
(let [el (dom/get-element "app")]
(mf/create-root el)))
(declare ^:private render-single-object) (declare ^:private render-single-object)
(declare ^:private render-components) (declare ^:private render-components)
(declare ^:private render-objects) (declare ^:private render-objects)
@ -48,7 +52,7 @@
"objects" (render-objects params) "objects" (render-objects params)
"components" (render-components params) "components" (render-components params)
nil)] nil)]
(mf/mount component (dom/get-element "app"))))) (mf/render! app-root component))))
(defn ^:export init (defn ^:export init
[] []
@ -57,7 +61,7 @@
(defn reinit (defn reinit
[] []
(mf/unmount (dom/get-element "app")) (mf/unmount! app-root)
(init-ui)) (init-ui))
(defn ^:dev/after-load after-load (defn ^:dev/after-load after-load

View file

@ -191,6 +191,7 @@
(rx/mapcat #(wapi/create-image-bitmap % #js {:resizeWidth width (rx/mapcat #(wapi/create-image-bitmap % #js {:resizeWidth width
:resizeQuality "medium"})) :resizeQuality "medium"}))
(rx/tap #(wapi/revoke-uri uri))))) (rx/tap #(wapi/revoke-uri uri)))))
(rx/mapcat bitmap->blob)))) (rx/mapcat bitmap->blob))))
(defn- on-message (defn- on-message

View file

@ -62,6 +62,7 @@
(defn- render-thumbnail (defn- render-thumbnail
[{:keys [page file-id revn] :as params}] [{:keys [page file-id revn] :as params}]
(try
(binding [fonts/loaded-hints (l/atom #{})] (binding [fonts/loaded-hints (l/atom #{})]
(let [objects (:objects page) (let [objects (:objects page)
frame (some->> page :thumbnail-frame-id (get objects)) frame (some->> page :thumbnail-frame-id (get objects))
@ -69,11 +70,13 @@
(mf/element render/frame-svg #js {:objects objects :frame frame :show-thumbnails? true}) (mf/element render/frame-svg #js {:objects objects :frame frame :show-thumbnails? true})
(mf/element render/page-svg #js {:data page :thumbnails? true :render-embed? true})) (mf/element render/page-svg #js {:data page :thumbnails? true :render-embed? true}))
data (rds/renderToStaticMarkup element)] data (rds/renderToStaticMarkup element)]
{:data data {:data data
:fonts @fonts/loaded-hints :fonts @fonts/loaded-hints
:file-id file-id :file-id file-id
:revn revn}))) :revn revn}))
(catch :default cause
(js/console.error "unexpected erorr on rendering thumbnail" cause)
nil)))
(defmethod impl/handler :thumbnails/generate-for-file (defmethod impl/handler :thumbnails/generate-for-file
[{:keys [file-id revn features] :as message} _] [{:keys [file-id revn features] :as message} _]
@ -85,9 +88,7 @@
(let [canvas (js/OffscreenCanvas. (.-width ^js ibpm) (.-height ^js ibpm)) (let [canvas (js/OffscreenCanvas. (.-width ^js ibpm) (.-height ^js ibpm))
ctx (.getContext ^js canvas "bitmaprenderer") ctx (.getContext ^js canvas "bitmaprenderer")
tp (ts/tpoint-ms)] tp (ts/tpoint-ms)]
(.transferFromImageBitmap ^js ctx ibpm) (.transferFromImageBitmap ^js ctx ibpm)
(->> (.convertToBlob ^js canvas #js {:type "image/png"}) (->> (.convertToBlob ^js canvas #js {:type "image/png"})
(p/fmap (fn [blob] (p/fmap (fn [blob]
{:result (wapi/create-uri blob)})) {:result (wapi/create-uri blob)}))

View file

@ -4406,14 +4406,13 @@ randomfill@^1.0.3:
randombytes "^2.0.5" randombytes "^2.0.5"
safe-buffer "^5.1.0" safe-buffer "^5.1.0"
react-dom@~17.0.2: react-dom@^18.2.0:
version "17.0.2" version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" scheduler "^0.23.0"
scheduler "^0.20.2"
react-is@^16.13.1: react-is@^16.13.1:
version "16.13.1" version "16.13.1"
@ -4437,13 +4436,12 @@ react-virtualized@^9.22.3:
prop-types "^15.7.2" prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4" react-lifecycles-compat "^3.0.4"
react@~17.0.2: react@^18.2.0:
version "17.0.2" version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1"
read-pkg-up@^1.0.1: read-pkg-up@^1.0.1:
version "1.0.1" version "1.0.1"
@ -4757,13 +4755,12 @@ sax@^1.2.4, sax@~1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
scheduler@^0.20.2: scheduler@^0.23.0:
version "0.20.2" version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1"
semver-greatest-satisfied-range@^1.1.0: semver-greatest-satisfied-range@^1.1.0:
version "1.1.0" version "1.1.0"