mirror of
https://github.com/penpot/penpot.git
synced 2025-01-25 07:58:49 -05:00
♻️ Improves shortcuts lifecycle management.
This commit is contained in:
parent
c33c3fb2fa
commit
4b7f82a9d9
6 changed files with 130 additions and 55 deletions
|
@ -5,14 +5,22 @@
|
|||
;; Copyright (c) UXBOX Labs SL
|
||||
|
||||
(ns app.main.data.shortcuts
|
||||
(:refer-clojure :exclude [meta reset!])
|
||||
(:require
|
||||
["mousetrap" :as mousetrap]
|
||||
[app.common.data :as d]
|
||||
[app.common.spec :as us]
|
||||
[app.config :as cfg]
|
||||
[app.util.logging :as log])
|
||||
(:refer-clojure :exclude [meta]))
|
||||
[app.util.logging :as log]
|
||||
[cljs.spec.alpha :as s]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
(log/set-level! :warn)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Helpers
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def mac-command "\u2318")
|
||||
(def mac-option "\u2325")
|
||||
(def mac-delete "\u232B")
|
||||
|
@ -44,30 +52,8 @@
|
|||
[shortcut]
|
||||
(c-mod (a-mod shortcut)))
|
||||
|
||||
(defn bind-shortcuts
|
||||
([shortcuts-config]
|
||||
(bind-shortcuts
|
||||
shortcuts-config
|
||||
mousetrap/bind
|
||||
(fn [key cb]
|
||||
(fn [event]
|
||||
(log/debug :msg (str "Shortcut" key))
|
||||
(.preventDefault event)
|
||||
(cb event)))))
|
||||
|
||||
([shortcuts-config bind-fn cb-fn]
|
||||
(doseq [[key {:keys [command disabled fn type]}] shortcuts-config]
|
||||
(when-not disabled
|
||||
(if (vector? command)
|
||||
(doseq [cmd (seq command)]
|
||||
(bind-fn cmd (cb-fn key fn) type))
|
||||
(bind-fn command (cb-fn key fn) type))))))
|
||||
|
||||
(defn remove-shortcuts
|
||||
[]
|
||||
(mousetrap/reset))
|
||||
|
||||
(defn meta [key]
|
||||
(defn meta
|
||||
[key]
|
||||
;; If the key is "+" we need to surround with quotes
|
||||
;; otherwise will not be very readable
|
||||
(let [key (if (and (not (cfg/check-platform? :macos))
|
||||
|
@ -80,37 +66,120 @@
|
|||
"Ctrl+")
|
||||
key)))
|
||||
|
||||
(defn shift [key]
|
||||
(defn shift
|
||||
[key]
|
||||
(str
|
||||
(if (cfg/check-platform? :macos)
|
||||
mac-shift
|
||||
"Shift+")
|
||||
key))
|
||||
|
||||
(defn alt [key]
|
||||
(defn alt
|
||||
[key]
|
||||
(str
|
||||
(if (cfg/check-platform? :macos)
|
||||
mac-option
|
||||
"Alt+")
|
||||
key))
|
||||
|
||||
(defn meta-shift [key]
|
||||
(defn meta-shift
|
||||
[key]
|
||||
(-> key meta shift))
|
||||
|
||||
(defn meta-alt [key]
|
||||
(defn meta-alt
|
||||
[key]
|
||||
(-> key meta alt))
|
||||
|
||||
(defn supr []
|
||||
(defn supr
|
||||
[]
|
||||
(if (cfg/check-platform? :macos)
|
||||
mac-delete
|
||||
"Supr"))
|
||||
|
||||
(defn esc []
|
||||
(defn esc
|
||||
[]
|
||||
(if (cfg/check-platform? :macos)
|
||||
mac-esc
|
||||
"Escape"))
|
||||
|
||||
(defn enter []
|
||||
(defn enter
|
||||
[]
|
||||
(if (cfg/check-platform? :macos)
|
||||
mac-enter
|
||||
"Enter"))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Events
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; --- EVENT: push
|
||||
|
||||
(s/def ::tooltip ::us/string)
|
||||
(s/def ::fn fn?)
|
||||
|
||||
(s/def ::command
|
||||
(s/or :str ::us/string
|
||||
:vec vector?))
|
||||
|
||||
(s/def ::shortcut
|
||||
(s/keys :req-un [::command]
|
||||
:opt-un [::fn
|
||||
::tooltip]))
|
||||
|
||||
(s/def ::shortcuts
|
||||
(s/map-of ::us/keyword
|
||||
::shortcut))
|
||||
|
||||
(defn- wrap-cb
|
||||
[key cb]
|
||||
(fn [event]
|
||||
(log/debug :msg (str "Shortcut" key))
|
||||
(.preventDefault event)
|
||||
(cb event)))
|
||||
|
||||
(defn- bind!
|
||||
[shortcuts]
|
||||
(->> shortcuts
|
||||
(remove #(:disabled (second %)))
|
||||
(run! (fn [[key {:keys [command fn type]}]]
|
||||
(if (vector? command)
|
||||
(run! #(mousetrap/bind % (wrap-cb key fn) type) command)
|
||||
(mousetrap/bind command (wrap-cb key fn) type))))))
|
||||
|
||||
(defn- reset!
|
||||
([]
|
||||
(mousetrap/reset))
|
||||
([shortcuts]
|
||||
(mousetrap/reset)
|
||||
(bind! shortcuts)))
|
||||
|
||||
(defn push-shortcuts
|
||||
[key shortcuts]
|
||||
(us/assert ::us/keyword key)
|
||||
(us/assert ::shortcuts shortcuts)
|
||||
(ptk/reify ::push-shortcuts
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update :shortcuts (fnil conj '()) [key shortcuts])))
|
||||
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(let [[key shortcuts] (peek (:shortcuts state))]
|
||||
(reset! shortcuts)))))
|
||||
|
||||
(defn pop-shortcuts
|
||||
[key]
|
||||
(ptk/reify ::pop-shortcuts
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :shortcuts (fn [shortcuts]
|
||||
(let [current-key (first (peek shortcuts))]
|
||||
(if (= key current-key)
|
||||
(pop shortcuts)
|
||||
shortcuts)))))
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(let [[key* shortcuts] (peek (:shortcuts state))]
|
||||
(when (not= key key*)
|
||||
(reset! shortcuts))))))
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
:toggle-assets {:tooltip (ds/alt "I")
|
||||
:command (ds/a-mod "i")
|
||||
:fn #(st/emit! (dw/go-to-layout :assets))}
|
||||
|
||||
|
||||
:toggle-history {:tooltip (ds/alt "H")
|
||||
:command (ds/a-mod "h")
|
||||
:fn #(st/emit! (dw/go-to-layout :document-history))}
|
||||
|
@ -45,7 +45,7 @@
|
|||
:toggle-rules {:tooltip (ds/meta-shift "R")
|
||||
:command (ds/c-mod "shift+r")
|
||||
:fn #(st/emit! (dw/toggle-layout-flags :rules))}
|
||||
|
||||
|
||||
:select-all {:tooltip (ds/meta "A")
|
||||
:command (ds/c-mod "a")
|
||||
:fn #(st/emit! (dw/select-all))}
|
||||
|
@ -73,7 +73,7 @@
|
|||
:decrease-zoom {:tooltip "-"
|
||||
:command "-"
|
||||
:fn #(st/emit! (dw/decrease-zoom nil))}
|
||||
|
||||
|
||||
:group {:tooltip (ds/meta "G")
|
||||
:command (ds/c-mod "g")
|
||||
:fn #(st/emit! dw/group-selected)}
|
||||
|
@ -173,7 +173,8 @@
|
|||
|
||||
:paste {:tooltip (ds/meta "V")
|
||||
:disabled true
|
||||
:command (ds/c-mod "v")}
|
||||
:command (ds/c-mod "v")
|
||||
:fn (constantly nil)}
|
||||
|
||||
:delete {:tooltip (ds/supr)
|
||||
:command ["del" "backspace"]
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
(events/unlistenByKey key1))))]
|
||||
|
||||
(mf/use-effect on-mount)
|
||||
(hooks/use-shortcuts sc/shortcuts)
|
||||
(hooks/use-shortcuts ::handoff sc/shortcuts)
|
||||
|
||||
[:div.handoff-layout {:class (dom/classnames :force-visible
|
||||
(:show-thumbnails state))}
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.main.data.shortcuts :as dsc]
|
||||
[app.main.store :as st]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.object :as obj]
|
||||
[app.util.dom.dnd :as dnd]
|
||||
[app.util.logging :as log]
|
||||
[app.util.object :as obj]
|
||||
[app.util.timers :as ts]
|
||||
[app.util.transit :as t]
|
||||
[app.util.webapi :as wapi]
|
||||
|
@ -35,11 +36,13 @@
|
|||
state))
|
||||
|
||||
(defn use-shortcuts
|
||||
[shortcuts]
|
||||
[key shortcuts]
|
||||
(mf/use-effect
|
||||
#js [(str key) shortcuts]
|
||||
(fn []
|
||||
(dsc/bind-shortcuts shortcuts)
|
||||
(fn [] (dsc/remove-shortcuts)))))
|
||||
(st/emit! (dsc/push-shortcuts key shortcuts))
|
||||
(fn []
|
||||
(st/emit! (dsc/pop-shortcuts key))))))
|
||||
|
||||
(defn invisible-image
|
||||
[]
|
||||
|
|
|
@ -237,7 +237,7 @@
|
|||
(events/unlistenByKey key3))))]
|
||||
|
||||
(mf/use-effect on-mount)
|
||||
(hooks/use-shortcuts sc/shortcuts)
|
||||
(hooks/use-shortcuts ::viewer sc/shortcuts)
|
||||
|
||||
[:div.viewer-layout {:class (dom/classnames :force-visible
|
||||
(:show-thumbnails state))}
|
||||
|
|
|
@ -153,18 +153,6 @@
|
|||
(utils/update-transform render-node roots modifiers)
|
||||
(utils/remove-transform render-node roots))))))
|
||||
|
||||
(defn setup-shortcuts [path-editing? drawing-path?]
|
||||
(mf/use-effect
|
||||
(mf/deps path-editing? drawing-path?)
|
||||
(fn []
|
||||
(cond
|
||||
(or drawing-path? path-editing?)
|
||||
(dsc/bind-shortcuts psc/shortcuts)
|
||||
|
||||
:else
|
||||
(dsc/bind-shortcuts wsc/shortcuts))
|
||||
dsc/remove-shortcuts)))
|
||||
|
||||
(defn inside-vbox [vbox objects frame-id]
|
||||
(let [frame (get objects frame-id)]
|
||||
|
||||
|
@ -195,3 +183,17 @@
|
|||
(:frame-id @hover))]
|
||||
(when (not (contains? @active-frames frame-id))
|
||||
(swap! active-frames assoc frame-id true))))))
|
||||
|
||||
;; NOTE: this is executed on each page change, maybe we need to move
|
||||
;; this shortcuts outside the viewport?
|
||||
|
||||
(defn setup-shortcuts
|
||||
[path-editing? drawing-path?]
|
||||
(hooks/use-shortcuts ::workspace wsc/shortcuts)
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps path-editing? drawing-path?)
|
||||
(fn []
|
||||
(when (or drawing-path? path-editing?)
|
||||
(st/emit! (dsc/push-shortcuts ::path psc/shortcuts))
|
||||
(st/emitf (dsc/pop-shortcuts ::path))))))
|
||||
|
|
Loading…
Add table
Reference in a new issue