mirror of
https://github.com/penpot/penpot.git
synced 2025-03-18 18:51:29 -05:00
⚡ Add performance oriented refactor for keyboard streams
This commit is contained in:
parent
9bb2c79ef8
commit
b6ef21e121
5 changed files with 135 additions and 129 deletions
|
@ -33,6 +33,7 @@
|
|||
[app.main.snap :as snap]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
|
@ -673,7 +674,8 @@
|
|||
(rx/switch-map #(rx/merge
|
||||
(rx/timer 1000)
|
||||
(->> stream
|
||||
(rx/filter ms/key-up?)
|
||||
(rx/filter kbd/keyboard-event?)
|
||||
(rx/filter kbd/key-up-event?)
|
||||
(rx/delay 250))))
|
||||
(rx/take 1))
|
||||
|
||||
|
|
|
@ -15,23 +15,9 @@
|
|||
|
||||
;; --- User Events
|
||||
|
||||
(defrecord KeyboardEvent [type key shift ctrl alt meta editing event])
|
||||
|
||||
(defn keyboard-event?
|
||||
[v]
|
||||
(instance? KeyboardEvent v))
|
||||
|
||||
(defn key-up?
|
||||
[v]
|
||||
(and (keyboard-event? v)
|
||||
(= :up (:type v))))
|
||||
|
||||
(defn key-down?
|
||||
[v]
|
||||
(and (keyboard-event? v)
|
||||
(= :down (:type v))))
|
||||
|
||||
(defrecord MouseEvent [type ctrl shift alt meta])
|
||||
(defrecord PointerEvent [source pt ctrl shift alt meta])
|
||||
(defrecord ScrollEvent [point])
|
||||
|
||||
(defn mouse-event?
|
||||
[v]
|
||||
|
@ -57,21 +43,17 @@
|
|||
(and (mouse-event? v)
|
||||
(= :double-click (:type v))))
|
||||
|
||||
(defrecord PointerEvent [source pt ctrl shift alt meta])
|
||||
|
||||
(defn pointer-event?
|
||||
[v]
|
||||
(instance? PointerEvent v))
|
||||
|
||||
(defrecord ScrollEvent [point])
|
||||
|
||||
(defn scroll-event?
|
||||
[v]
|
||||
(instance? ScrollEvent v))
|
||||
|
||||
(defn interaction-event?
|
||||
[event]
|
||||
(or (keyboard-event? event)
|
||||
(or (kbd/keyboard-event? event)
|
||||
(mouse-event? event)))
|
||||
|
||||
;; --- Derived streams
|
||||
|
@ -126,55 +108,54 @@
|
|||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
||||
|
||||
(defonce window-blur
|
||||
(defonce ^:private window-blur
|
||||
(->> (rx/from-event globals/window "blur")
|
||||
(rx/map (constantly false))
|
||||
(rx/share)))
|
||||
|
||||
(defonce keyboard
|
||||
(->> st/stream
|
||||
(rx/filter kbd/keyboard-event?)
|
||||
(rx/share)))
|
||||
|
||||
(defonce keyboard-alt
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> (rx/merge
|
||||
(->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
(rx/filter kbd/alt-key?)
|
||||
(rx/map #(= :down (:type %))))
|
||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
||||
;; that makes keyboard-alt stream registering the key pressed but
|
||||
;; on blurring the window (unfocus) the key down is never arrived.
|
||||
(->> window-blur
|
||||
(rx/map (constantly false))))
|
||||
ob (->> keyboard
|
||||
(rx/filter kbd/alt-key?)
|
||||
(rx/map kbd/key-down-event?)
|
||||
;; Fix a situation caused by using `ctrl+alt` kind of
|
||||
;; shortcuts, that makes keyboard-alt stream
|
||||
;; registering the key pressed but on blurring the
|
||||
;; window (unfocus) the key down is never arrived.
|
||||
(rx/merge window-blur)
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-ctrl
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> (rx/merge
|
||||
(->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
(rx/filter kbd/ctrl-key?)
|
||||
(rx/map #(= :down (:type %))))
|
||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
||||
;; that makes keyboard-alt stream registering the key pressed but
|
||||
;; on blurring the window (unfocus) the key down is never arrived.
|
||||
(->> window-blur
|
||||
(rx/map (constantly false))))
|
||||
ob (->> keyboard
|
||||
(rx/filter kbd/ctrl-key?)
|
||||
(rx/map kbd/key-down-event?)
|
||||
;; Fix a situation caused by using `ctrl+alt` kind of
|
||||
;; shortcuts, that makes keyboard-alt stream
|
||||
;; registering the key pressed but on blurring the
|
||||
;; window (unfocus) the key down is never arrived.
|
||||
(rx/merge window-blur)
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-meta
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> (rx/merge
|
||||
(->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
(rx/filter kbd/meta-key?)
|
||||
(rx/map #(= :down (:type %))))
|
||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
||||
;; that makes keyboard-alt stream registering the key pressed but
|
||||
;; on blurring the window (unfocus) the key down is never arrived.
|
||||
(->> window-blur
|
||||
(rx/map (constantly false))))
|
||||
ob (->> keyboard
|
||||
(rx/filter kbd/meta-key?)
|
||||
(rx/map kbd/key-down-event?)
|
||||
;; Fix a situation caused by using `ctrl+alt` kind of
|
||||
;; shortcuts, that makes keyboard-alt stream
|
||||
;; registering the key pressed but on blurring the
|
||||
;; window (unfocus) the key down is never arrived.
|
||||
(rx/merge window-blur)
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
@ -184,57 +165,12 @@
|
|||
keyboard-meta
|
||||
keyboard-ctrl))
|
||||
|
||||
(defonce keyboard-minus-or-underscore
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
(rx/filter key-down?)
|
||||
(rx/filter #(kbd/mod? (:event %)))
|
||||
(rx/filter #(or (kbd/minus? %) (kbd/underscore? %)))
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-=-or-+
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
(rx/filter key-down?)
|
||||
(rx/filter #(kbd/mod? (:event %)))
|
||||
(rx/filter #(or (kbd/equals? %) (kbd/plus? %)))
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-space
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
ob (->> keyboard
|
||||
(rx/filter kbd/space?)
|
||||
(rx/filter (comp not kbd/editing?))
|
||||
(rx/map #(= :down (:type %)))
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-z
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
(rx/filter kbd/z?)
|
||||
(rx/filter (comp not kbd/editing?))
|
||||
(rx/map #(= :down (:type %)))
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-shift
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> st/stream
|
||||
(rx/filter keyboard-event?)
|
||||
(rx/filter kbd/shift-key?)
|
||||
(rx/filter (comp not kbd/editing?))
|
||||
(rx/map #(= :down (:type %)))
|
||||
(rx/filter (complement kbd/editing-event?))
|
||||
(rx/map kbd/key-down-event?)
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob sub)
|
||||
sub))
|
||||
|
|
|
@ -314,29 +314,33 @@
|
|||
shift? (kbd/shift? event)
|
||||
alt? (kbd/alt? event)
|
||||
meta? (kbd/meta? event)
|
||||
mod? (kbd/mod? event)
|
||||
target (dom/get-target event)
|
||||
|
||||
editing? (or (some? (.closest ^js target ".public-DraftEditor-content"))
|
||||
(= "rich-text" (obj/get target "className"))
|
||||
(= "INPUT" (obj/get target "tagName"))
|
||||
(= "TEXTAREA" (obj/get target "tagName")))]
|
||||
|
||||
(when-not (.-repeat bevent)
|
||||
(st/emit! (ms/->KeyboardEvent :down key shift? ctrl? alt? meta? editing? event)))))))
|
||||
(st/emit! (kbd/->KeyboardEvent :down key shift? ctrl? alt? meta? mod? editing? event)))))))
|
||||
|
||||
(defn on-key-up []
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(let [key (.-key event)
|
||||
ctrl? (kbd/ctrl? event)
|
||||
shift? (kbd/shift? event)
|
||||
alt? (kbd/alt? event)
|
||||
meta? (kbd/meta? event)
|
||||
(let [key (.-key event)
|
||||
ctrl? (kbd/ctrl? event)
|
||||
shift? (kbd/shift? event)
|
||||
alt? (kbd/alt? event)
|
||||
meta? (kbd/meta? event)
|
||||
mod? (kbd/mod? event)
|
||||
target (dom/get-target event)
|
||||
|
||||
editing? (or (some? (.closest ^js target ".public-DraftEditor-content"))
|
||||
(= "rich-text" (obj/get target "className"))
|
||||
(= "INPUT" (obj/get target "tagName"))
|
||||
(= "TEXTAREA" (obj/get target "tagName")))]
|
||||
(st/emit! (ms/->KeyboardEvent :up key shift? ctrl? alt? meta? editing? event))))))
|
||||
(st/emit! (kbd/->KeyboardEvent :up key shift? ctrl? alt? meta? mod? editing? event))))))
|
||||
|
||||
(defn on-pointer-move [move-stream]
|
||||
(let [last-position (mf/use-var nil)]
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
[app.util.debug :as dbg]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.globals :as globals]
|
||||
[app.util.keyboard :as kbd]
|
||||
[beicon.core :as rx]
|
||||
[goog.events :as events]
|
||||
[rumext.v2 :as mf])
|
||||
|
@ -99,20 +100,57 @@
|
|||
(when (not= @cursor new-cursor)
|
||||
(reset! cursor new-cursor))))))
|
||||
|
||||
(defn setup-keyboard [alt? mod? space? z? shift?]
|
||||
(hooks/use-stream ms/keyboard-alt #(reset! alt? %))
|
||||
(hooks/use-stream ms/keyboard-mod #(do
|
||||
(reset! mod? %)
|
||||
(when-not % (reset! z? false)))) ;; In mac after command+z there is no event for the release of the z key
|
||||
(hooks/use-stream ms/keyboard-space #(reset! space? %))
|
||||
(hooks/use-stream ms/keyboard-=-or-+ #(do
|
||||
(dom/prevent-default (:event %))
|
||||
(st/emit! (dw/increase-zoom))))
|
||||
(hooks/use-stream ms/keyboard-minus-or-underscore #(do
|
||||
(dom/prevent-default (:event %))
|
||||
(st/emit! (dw/decrease-zoom))))
|
||||
(hooks/use-stream ms/keyboard-z #(reset! z? %))
|
||||
(hooks/use-stream ms/keyboard-shift #(reset! shift? %)))
|
||||
(defn setup-keyboard
|
||||
[alt* mod* space* z* shift*]
|
||||
(let [kbd-zoom-s
|
||||
(mf/with-memo []
|
||||
(->> ms/keyboard
|
||||
(rx/filter kbd/key-down-event?)
|
||||
(rx/filter kbd/mod-event?)
|
||||
(rx/filter (fn [kevent]
|
||||
(or ^boolean (kbd/minus? kevent)
|
||||
^boolean (kbd/underscore? kevent)
|
||||
^boolean (kbd/equals? kevent)
|
||||
^boolean (kbd/plus? kevent))))
|
||||
(rx/dedupe)))
|
||||
|
||||
kbd-shift-s
|
||||
(mf/with-memo []
|
||||
(->> ms/keyboard
|
||||
(rx/filter kbd/shift-key?)
|
||||
(rx/filter (complement kbd/editing-event?))
|
||||
(rx/map kbd/key-down-event?)
|
||||
(rx/dedupe)))
|
||||
|
||||
kbd-z-s
|
||||
(mf/with-memo []
|
||||
(->> ms/keyboard
|
||||
(rx/filter kbd/z?)
|
||||
(rx/filter (complement kbd/editing-event?))
|
||||
(rx/map kbd/key-down-event?)
|
||||
(rx/dedupe)))]
|
||||
|
||||
(hooks/use-stream ms/keyboard-alt (partial reset! alt*))
|
||||
(hooks/use-stream ms/keyboard-space (partial reset! space*))
|
||||
(hooks/use-stream kbd-z-s (partial reset! z*))
|
||||
(hooks/use-stream kbd-shift-s (partial reset! shift*))
|
||||
(hooks/use-stream ms/keyboard-mod
|
||||
(fn [value]
|
||||
(reset! mod* value)
|
||||
;; In mac after command+z there is no event
|
||||
;; for the release of the z key
|
||||
(when-not ^boolean value
|
||||
(reset! z* false))))
|
||||
|
||||
(hooks/use-stream kbd-zoom-s
|
||||
(fn [kevent]
|
||||
(dom/prevent-default kevent)
|
||||
(st/emit!
|
||||
(if (or ^boolean (kbd/minus? kevent)
|
||||
^boolean (kbd/underscore? kevent))
|
||||
(dw/decrease-zoom)
|
||||
(dw/increase-zoom)))))))
|
||||
|
||||
|
||||
(defn group-empty-space?
|
||||
"Given a group `group-id` check if `hover-ids` contains any of its children. If it doesn't means
|
||||
|
|
|
@ -9,15 +9,44 @@
|
|||
[app.config :as cfg]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defrecord KeyboardEvent [type key shift ctrl alt meta mod editing native-event]
|
||||
Object
|
||||
(preventDefault [_]
|
||||
(.preventDefault native-event))
|
||||
|
||||
(stopPropagation [_]
|
||||
(.stopPropagation native-event)))
|
||||
|
||||
(defn keyboard-event?
|
||||
[o]
|
||||
(instance? KeyboardEvent o))
|
||||
|
||||
(defn key-up-event?
|
||||
[^KeyboardEvent event]
|
||||
(= :up (.-type event)))
|
||||
|
||||
(defn key-down-event?
|
||||
[^KeyboardEvent event]
|
||||
(= :down (.-type event)))
|
||||
|
||||
(defn mod-event?
|
||||
[^KeyboardEvent event]
|
||||
(true? (.-mod event)))
|
||||
|
||||
(defn editing-event?
|
||||
[^KeyboardEvent event]
|
||||
(true? (.-editing event)))
|
||||
|
||||
(defn is-key?
|
||||
[^string key]
|
||||
(fn [^js e]
|
||||
(fn [^KeyboardEvent e]
|
||||
(= (.-key e) key)))
|
||||
|
||||
(defn is-key-ignore-case?
|
||||
[^string key]
|
||||
(fn [^js e]
|
||||
(= (str/upper (.-key e)) (str/upper key))))
|
||||
(let [key (str/upper key)]
|
||||
(fn [^KeyboardEvent e]
|
||||
(= (str/upper (.-key e)) key))))
|
||||
|
||||
(defn ^boolean alt?
|
||||
[^js event]
|
||||
|
@ -62,6 +91,3 @@
|
|||
(def home? (is-key? "Home"))
|
||||
(def tab? (is-key? "Tab"))
|
||||
|
||||
(defn editing? [e]
|
||||
(.-editing ^js e))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue