Browse Source

fix: cross-platform shotcuts (#10590)

This PR also simplifies the implementation of shui/shortcut a lot.

* fix: consistent char for the Enter key

* fix: show ctrl instead of ⌘ for copy ref

* fix: "Ctrl" should be split from "Ctrl X"
Tienson Qin 1 year ago
parent
commit
ecde2c3bfc

+ 13 - 10
deps/shui/src/logseq/shui/button/v2.cljs

@@ -3,11 +3,12 @@
     [clojure.string :as str]
     [rum.core :as rum]
     [logseq.shui.icon.v2 :as icon]
-    [clojure.string :as string]))
+    [clojure.string :as string]
+    [goog.userAgent]))
 
 (rum/defcs root < rum/reactive
   (rum/local nil ::hover-theme)
-  [state {:keys [theme hover-theme color text depth size icon interactive shortcut tiled on-click muted disabled? class href button-props icon-props]
+  [state {:keys [theme hover-theme color text depth size icon interactive shortcut tiled tiles on-click muted disabled? class href button-props icon-props]
           :or {theme :color depth 1 size :md interactive true muted false class ""}} context]
   (let [*hover-theme (::hover-theme state)
         color-string (or (some-> color name) (some-> context :state rum/react :ui/radix-color name) "custom")
@@ -31,12 +32,14 @@
         :on-mouse-out #(reset! *hover-theme nil)}
         on-click
         (assoc :on-click on-click)))
-     (if-not tiled text
-             (for [[index tile] (map-indexed vector (rest (string/split text #"")))]
-               [:<>
-                (when (< 0 index)
-                  [:div.ui__button__tile-separator])
-                [:div.ui__button__tile tile]]))
+     (if (and tiled (or text tiles))
+       (for [[index tile] (map-indexed vector
+                                       (or tiles (and text (rest (string/split text #"")))))]
+         [:<>
+          (when (< 0 index)
+            [:div.ui__button__tile-separator])
+          [:div.ui__button__tile tile]])
+       text)
 
      (when icon
        (icon/root icon icon-props))
@@ -44,9 +47,9 @@
        (for [key shortcut]
          [:div.ui__button-shortcut-key
           (case key
-            "cmd" [:div "⌘"]
+            "cmd" [:div (if goog.userAgent/MAC "⌘" "Ctrl")]
             "shift" [:div "⇧"]
-            "return" [:div ""]
+            "return" [:div ""]
             "esc" [:div.tracking-tightest {:style {:transform "scaleX(0.8) scaleY(1.2) "
                                                    :font-size "0.5rem"
                                                    :font-weight "500"}} "ESC"]

+ 67 - 79
deps/shui/src/logseq/shui/shortcut/v1.cljs

@@ -6,35 +6,42 @@
 
 (def mac? goog.userAgent/MAC)
 (defn print-shortcut-key [key]
-  (case key
-    ("cmd" "command" "mod" "⌘" "meta") "⌘"
-    ("return" "enter" "⏎") "⏎"
-    ("shift" "⇧") "⇧"
-    ("alt" "option" "opt" "⌥") "⌥"
-    ("ctrl" "control" "⌃") "⌃"
-    ("space" " ") " "
-    ("up" "↑") "↑"
-    ("down" "↓") "↓"
-    ("left" "←") "←"
-    ("right" "→") "→"
-    ("tab") "⇥"
-    ("open-square-bracket") "["
-    ("close-square-bracket") "]"
-    ("dash") "-"
-    ("semicolon") ";"
-    ("equals") "="
-    ("single-quote") "'"
-    ("backslash") "\\"
-    ("comma") ","
-    ("period") "."
-    ("slash") "/"
-    ("grave-accent") "`"
-    ("page-up") ""
-    ("page-down") ""
-    (nil) ""
-    (name key)))
+  (let [result (if (coll? key)
+                 (string/join "+" key)
+                 (case (if (string? key)
+                         (string/lower-case key)
+                         key)
+                   ("cmd" "command" "mod" "⌘") (if mac? "⌘" "Ctrl")
+                   ("meta") (if mac? "⌘" "⊞")
+                   ("return" "enter" "⏎") "⏎"
+                   ("shift" "⇧") "⇧"
+                   ("alt" "option" "opt" "⌥") (if mac? "Opt" "Alt")
+                   ("ctrl" "control" "⌃") "Ctrl"
+                   ("space" " ") "Space"
+                   ("up" "↑") "↑"
+                   ("down" "↓") "↓"
+                   ("left" "←") "←"
+                   ("right" "→") "→"
+                   ("tab") "Tab"
+                   ("open-square-bracket") "["
+                   ("close-square-bracket") "]"
+                   ("dash") "-"
+                   ("semicolon") ";"
+                   ("equals") "="
+                   ("single-quote") "'"
+                   ("backslash") "\\"
+                   ("comma") ","
+                   ("period") "."
+                   ("slash") "/"
+                   ("grave-accent") "`"
+                   ("page-up") ""
+                   ("page-down") ""
+                   (nil) ""
+                   (name key)))]
+    (if (= (count result) 1)
+      result
+      (string/capitalize result))))
 
-;; TODO: shortcut component shouldn't worry about this
 (defn to-string [input]
   (cond
     (string? input) input
@@ -45,57 +52,38 @@
     (nil? input) ""
     :else (pr-str input)))
 
+(defn- parse-shortcuts
+  [s]
+  (->> (string/split s #" \| ")
+       (map (fn [x]
+              (->> (string/split x #" ")
+                   (map #(if (string/includes? % "+")
+                           (string/split % #"\+")
+                           %)))))))
+
+(rum/defc part
+  [context theme ks size]
+  (button/root {:theme theme
+                :interactive false
+                :tiled true
+                :tiles (map print-shortcut-key ks)
+                :size size
+                :mused true}
+               context))
+
 (rum/defc root
-  [shortcut context & {:keys [tiled size theme]
-                       :or {tiled true
-                            size :sm
+  [shortcut context & {:keys [size theme]
+                       :or {size :sm
                             theme :gray}}]
   (when (seq shortcut)
-    (if (coll? shortcut)
-      (let [texts (map print-shortcut-key shortcut)
-            tiled? (every? #(= (count %) 1) texts)]
-        (if tiled?
-          [:div.flex.flex-row
-           (for [text texts]
-             (button/root {:theme theme
-                           :interactive false
-                           :text (to-string text)
-                           :tiled tiled?
-                           :size size
-                           :mused true}
-                          context))]
-          (let [text' (string/join " " texts)]
-            (button/root {:theme theme
-                          :interactive false
-                          :text text'
-                          :tiled false
-                          :size size
-                          :mused true}
-                         context))))
-      [:<>
-       (for [[index option] (map-indexed vector (string/split shortcut #" \| "))]
-         [:<>
-          (when (< 0 index)
-            [:div.text-gray-11.text-sm "|"])
-          (let [[system-default option] (if (.startsWith option "system default: ")
-                                          [true (subs option 16)]
-                                          [false option])]
-            [:<>
-             (when system-default
-               [:div.mr-1.text-xs "System default: "])
-             (for [sequence (string/split option #" ")
-                   :let [text (->> (string/split sequence #"\+")
-                                   (map print-shortcut-key)
-                                   (apply str))]]
-               (let [tiled? (if (contains?
-                                 #{"backspace" "delete" "home" "end" "insert"}
-                                 (string/lower-case text))
-                              false
-                              tiled)]
-                 (button/root {:theme theme
-                               :interactive false
-                               :text (to-string text)
-                               :tiled tiled?
-                               :size size
-                               :mused true}
-                              context)))])])])))
+    (let [shortcuts (if (coll? shortcut)
+                      [shortcut]
+                      (parse-shortcuts shortcut))]
+      (for [[index binding] (map-indexed vector shortcuts)]
+        [:<>
+         (when (< 0 index)
+           [:div.text-gray-11.text-sm "|"])
+         (if (coll? (first binding))   ; + included
+           (for [ks binding]
+             (part context theme ks size))
+           (part context theme binding size))]))))

+ 6 - 3
resources/css/shui.css

@@ -23,19 +23,22 @@
 }
 
 .ui__button-tiled .ui__button__tile {
-  @apply flex items-center justify-center text-center;
+  @apply flex items-center justify-center text-center px-1;
 }
 
 .ui__button-tiled.ui__button-size-md .ui__button__tile {
-  @apply h-6 w-6;
+  @apply h-6;
+  min-width: 1.5rem;
 }
 
 .ui__button-tiled.ui__button-size-sm .ui__button__tile {
-    @apply h-4 w-4;
+  @apply h-4;
+  min-width: 1rem;
 }
 
 .ui__button__tile-separator {
   @apply w-px h-full bg-gray-08-alpha;
+  min-height: 14px;
 }
 
 .ui__button-theme-text {

+ 2 - 2
src/main/frontend/components/cmdk.cljs

@@ -665,8 +665,8 @@
      (shui/shortcut "/" context)
      [:div "to filter search results"]]
     [:div.flex.flex-row.gap-1.items-center.opacity-50.hover:opacity-100
-     (shui/shortcut "mod enter" context)
-     [:div "to open search in the sidebar"]]]))
+     (shui/shortcut ["mod" "enter"] context)
+     [:div "to open search in the sidebar"]]])  )
 
 (rum/defcs tip <
   {:init (fn [state]

+ 1 - 1
src/main/frontend/components/shortcut.cljs

@@ -459,7 +459,7 @@
 
                       (cond
                         (or unset? user-binding (false? user-binding))
-                        [:code.dark:bg-green-800.bg-green-300
+                        [:code
                          (if unset?
                            (t :keymap/unset)
                            (str (t :keymap/custom) ": "

+ 4 - 4
src/main/frontend/modules/shortcut/data_helper.cljs

@@ -140,10 +140,10 @@
   (let [tmp (cond
               (false? binding)
               (cond
-                (and util/mac? (= k :editor/kill-line-after)) "system default: ctrl k"
-                (and util/mac? (= k :editor/beginning-of-block)) "system default: ctrl a"
-                (and util/mac? (= k :editor/end-of-block)) "system default: ctrl e"
-                (and util/mac? (= k :editor/backward-kill-word)) "system default: opt delete"
+                (and util/mac? (= k :editor/kill-line-after)) "ctrl k"
+                (and util/mac? (= k :editor/beginning-of-block)) "ctrl a"
+                (and util/mac? (= k :editor/end-of-block)) "ctrl e"
+                (and util/mac? (= k :editor/backward-kill-word)) "opt delete"
                 :else (t :keymap/disabled))
 
               (string? binding)