mirror of
https://github.com/penpot/penpot.git
synced 2025-06-04 03:32:36 +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
|
@ -342,6 +342,13 @@
|
||||||
(some? list)
|
(some? list)
|
||||||
(assoc :list list)))))))
|
(assoc :list list)))))))
|
||||||
|
|
||||||
|
(defn update-options
|
||||||
|
[params]
|
||||||
|
(ptk/reify ::update-options
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :comments-local merge params))))
|
||||||
|
|
||||||
(s/def ::create-draft-params
|
(s/def ::create-draft-params
|
||||||
(s/keys :req-un [::page-id ::file-id ::position]))
|
(s/keys :req-un [::page-id ::file-id ::position]))
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.main.data.viewer
|
(ns app.main.data.viewer
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
|
@ -20,6 +21,9 @@
|
||||||
[cljs.spec.alpha :as s]
|
[cljs.spec.alpha :as s]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
|
(s/def ::nilable-boolean (s/nilable ::us/boolean))
|
||||||
|
(s/def ::nilable-animation (s/nilable ::ctsi/animation))
|
||||||
|
|
||||||
;; --- Local State Initialization
|
;; --- Local State Initialization
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
|
@ -32,7 +36,6 @@
|
||||||
:comments-show :unresolved
|
:comments-show :unresolved
|
||||||
:selected #{}
|
:selected #{}
|
||||||
:collapsed #{}
|
:collapsed #{}
|
||||||
:overlays []
|
|
||||||
:hover nil
|
:hover nil
|
||||||
:share-id ""
|
:share-id ""
|
||||||
:file-comments-users []})
|
:file-comments-users []})
|
||||||
|
@ -329,7 +332,8 @@
|
||||||
|
|
||||||
(declare flash-done)
|
(declare flash-done)
|
||||||
|
|
||||||
(def flash-interactions
|
(defn flash-interactions
|
||||||
|
[]
|
||||||
(ptk/reify ::flash-interactions
|
(ptk/reify ::flash-interactions
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -367,7 +371,7 @@
|
||||||
(ptk/reify ::complete-animation
|
(ptk/reify ::complete-animation
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(d/dissoc-in state [:viewer-local :current-animation]))))
|
(dissoc state :viewer-animation))))
|
||||||
|
|
||||||
;; --- Navigation inside page
|
;; --- Navigation inside page
|
||||||
|
|
||||||
|
@ -376,7 +380,7 @@
|
||||||
(ptk/reify ::go-to-frame-by-index
|
(ptk/reify ::go-to-frame-by-index
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc-in state [:viewer-local :overlays] []))
|
(assoc state :viewer-overlays []))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -391,8 +395,9 @@
|
||||||
(go-to-frame frame-id nil))
|
(go-to-frame frame-id nil))
|
||||||
|
|
||||||
([frame-id animation]
|
([frame-id animation]
|
||||||
(us/verify ::us/uuid frame-id)
|
(us/assert! ::us/uuid frame-id)
|
||||||
(us/verify (s/nilable ::ctsi/animation) animation)
|
(us/assert! ::nilable-animation animation)
|
||||||
|
|
||||||
(ptk/reify ::go-to-frame
|
(ptk/reify ::go-to-frame
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -404,10 +409,10 @@
|
||||||
frame (get frames index)]
|
frame (get frames index)]
|
||||||
(cond-> state
|
(cond-> state
|
||||||
:always
|
:always
|
||||||
(assoc-in [:viewer-local :overlays] [])
|
(assoc :viewer-overlays [])
|
||||||
|
|
||||||
(some? animation)
|
(some? animation)
|
||||||
(assoc-in [:viewer-local :current-animation]
|
(assoc :viewer-animation
|
||||||
{:kind :go-to-frame
|
{:kind :go-to-frame
|
||||||
:orig-frame-id (:id frame)
|
:orig-frame-id (:id frame)
|
||||||
:animation animation}))))
|
:animation animation}))))
|
||||||
|
@ -440,7 +445,7 @@
|
||||||
(ptk/reify ::go-to-section
|
(ptk/reify ::go-to-section
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc-in state [:viewer-local :overlays] []))
|
(assoc state :viewer-overlays []))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -451,50 +456,53 @@
|
||||||
|
|
||||||
;; --- Overlays
|
;; --- Overlays
|
||||||
|
|
||||||
(defn- do-open-overlay
|
(defn- open-overlay*
|
||||||
[state frame position close-click-outside background-overlay animation]
|
[state frame position close-click-outside background-overlay animation]
|
||||||
(cond-> state
|
(cond-> state
|
||||||
:always
|
:always
|
||||||
(update-in [:viewer-local :overlays] conj
|
(update :viewer-overlays conj
|
||||||
{:frame frame
|
{:frame frame
|
||||||
|
:id (:id frame)
|
||||||
:position position
|
:position position
|
||||||
:close-click-outside close-click-outside
|
:close-click-outside close-click-outside
|
||||||
:background-overlay background-overlay})
|
:background-overlay background-overlay})
|
||||||
|
|
||||||
(some? animation)
|
(some? animation)
|
||||||
(assoc-in [:viewer-local :current-animation]
|
(assoc :viewer-animation
|
||||||
{:kind :open-overlay
|
{:kind :open-overlay
|
||||||
:overlay-id (:id frame)
|
:overlay-id (:id frame)
|
||||||
:animation animation})))
|
:animation animation})))
|
||||||
|
|
||||||
(defn- do-close-overlay
|
(defn- close-overlay*
|
||||||
[state frame-id animation]
|
[state frame-id animation]
|
||||||
(if (nil? animation)
|
(if (nil? animation)
|
||||||
(update-in state [:viewer-local :overlays]
|
(update state :viewer-overlays
|
||||||
(fn [overlays]
|
(fn [overlays]
|
||||||
(d/removev #(= (:id (:frame %)) frame-id) overlays)))
|
(d/removev #(= (:id (:frame %)) frame-id) overlays)))
|
||||||
(assoc-in state [:viewer-local :current-animation]
|
(assoc state :viewer-animation
|
||||||
{:kind :close-overlay
|
{:kind :close-overlay
|
||||||
:overlay-id frame-id
|
:overlay-id frame-id
|
||||||
:animation animation})))
|
:animation animation})))
|
||||||
|
|
||||||
(defn open-overlay
|
(defn open-overlay
|
||||||
[frame-id position close-click-outside background-overlay animation]
|
[frame-id position close-click-outside background-overlay animation]
|
||||||
(us/verify ::us/uuid frame-id)
|
(us/assert! ::us/uuid frame-id)
|
||||||
(us/verify ::gpt/point position)
|
(us/assert! ::gpt/point position)
|
||||||
(us/verify (s/nilable ::us/boolean) close-click-outside)
|
(us/assert! ::nilable-boolean close-click-outside)
|
||||||
(us/verify (s/nilable ::us/boolean) background-overlay)
|
(us/assert! ::nilable-boolean background-overlay)
|
||||||
(us/verify (s/nilable ::ctsi/animation) animation)
|
(us/assert! ::nilable-animation animation)
|
||||||
|
|
||||||
(ptk/reify ::open-overlay
|
(ptk/reify ::open-overlay
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [route (:route state)
|
(let [route (:route state)
|
||||||
qparams (:query-params route)
|
qparams (:query-params route)
|
||||||
page-id (:page-id qparams)
|
page-id (:page-id qparams)
|
||||||
frames (get-in state [:viewer :pages page-id :all-frames])
|
frames (dm/get-in state [:viewer :pages page-id :all-frames])
|
||||||
frame (d/seek #(= (:id %) frame-id) frames)
|
frame (d/seek #(= (:id %) frame-id) frames)
|
||||||
overlays (get-in state [:viewer-local :overlays])]
|
overlays (:viewer-overlays state)]
|
||||||
(if-not (some #(= (:frame %) frame) overlays)
|
(if-not (some #(= (:frame %) frame) overlays)
|
||||||
(do-open-overlay state
|
(open-overlay* state
|
||||||
frame
|
frame
|
||||||
position
|
position
|
||||||
close-click-outside
|
close-click-outside
|
||||||
|
@ -502,13 +510,15 @@
|
||||||
animation)
|
animation)
|
||||||
state)))))
|
state)))))
|
||||||
|
|
||||||
|
|
||||||
(defn toggle-overlay
|
(defn toggle-overlay
|
||||||
[frame-id position close-click-outside background-overlay animation]
|
[frame-id position close-click-outside background-overlay animation]
|
||||||
(us/verify ::us/uuid frame-id)
|
(us/assert! ::us/uuid frame-id)
|
||||||
(us/verify ::gpt/point position)
|
(us/assert! ::gpt/point position)
|
||||||
(us/verify (s/nilable ::us/boolean) close-click-outside)
|
(us/assert! ::nilable-boolean close-click-outside)
|
||||||
(us/verify (s/nilable ::us/boolean) background-overlay)
|
(us/assert! ::nilable-boolean background-overlay)
|
||||||
(us/verify (s/nilable ::ctsi/animation) animation)
|
(us/assert! ::nilable-animation animation)
|
||||||
|
|
||||||
(ptk/reify ::toggle-overlay
|
(ptk/reify ::toggle-overlay
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -517,27 +527,28 @@
|
||||||
page-id (:page-id qparams)
|
page-id (:page-id qparams)
|
||||||
frames (get-in state [:viewer :pages page-id :all-frames])
|
frames (get-in state [:viewer :pages page-id :all-frames])
|
||||||
frame (d/seek #(= (:id %) frame-id) frames)
|
frame (d/seek #(= (:id %) frame-id) frames)
|
||||||
overlays (get-in state [:viewer-local :overlays])]
|
overlays (:viewer-overlays state)]
|
||||||
(if-not (some #(= (:frame %) frame) overlays)
|
(if-not (some #(= (:frame %) frame) overlays)
|
||||||
(do-open-overlay state
|
(open-overlay* state
|
||||||
frame
|
frame
|
||||||
position
|
position
|
||||||
close-click-outside
|
close-click-outside
|
||||||
background-overlay
|
background-overlay
|
||||||
animation)
|
animation)
|
||||||
(do-close-overlay state
|
(close-overlay* state
|
||||||
(:id frame)
|
(:id frame)
|
||||||
(ctsi/invert-direction animation)))))))
|
(ctsi/invert-direction animation)))))))
|
||||||
|
|
||||||
(defn close-overlay
|
(defn close-overlay
|
||||||
([frame-id] (close-overlay frame-id nil))
|
([frame-id] (close-overlay frame-id nil))
|
||||||
([frame-id animation]
|
([frame-id animation]
|
||||||
(us/verify ::us/uuid frame-id)
|
(us/assert! ::us/uuid frame-id)
|
||||||
(us/verify (s/nilable ::ctsi/animation) animation)
|
(us/assert! ::nilable-animation animation)
|
||||||
|
|
||||||
(ptk/reify ::close-overlay
|
(ptk/reify ::close-overlay
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(do-close-overlay state
|
(close-overlay* state
|
||||||
frame-id
|
frame-id
|
||||||
animation)))))
|
animation)))))
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
(def current-project-id (mf/create-context nil))
|
(def current-project-id (mf/create-context nil))
|
||||||
(def current-page-id (mf/create-context nil))
|
(def current-page-id (mf/create-context nil))
|
||||||
(def current-file-id (mf/create-context nil))
|
(def current-file-id (mf/create-context nil))
|
||||||
(def scroll-ctx (mf/create-context nil))
|
(def current-scroll (mf/create-context nil))
|
||||||
|
(def current-zoom (mf/create-context nil))
|
||||||
|
|
||||||
(def active-frames-ctx (mf/create-context nil))
|
(def active-frames-ctx (mf/create-context nil))
|
||||||
(def render-thumbnails (mf/create-context nil))
|
(def render-thumbnails (mf/create-context nil))
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.ui.context :as muc]
|
[app.main.ui.context :as muc]
|
||||||
|
[app.main.ui.hooks :as h]
|
||||||
[app.main.ui.shapes.attrs :as attrs]
|
[app.main.ui.shapes.attrs :as attrs]
|
||||||
[app.main.ui.shapes.export :as ed]
|
[app.main.ui.shapes.export :as ed]
|
||||||
[app.main.ui.shapes.fills :as fills]
|
[app.main.ui.shapes.fills :as fills]
|
||||||
|
@ -49,14 +50,15 @@
|
||||||
{::mf/forward-ref true
|
{::mf/forward-ref true
|
||||||
::mf/wrap-props false}
|
::mf/wrap-props false}
|
||||||
[props ref]
|
[props ref]
|
||||||
(let [shape (obj/get props "shape")
|
|
||||||
children (obj/get props "children")
|
(let [shape (unchecked-get props "shape")
|
||||||
pointer-events (obj/get props "pointer-events")
|
children (unchecked-get props "children")
|
||||||
disable-shadows? (obj/get props "disable-shadows?")
|
pointer-events (unchecked-get props "pointer-events")
|
||||||
|
disable-shadows? (unchecked-get props "disable-shadows?")
|
||||||
|
|
||||||
type (:type shape)
|
type (:type shape)
|
||||||
render-id (mf/use-memo #(str (uuid/next)))
|
render-id (h/use-id)
|
||||||
filter-id (str "filter_" render-id)
|
filter-id (dm/str "filter_" render-id)
|
||||||
styles (-> (obj/create)
|
styles (-> (obj/create)
|
||||||
(obj/set! "pointerEvents" pointer-events)
|
(obj/set! "pointerEvents" pointer-events)
|
||||||
(cond-> (and (:blend-mode shape) (not= (:blend-mode shape) :normal))
|
(cond-> (and (:blend-mode shape) (not= (:blend-mode shape) :normal))
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
[app.main.ui.static :as static]
|
[app.main.ui.static :as static]
|
||||||
[app.main.ui.viewer.comments :refer [comments-layer comments-sidebar]]
|
[app.main.ui.viewer.comments :refer [comments-layer comments-sidebar]]
|
||||||
[app.main.ui.viewer.handoff :as handoff]
|
[app.main.ui.viewer.handoff :as handoff]
|
||||||
[app.main.ui.viewer.header :refer [header]]
|
[app.main.ui.viewer.header :as header]
|
||||||
[app.main.ui.viewer.interactions :as interactions]
|
[app.main.ui.viewer.interactions :as interactions]
|
||||||
[app.main.ui.viewer.login]
|
[app.main.ui.viewer.login]
|
||||||
[app.main.ui.viewer.thumbnails :refer [thumbnails-panel]]
|
[app.main.ui.viewer.thumbnails :refer [thumbnails-panel]]
|
||||||
|
@ -36,8 +36,15 @@
|
||||||
[app.util.webapi :as wapi]
|
[app.util.webapi :as wapi]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[goog.events :as events]
|
[goog.events :as events]
|
||||||
|
[okulary.core :as l]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
|
(def current-animation-ref
|
||||||
|
(l/derived :viewer-animation st/state))
|
||||||
|
|
||||||
|
(def current-overlays-ref
|
||||||
|
(l/derived :viewer-overlays st/state))
|
||||||
|
|
||||||
(defn- calculate-size
|
(defn- calculate-size
|
||||||
[objects frame zoom]
|
[objects frame zoom]
|
||||||
(let [{:keys [x y width height]} (gsb/get-object-bounds objects frame)]
|
(let [{:keys [x y width height]} (gsb/get-object-bounds objects frame)]
|
||||||
|
@ -60,7 +67,6 @@
|
||||||
:height (* height zoom)
|
:height (* height zoom)
|
||||||
:vbox (str "0 0 " width " " height)})))
|
:vbox (str "0 0 " width " " height)})))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc viewer-pagination
|
(mf/defc viewer-pagination
|
||||||
[{:keys [index num-frames left-bar right-bar] :as props}]
|
[{:keys [index num-frames left-bar right-bar] :as props}]
|
||||||
[:*
|
[:*
|
||||||
|
@ -75,23 +81,83 @@
|
||||||
[:div.counter (str/join " / " [(+ index 1) num-frames])]
|
[:div.counter (str/join " / " [(+ index 1) num-frames])]
|
||||||
[:span]]])
|
[:span]]])
|
||||||
|
|
||||||
|
(mf/defc viewer-pagination-and-sidebar
|
||||||
|
{::mf/wrap [mf/memo]}
|
||||||
|
[{:keys [section index frames users frame page]}]
|
||||||
|
(let [comments-local (mf/deref refs/comments-local)
|
||||||
|
show-sidebar? (and (= section :comments) (:show-sidebar? comments-local))]
|
||||||
|
[:*
|
||||||
|
[:& viewer-pagination
|
||||||
|
{:index index
|
||||||
|
:num-frames (count (:frames page))
|
||||||
|
:right-bar show-sidebar?}]
|
||||||
|
|
||||||
|
(when show-sidebar?
|
||||||
|
[:& comments-sidebar
|
||||||
|
{:users users
|
||||||
|
:frame frame
|
||||||
|
:page page}])]))
|
||||||
|
|
||||||
|
(mf/defc viewer-overlay
|
||||||
|
[{:keys [overlay file page frame zoom wrapper-size close-overlay interactions-mode]}]
|
||||||
|
(let [close-click-outside? (:close-click-outside overlay)
|
||||||
|
background-overlay? (:background-overlay overlay)
|
||||||
|
overlay-frame (:frame overlay)
|
||||||
|
overlay-position (:position overlay)
|
||||||
|
|
||||||
|
size
|
||||||
|
(mf/with-memo [page overlay zoom]
|
||||||
|
(calculate-size (:objects page) (:frame overlay) zoom))
|
||||||
|
|
||||||
|
on-click
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps overlay close-overlay close-click-outside?)
|
||||||
|
(fn [_]
|
||||||
|
(when close-click-outside?
|
||||||
|
(close-overlay (:frame overlay)))))]
|
||||||
|
|
||||||
|
[:*
|
||||||
|
(when (or close-click-outside? background-overlay?)
|
||||||
|
[:div.viewer-overlay-background
|
||||||
|
{:class (dom/classnames :visible background-overlay?)
|
||||||
|
:style {:width (:width wrapper-size)
|
||||||
|
:height (:height wrapper-size)
|
||||||
|
:position "absolute"
|
||||||
|
:left 0
|
||||||
|
:top 0}
|
||||||
|
:on-click on-click}])
|
||||||
|
|
||||||
|
[:div.viewport-container.viewer-overlay
|
||||||
|
{:id (dm/str "overlay-" (:id overlay-frame))
|
||||||
|
:style {:width (:width size)
|
||||||
|
:height (:height size)
|
||||||
|
:left (* (:x overlay-position) zoom)
|
||||||
|
:top (* (:y overlay-position) zoom)}}
|
||||||
|
|
||||||
|
[:& interactions/viewport
|
||||||
|
{:frame overlay-frame
|
||||||
|
:base-frame frame
|
||||||
|
:frame-offset overlay-position
|
||||||
|
:size size
|
||||||
|
:page page
|
||||||
|
:interactions-mode interactions-mode}]]]))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc viewer-wrapper
|
(mf/defc viewer-wrapper
|
||||||
[{:keys [wrapper-size scroll orig-frame orig-viewport-ref orig-size page file users current-viewport-ref
|
[{:keys [wrapper-size scroll orig-frame orig-viewport-ref orig-size page file users current-viewport-ref
|
||||||
size frame interactions-mode overlays zoom close-overlay section index] :as props}]
|
size frame interactions-mode overlays zoom close-overlay section index] :as props}]
|
||||||
(let [{clist :list} (mf/deref refs/comments-local)
|
|
||||||
show-comments-list (and (= section :comments) (= :show clist))]
|
|
||||||
[:*
|
[:*
|
||||||
[:& viewer-pagination {:index index :num-frames (count (:frames page)) :right-bar show-comments-list}]
|
[:& viewer-pagination-and-sidebar
|
||||||
|
{:section section
|
||||||
(when show-comments-list
|
:index index
|
||||||
[:& comments-sidebar {:users users :frame frame :page page}])
|
:page page
|
||||||
|
:users users
|
||||||
|
:frame frame}]
|
||||||
|
|
||||||
[:div.viewer-wrapper
|
[:div.viewer-wrapper
|
||||||
{:style {:width (:width wrapper-size)
|
{:style {:width (:width wrapper-size)
|
||||||
:height (:height wrapper-size)}}
|
:height (:height wrapper-size)}}
|
||||||
[:& (mf/provider ctx/scroll-ctx) {:value @scroll}
|
|
||||||
[:div.viewer-clipper
|
[:div.viewer-clipper
|
||||||
[:*
|
|
||||||
(when orig-frame
|
(when orig-frame
|
||||||
[:div.viewport-container
|
[:div.viewport-container
|
||||||
{:ref orig-viewport-ref
|
{:ref orig-viewport-ref
|
||||||
|
@ -121,48 +187,28 @@
|
||||||
:frame-offset (gpt/point 0 0)
|
:frame-offset (gpt/point 0 0)
|
||||||
:size size
|
:size size
|
||||||
:page page
|
:page page
|
||||||
:file file
|
|
||||||
:users users
|
|
||||||
:interactions-mode interactions-mode}]
|
:interactions-mode interactions-mode}]
|
||||||
|
|
||||||
(for [overlay overlays]
|
(for [overlay overlays]
|
||||||
(let [size-over (calculate-size (:objects page) (:frame overlay) zoom)]
|
[:& viewer-overlay {:overlay overlay
|
||||||
[:*
|
|
||||||
(when (or (:close-click-outside overlay)
|
|
||||||
(:background-overlay overlay))
|
|
||||||
[:div.viewer-overlay-background
|
|
||||||
{:class (dom/classnames
|
|
||||||
:visible (:background-overlay overlay))
|
|
||||||
:style {:width (:width wrapper-size)
|
|
||||||
:height (:height wrapper-size)
|
|
||||||
:position "absolute"
|
|
||||||
:left 0
|
|
||||||
:top 0}
|
|
||||||
:on-click #(when (:close-click-outside overlay)
|
|
||||||
(close-overlay (:frame overlay)))}])
|
|
||||||
[:div.viewport-container.viewer-overlay
|
|
||||||
|
|
||||||
{:id (str "overlay-" (-> overlay :frame :id))
|
|
||||||
:style {:width (:width size-over)
|
|
||||||
:height (:height size-over)
|
|
||||||
:left (* (:x (:position overlay)) zoom)
|
|
||||||
:top (* (:y (:position overlay)) zoom)}}
|
|
||||||
[:& interactions/viewport
|
|
||||||
{:frame (:frame overlay)
|
|
||||||
:base-frame frame
|
|
||||||
:frame-offset (:position overlay)
|
|
||||||
:size size-over
|
|
||||||
:page page
|
|
||||||
:file file
|
:file file
|
||||||
:users users
|
:key (dm/str (:id overlay))
|
||||||
:interactions-mode interactions-mode}]]]))]]
|
:page page
|
||||||
|
:frame frame
|
||||||
|
:zoom zoom
|
||||||
|
:wrapper-size wrapper-size
|
||||||
|
:close-overlay close-overlay
|
||||||
|
:interactions-mode interactions-mode}])
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
(when (= section :comments)
|
(when (= section :comments)
|
||||||
[:& comments-layer {:file file
|
[:& comments-layer {:file file
|
||||||
:users users
|
:users users
|
||||||
:frame frame
|
:frame frame
|
||||||
:page page
|
:page page
|
||||||
:zoom zoom}])]]]]))
|
:zoom zoom}])]])
|
||||||
|
|
||||||
(mf/defc viewer
|
(mf/defc viewer
|
||||||
[{:keys [params data]}]
|
[{:keys [params data]}]
|
||||||
|
@ -187,7 +233,8 @@
|
||||||
orig-viewport-ref (mf/use-ref nil)
|
orig-viewport-ref (mf/use-ref nil)
|
||||||
current-viewport-ref (mf/use-ref nil)
|
current-viewport-ref (mf/use-ref nil)
|
||||||
viewer-section-ref (mf/use-ref nil)
|
viewer-section-ref (mf/use-ref nil)
|
||||||
current-animation (:current-animation local)
|
|
||||||
|
current-animation (mf/deref current-animation-ref)
|
||||||
|
|
||||||
page-id (or page-id (-> file :data :pages first))
|
page-id (or page-id (-> file :data :pages first))
|
||||||
|
|
||||||
|
@ -206,47 +253,49 @@
|
||||||
frames (:frames page)
|
frames (:frames page)
|
||||||
frame (get frames index)
|
frame (get frames index)
|
||||||
|
|
||||||
fullscreen? (mf/deref refs/viewer-fullscreen?)
|
fullscreen? (mf/deref header/fullscreen-ref)
|
||||||
overlays (:overlays local)
|
overlays (:overlays local)
|
||||||
|
overlays (mf/deref current-overlays-ref)
|
||||||
scroll (mf/use-state nil)
|
scroll (mf/use-state nil)
|
||||||
|
|
||||||
orig-frame
|
orig-frame
|
||||||
(when (:orig-frame-id current-animation)
|
(when (:orig-frame-id current-animation)
|
||||||
(d/seek #(= (:id %) (:orig-frame-id current-animation)) frames))
|
(d/seek #(= (:id %) (:orig-frame-id current-animation)) frames))
|
||||||
|
|
||||||
size (mf/use-memo
|
size
|
||||||
(mf/deps frame zoom)
|
(mf/with-memo [frame zoom]
|
||||||
(fn [] (calculate-size (:objects page) frame zoom)))
|
(calculate-size (:objects page) frame zoom))
|
||||||
|
|
||||||
orig-size (mf/use-memo
|
orig-size
|
||||||
(mf/deps orig-frame zoom)
|
(mf/with-memo [orig-frame zoom]
|
||||||
(fn [] (when orig-frame
|
(when orig-frame
|
||||||
(calculate-size (:objects page) orig-frame zoom))))
|
(calculate-size (:objects page) orig-frame zoom)))
|
||||||
|
|
||||||
wrapper-size (mf/use-memo
|
wrapper-size
|
||||||
(mf/deps size orig-size zoom)
|
(mf/with-memo [size orig-size zoom]
|
||||||
(fn [] (calculate-wrapper size orig-size zoom)))
|
(calculate-wrapper size orig-size zoom))
|
||||||
|
|
||||||
interactions-mode
|
interactions-mode
|
||||||
(:interactions-mode local)
|
(:interactions-mode local)
|
||||||
|
|
||||||
on-click
|
on-click
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(mf/deps section)
|
(mf/deps section)
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(when (= section :comments)
|
(when (= section :comments)
|
||||||
(st/emit! (dcm/close-thread)))))
|
(st/emit! (dcm/close-thread)))))
|
||||||
|
|
||||||
set-up-new-size
|
set-up-new-size
|
||||||
(mf/use-callback
|
(mf/use-fn
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [viewer-section (dom/get-element "viewer-section")
|
(let [viewer-section (dom/get-element "viewer-section")
|
||||||
size (dom/get-client-size viewer-section)]
|
size (dom/get-client-size viewer-section)]
|
||||||
(st/emit! (dv/set-viewport-size {:size size})))))
|
(st/emit! (dv/set-viewport-size {:size size})))))
|
||||||
|
|
||||||
on-scroll
|
on-scroll
|
||||||
|
(mf/use-fn
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(reset! scroll (dom/get-target-scroll event)))]
|
(reset! scroll (dom/get-target-scroll event))))]
|
||||||
|
|
||||||
(hooks/use-shortcuts ::viewer sc/shortcuts)
|
(hooks/use-shortcuts ::viewer sc/shortcuts)
|
||||||
|
|
||||||
|
@ -264,14 +313,13 @@
|
||||||
(let [name (:name file)]
|
(let [name (:name file)]
|
||||||
(dom/set-html-title (str "\u25b6 " (tr "title.viewer" name))))))
|
(dom/set-html-title (str "\u25b6 " (tr "title.viewer" name))))))
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/with-effect []
|
||||||
(fn []
|
|
||||||
(dom/set-html-theme-color clr/gray-50 "dark")
|
(dom/set-html-theme-color clr/gray-50 "dark")
|
||||||
(let [key1 (events/listen js/window "click" on-click)
|
(let [key1 (events/listen js/window "click" on-click)
|
||||||
key2 (events/listen (mf/ref-val viewer-section-ref) "scroll" on-scroll)]
|
key2 (events/listen (mf/ref-val viewer-section-ref) "scroll" on-scroll)]
|
||||||
(fn []
|
(fn []
|
||||||
(events/unlistenByKey key1)
|
(events/unlistenByKey key1)
|
||||||
(events/unlistenByKey key2)))))
|
(events/unlistenByKey key2))))
|
||||||
|
|
||||||
(mf/use-layout-effect
|
(mf/use-layout-effect
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -362,13 +410,15 @@
|
||||||
fonts (into #{} (keep :font-id) text-nodes)]
|
fonts (into #{} (keep :font-id) text-nodes)]
|
||||||
(run! fonts/ensure-loaded! fonts))))
|
(run! fonts/ensure-loaded! fonts))))
|
||||||
|
|
||||||
[:div#viewer-layout {:class (dom/classnames
|
[:div#viewer-layout
|
||||||
|
{:class (dom/classnames
|
||||||
:force-visible (:show-thumbnails local)
|
:force-visible (:show-thumbnails local)
|
||||||
:viewer-layout (not= section :handoff)
|
:viewer-layout (not= section :handoff)
|
||||||
:handoff-layout (= section :handoff)
|
:handoff-layout (= section :handoff)
|
||||||
:fullscreen fullscreen?)}
|
:fullscreen fullscreen?)}
|
||||||
|
|
||||||
[:& header {:project project
|
[:& header/header
|
||||||
|
{:project project
|
||||||
:index index
|
:index index
|
||||||
:file file
|
:file file
|
||||||
:page page
|
:page page
|
||||||
|
@ -410,9 +460,11 @@
|
||||||
:index index
|
:index index
|
||||||
:viewer-pagination viewer-pagination}]
|
:viewer-pagination viewer-pagination}]
|
||||||
|
|
||||||
|
[:& (mf/provider ctx/current-scroll) {:value @scroll}
|
||||||
|
[:& (mf/provider ctx/current-zoom) {:value zoom}
|
||||||
[:& viewer-wrapper
|
[:& viewer-wrapper
|
||||||
{:wrapper-size wrapper-size
|
{:wrapper-size wrapper-size
|
||||||
:scroll scroll
|
:scroll @scroll
|
||||||
:orig-frame orig-frame
|
:orig-frame orig-frame
|
||||||
:orig-viewport-ref orig-viewport-ref
|
:orig-viewport-ref orig-viewport-ref
|
||||||
:orig-size orig-size
|
:orig-size orig-size
|
||||||
|
@ -426,7 +478,7 @@
|
||||||
:overlays overlays
|
:overlays overlays
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:section section
|
:section section
|
||||||
:index index}]))]]]))
|
:index index}]]]))]]]))
|
||||||
|
|
||||||
;; --- Component: Viewer Page
|
;; --- Component: Viewer Page
|
||||||
|
|
||||||
|
|
|
@ -188,8 +188,7 @@
|
||||||
|
|
||||||
(mf/defc render-frame-svg
|
(mf/defc render-frame-svg
|
||||||
[{:keys [page frame local size]}]
|
[{:keys [page frame local size]}]
|
||||||
(let [objects (mf/use-memo
|
(let [objects (mf/with-memo [page frame size]
|
||||||
(mf/deps page frame)
|
|
||||||
(prepare-objects page frame size))
|
(prepare-objects page frame size))
|
||||||
|
|
||||||
;; Retrieve frame again with correct modifier
|
;; Retrieve frame again with correct modifier
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
(ns app.main.ui.viewer.header
|
(ns app.main.ui.viewer.header
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.modal :as modal]
|
[app.main.data.modal :as modal]
|
||||||
[app.main.data.viewer :as dv]
|
[app.main.data.viewer :as dv]
|
||||||
[app.main.data.viewer.shortcuts :as sc]
|
[app.main.data.viewer.shortcuts :as sc]
|
||||||
|
@ -19,8 +20,14 @@
|
||||||
[app.main.ui.viewer.interactions :refer [flows-menu interactions-menu]]
|
[app.main.ui.viewer.interactions :refer [flows-menu interactions-menu]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
|
[okulary.core :as l]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
|
(def fullscreen-ref
|
||||||
|
(l/derived (fn [state]
|
||||||
|
(dm/get-in state [:viewer-local :fullscreen?]))
|
||||||
|
st/state))
|
||||||
|
|
||||||
(defn open-login-dialog
|
(defn open-login-dialog
|
||||||
[]
|
[]
|
||||||
(modal/show! :login-register {}))
|
(modal/show! :login-register {}))
|
||||||
|
@ -65,7 +72,7 @@
|
||||||
|
|
||||||
(mf/defc header-options
|
(mf/defc header-options
|
||||||
[{:keys [section zoom page file index permissions]}]
|
[{:keys [section zoom page file index permissions]}]
|
||||||
(let [fullscreen? (mf/deref refs/viewer-fullscreen?)
|
(let [fullscreen? (mf/deref fullscreen-ref)
|
||||||
|
|
||||||
toggle-fullscreen
|
toggle-fullscreen
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
|
|
@ -18,16 +18,17 @@
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
|
[app.main.ui.hooks :as h]
|
||||||
[app.main.ui.viewer.shapes :as shapes]
|
[app.main.ui.viewer.shapes :as shapes]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
|
[app.util.object :as obj]
|
||||||
[goog.events :as events]
|
[goog.events :as events]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
(defn prepare-objects
|
(defn prepare-objects
|
||||||
[page frame size]
|
[page frame size]
|
||||||
(fn []
|
|
||||||
(let [objects (:objects page)
|
(let [objects (:objects page)
|
||||||
frame-id (:id frame)
|
frame-id (:id frame)
|
||||||
modifier (-> (gpt/point (:x size) (:y size))
|
modifier (-> (gpt/point (:x size) (:y size))
|
||||||
|
@ -38,34 +39,71 @@
|
||||||
|
|
||||||
(->> (cph/get-children-ids objects frame-id)
|
(->> (cph/get-children-ids objects frame-id)
|
||||||
(into [frame-id])
|
(into [frame-id])
|
||||||
(reduce update-fn objects)))))
|
(reduce update-fn objects))))
|
||||||
|
|
||||||
(mf/defc viewport
|
(mf/defc viewport-svg
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]
|
||||||
[{:keys [page interactions-mode frame base-frame frame-offset size]}]
|
::mf/wrap-props false}
|
||||||
(let [objects (mf/use-memo
|
[props]
|
||||||
(mf/deps page frame size)
|
(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")
|
||||||
|
|
||||||
|
vbox (:vbox size)
|
||||||
|
|
||||||
|
objects (mf/with-memo [page frame size]
|
||||||
(prepare-objects page frame size))
|
(prepare-objects page frame size))
|
||||||
|
|
||||||
wrapper (mf/use-memo
|
wrapper (mf/with-memo [objects]
|
||||||
(mf/deps objects)
|
(shapes/frame-container-factory objects))
|
||||||
#(shapes/frame-container-factory objects))
|
|
||||||
|
|
||||||
;; Retrieve frames again with correct modifier
|
;; Retrieve frames again with correct modifier
|
||||||
frame (get objects (:id frame))
|
frame (get objects (:id frame))
|
||||||
base-frame (get objects (:id base-frame))
|
base (get objects (:id base))]
|
||||||
|
|
||||||
on-click
|
[:& (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}]]]]))
|
||||||
|
|
||||||
|
(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 [_]
|
(fn [_]
|
||||||
(when (= interactions-mode :show-on-click)
|
(when (= mode :show-on-click)
|
||||||
(st/emit! dv/flash-interactions)))
|
(st/emit! (dv/flash-interactions))))
|
||||||
|
|
||||||
on-mouse-wheel
|
on-mouse-wheel
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (kbd/mod? event)
|
(when (kbd/mod? event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(let [event (.getBrowserEvent ^js event)
|
(let [event (dom/event->browser-event event)
|
||||||
delta (+ (.-deltaY ^js event) (.-deltaX ^js event))]
|
delta (+ (.-deltaY ^js event)
|
||||||
|
(.-deltaX ^js event))]
|
||||||
(if (pos? delta)
|
(if (pos? delta)
|
||||||
(st/emit! dv/decrease-zoom)
|
(st/emit! dv/decrease-zoom)
|
||||||
(st/emit! dv/increase-zoom)))))
|
(st/emit! dv/increase-zoom)))))
|
||||||
|
@ -73,38 +111,29 @@
|
||||||
on-key-down
|
on-key-down
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when (kbd/esc? event)
|
(when (kbd/esc? event)
|
||||||
(st/emit! (dcm/close-thread))))]
|
(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
|
;; bind with passive=false to allow the event to be cancelled
|
||||||
;; https://stackoverflow.com/a/57582286/3219895
|
;; https://stackoverflow.com/a/57582286/3219895
|
||||||
(let [key1 (events/listen goog/global "wheel" on-mouse-wheel #js {"passive" false})
|
key1 (events/listen goog/global "wheel" on-mouse-wheel #js {"passive" false})
|
||||||
key2 (events/listen js/window "keydown" on-key-down)
|
key2 (events/listen goog/global "keydown" on-key-down)
|
||||||
key3 (events/listen js/window "click" on-click)]
|
key3 (events/listen goog/global "click" on-click)]
|
||||||
(fn []
|
(fn []
|
||||||
(events/unlistenByKey key1)
|
(events/unlistenByKey key1)
|
||||||
(events/unlistenByKey key2)
|
(events/unlistenByKey key2)
|
||||||
(events/unlistenByKey key3)))))
|
(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)
|
|
||||||
: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)}]]]]))
|
|
||||||
|
|
||||||
|
[:& viewport-svg {:page page
|
||||||
|
:frame frame
|
||||||
|
:base base
|
||||||
|
:offset offset
|
||||||
|
:size size}]))
|
||||||
|
|
||||||
(mf/defc flows-menu
|
(mf/defc flows-menu
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [page index]}]
|
[{:keys [page index]}]
|
||||||
(let [flows (get-in page [:options :flows])
|
(let [flows (dm/get-in page [:options :flows])
|
||||||
frames (:frames page)
|
frames (:frames page)
|
||||||
frame (get frames index)
|
frame (get frames index)
|
||||||
current-flow (mf/use-state
|
current-flow (mf/use-state
|
||||||
|
@ -135,7 +164,6 @@
|
||||||
[:span.icon i/tick]
|
[:span.icon i/tick]
|
||||||
[:span.label (:name flow)]])]]])))
|
[:span.label (:name flow)]])]]])))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc interactions-menu
|
(mf/defc interactions-menu
|
||||||
[]
|
[]
|
||||||
(let [local (mf/deref refs/viewer-local)
|
(let [local (mf/deref refs/viewer-local)
|
||||||
|
|
|
@ -206,6 +206,9 @@
|
||||||
:style {:pointer-events (when frame? "none")}
|
:style {:pointer-events (when frame? "none")}
|
||||||
:transform (gsh/transform-str shape)}])))
|
:transform (gsh/transform-str shape)}])))
|
||||||
|
|
||||||
|
|
||||||
|
;; TODO: use-memo use-fn
|
||||||
|
|
||||||
(defn generic-wrapper-factory
|
(defn generic-wrapper-factory
|
||||||
"Wrap some svg shape and add interaction controls"
|
"Wrap some svg shape and add interaction controls"
|
||||||
[component]
|
[component]
|
||||||
|
@ -226,20 +229,37 @@
|
||||||
interactions (:interactions shape)
|
interactions (:interactions shape)
|
||||||
|
|
||||||
svg-element? (and (= :svg-raw (:type shape))
|
svg-element? (and (= :svg-raw (:type shape))
|
||||||
(not= :svg (get-in shape [:content :tag])))]
|
(not= :svg (get-in shape [:content :tag])))
|
||||||
|
|
||||||
(mf/use-effect
|
|
||||||
(fn []
|
on-mouse-down
|
||||||
|
(mf/use-fn (mf/deps shape base-frame frame-offset objects)
|
||||||
|
#(on-mouse-down % shape base-frame frame-offset objects))
|
||||||
|
|
||||||
|
on-mouse-up
|
||||||
|
(mf/use-fn (mf/deps shape base-frame frame-offset objects)
|
||||||
|
#(on-mouse-up % shape base-frame frame-offset objects))
|
||||||
|
|
||||||
|
on-mouse-enter
|
||||||
|
(mf/use-fn (mf/deps shape base-frame frame-offset objects)
|
||||||
|
#(on-mouse-enter % shape base-frame frame-offset objects))
|
||||||
|
|
||||||
|
on-mouse-leave
|
||||||
|
(mf/use-fn (mf/deps shape base-frame frame-offset objects)
|
||||||
|
#(on-mouse-leave % shape base-frame frame-offset objects))]
|
||||||
|
|
||||||
|
|
||||||
|
(mf/with-effect []
|
||||||
(let [sems (on-load shape base-frame frame-offset objects)]
|
(let [sems (on-load shape base-frame frame-offset objects)]
|
||||||
#(run! tm/dispose! sems))))
|
(partial run! tm/dispose! sems)))
|
||||||
|
|
||||||
(if-not svg-element?
|
(if-not svg-element?
|
||||||
[:> shape-container {:shape shape
|
[:> shape-container {:shape shape
|
||||||
:cursor (when (ctsi/actionable? interactions) "pointer")
|
:cursor (when (ctsi/actionable? interactions) "pointer")
|
||||||
:on-mouse-down #(on-mouse-down % shape base-frame frame-offset objects)
|
:on-mouse-down on-mouse-down
|
||||||
:on-mouse-up #(on-mouse-up % shape base-frame frame-offset objects)
|
:on-mouse-up on-mouse-up
|
||||||
:on-mouse-enter #(on-mouse-enter % shape base-frame frame-offset objects)
|
:on-mouse-enter on-mouse-enter
|
||||||
:on-mouse-leave #(on-mouse-leave % shape base-frame frame-offset objects)}
|
:on-mouse-leave on-mouse-leave}
|
||||||
|
|
||||||
[:& component {:shape shape
|
[:& component {:shape shape
|
||||||
:frame frame
|
:frame frame
|
||||||
|
@ -311,6 +331,7 @@
|
||||||
#js {:shape shape
|
#js {:shape shape
|
||||||
:childs childs
|
:childs childs
|
||||||
:objects objects})]
|
:objects objects})]
|
||||||
|
|
||||||
[:> frame-wrapper props]))))
|
[:> frame-wrapper props]))))
|
||||||
|
|
||||||
(defn group-container-factory
|
(defn group-container-factory
|
||||||
|
|
|
@ -37,6 +37,14 @@
|
||||||
(when (some? e)
|
(when (some? e)
|
||||||
(.-target e)))
|
(.-target e)))
|
||||||
|
|
||||||
|
(defn event->native-event
|
||||||
|
[^js e]
|
||||||
|
(.-nativeEvent e))
|
||||||
|
|
||||||
|
(defn event->browser-event
|
||||||
|
[^js e]
|
||||||
|
(.getBrowserEvent e))
|
||||||
|
|
||||||
;; --- New methods
|
;; --- New methods
|
||||||
|
|
||||||
(declare get-elements-by-tag)
|
(declare get-elements-by-tag)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue