mirror of
https://github.com/penpot/penpot.git
synced 2025-06-05 11:11:43 +02:00
♻️ Refactor viewer state management (partial)
This commit is contained in:
parent
48de242a2d
commit
50d371c14b
11 changed files with 434 additions and 297 deletions
|
@ -18,93 +18,122 @@
|
|||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.viewer.shapes :as shapes]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
[goog.events :as events]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(defn prepare-objects
|
||||
[page frame size]
|
||||
(fn []
|
||||
(let [objects (:objects page)
|
||||
frame-id (:id frame)
|
||||
modifier (-> (gpt/point (:x size) (:y size))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))
|
||||
(let [objects (:objects page)
|
||||
frame-id (:id frame)
|
||||
modifier (-> (gpt/point (:x size) (:y size))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))
|
||||
|
||||
update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)]
|
||||
update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)]
|
||||
|
||||
(->> (cph/get-children-ids objects frame-id)
|
||||
(into [frame-id])
|
||||
(reduce update-fn objects)))))
|
||||
(->> (cph/get-children-ids objects frame-id)
|
||||
(into [frame-id])
|
||||
(reduce update-fn objects))))
|
||||
|
||||
(mf/defc viewport
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [page interactions-mode frame base-frame frame-offset size]}]
|
||||
(let [objects (mf/use-memo
|
||||
(mf/deps page frame size)
|
||||
(prepare-objects page frame size))
|
||||
(mf/defc viewport-svg
|
||||
{::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")
|
||||
|
||||
wrapper (mf/use-memo
|
||||
(mf/deps objects)
|
||||
#(shapes/frame-container-factory objects))
|
||||
vbox (:vbox size)
|
||||
|
||||
objects (mf/with-memo [page frame size]
|
||||
(prepare-objects page frame size))
|
||||
|
||||
wrapper (mf/with-memo [objects]
|
||||
(shapes/frame-container-factory objects))
|
||||
|
||||
;; Retrieve frames again with correct modifier
|
||||
frame (get objects (:id frame))
|
||||
base-frame (get objects (:id base-frame))
|
||||
frame (get objects (:id frame))
|
||||
base (get objects (:id base))]
|
||||
|
||||
on-click
|
||||
(fn [_]
|
||||
(when (= interactions-mode :show-on-click)
|
||||
(st/emit! dv/flash-interactions)))
|
||||
|
||||
on-mouse-wheel
|
||||
(fn [event]
|
||||
(when (kbd/mod? event)
|
||||
(dom/prevent-default event)
|
||||
(let [event (.getBrowserEvent ^js event)
|
||||
delta (+ (.-deltaY ^js event) (.-deltaX ^js event))]
|
||||
(if (pos? delta)
|
||||
(st/emit! dv/decrease-zoom)
|
||||
(st/emit! dv/increase-zoom)))))
|
||||
|
||||
on-key-down
|
||||
(fn [event]
|
||||
(when (kbd/esc? event)
|
||||
(st/emit! (dcm/close-thread))))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps interactions-mode) ;; on-click event depends on interactions-mode
|
||||
(fn []
|
||||
;; bind with passive=false to allow the event to be cancelled
|
||||
;; https://stackoverflow.com/a/57582286/3219895
|
||||
(let [key1 (events/listen goog/global "wheel" on-mouse-wheel #js {"passive" false})
|
||||
key2 (events/listen js/window "keydown" on-key-down)
|
||||
key3 (events/listen js/window "click" on-click)]
|
||||
(fn []
|
||||
(events/unlistenByKey key1)
|
||||
(events/unlistenByKey key2)
|
||||
(events/unlistenByKey key3)))))
|
||||
|
||||
[:& (mf/provider shapes/base-frame-ctx) {:value base-frame}
|
||||
[:& (mf/provider shapes/frame-offset-ctx) {:value frame-offset}
|
||||
[:svg {:view-box (:vbox size)
|
||||
[:& (mf/provider shapes/base-frame-ctx) {:value base}
|
||||
[:& (mf/provider shapes/frame-offset-ctx) {:value offset}
|
||||
[:svg {:view-box vbox
|
||||
:width (:width size)
|
||||
:height (:height size)
|
||||
:version "1.1"
|
||||
:xmlnsXlink "http://www.w3.org/1999/xlink"
|
||||
:xmlns "http://www.w3.org/2000/svg"
|
||||
:fill "none"}
|
||||
[:& wrapper {:shape frame
|
||||
:view-box (:vbox size)}]]]]))
|
||||
[:& wrapper {:shape frame :view-box vbox}]]]]))
|
||||
|
||||
(mf/defc viewport
|
||||
{
|
||||
::mf/wrap [mf/memo]
|
||||
::mf/wrap-props false}
|
||||
[props]
|
||||
(let [;; NOTE: with `use-equal-memo` hook we ensure that all values
|
||||
;; conserves the reference identity for avoid unnecesary dummy
|
||||
;; rerenders.
|
||||
mode (h/use-equal-memo (unchecked-get props "interactions-mode"))
|
||||
offset (h/use-equal-memo (unchecked-get props "frame-offset"))
|
||||
size (h/use-equal-memo (unchecked-get props "size"))
|
||||
|
||||
page (unchecked-get props "page")
|
||||
frame (unchecked-get props "frame")
|
||||
base (unchecked-get props "base-frame")]
|
||||
|
||||
|
||||
(mf/with-effect [mode]
|
||||
(let [on-click
|
||||
(fn [_]
|
||||
(when (= mode :show-on-click)
|
||||
(st/emit! (dv/flash-interactions))))
|
||||
|
||||
on-mouse-wheel
|
||||
(fn [event]
|
||||
(when (kbd/mod? event)
|
||||
(dom/prevent-default event)
|
||||
(let [event (dom/event->browser-event event)
|
||||
delta (+ (.-deltaY ^js event)
|
||||
(.-deltaX ^js event))]
|
||||
(if (pos? delta)
|
||||
(st/emit! dv/decrease-zoom)
|
||||
(st/emit! dv/increase-zoom)))))
|
||||
|
||||
on-key-down
|
||||
(fn [event]
|
||||
(when (kbd/esc? event)
|
||||
(st/emit! (dcm/close-thread))))
|
||||
|
||||
|
||||
;; bind with passive=false to allow the event to be cancelled
|
||||
;; https://stackoverflow.com/a/57582286/3219895
|
||||
key1 (events/listen goog/global "wheel" on-mouse-wheel #js {"passive" false})
|
||||
key2 (events/listen goog/global "keydown" on-key-down)
|
||||
key3 (events/listen goog/global "click" on-click)]
|
||||
(fn []
|
||||
(events/unlistenByKey key1)
|
||||
(events/unlistenByKey key2)
|
||||
(events/unlistenByKey key3))))
|
||||
|
||||
[:& viewport-svg {:page page
|
||||
:frame frame
|
||||
:base base
|
||||
:offset offset
|
||||
:size size}]))
|
||||
|
||||
(mf/defc flows-menu
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [page index]}]
|
||||
(let [flows (get-in page [:options :flows])
|
||||
(let [flows (dm/get-in page [:options :flows])
|
||||
frames (:frames page)
|
||||
frame (get frames index)
|
||||
current-flow (mf/use-state
|
||||
|
@ -135,7 +164,6 @@
|
|||
[:span.icon i/tick]
|
||||
[:span.label (:name flow)]])]]])))
|
||||
|
||||
|
||||
(mf/defc interactions-menu
|
||||
[]
|
||||
(let [local (mf/deref refs/viewer-local)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue