Browse Source

feat: command palette history

Weihua Lu 4 years ago
parent
commit
719f780f3d

+ 11 - 10
src/main/frontend/components/command_palette.cljs

@@ -1,14 +1,15 @@
 (ns frontend.components.command-palette
-  (:require [frontend.handler.command-palette :as cp]
+  (:require [clojure.string :as str]
+            [frontend.handler.command-palette :as cp]
+            [frontend.modules.shortcut.core :as shortcut]
             [frontend.search :as search]
             [frontend.state :as state]
-            [frontend.modules.shortcut.core :as shortcut]
             [frontend.ui :as ui]
             [frontend.util :as util]
             [rum.core :as rum]))
 
-(defn get-matched-commands [commands input]
-  (search/fuzzy-search commands input :limit 7 :extract-fn :desc))
+(defn get-matched-commands [commands input limit]
+  (search/fuzzy-search commands input :limit limit :extract-fn :desc))
 
 (defn render-command [{:keys [id desc shortcut]} chosen?]
   [:div.inline-grid.grid-cols-4.gap-x-4.w-full
@@ -25,7 +26,8 @@
   {:will-unmount (fn [state]
                    (state/set-state! :ui/command-palette-open? false)
                    state)}
-  [state {:keys [commands]}]
+  [state {:keys [commands limit]
+          :or {limit 10}}]
   (let [input (::input state)]
     [:div#command-palette.cp__command-palette-main
      [:input.cp__command-palette-input.w-full
@@ -36,13 +38,12 @@
        :on-change   (fn [e] (reset! input (util/evalue e)))}]
      [:div.w-full
       (ui/auto-complete
-       (get-matched-commands commands @input)
+       (if (str/blank? @input)
+         (cp/top-commands limit)
+         (get-matched-commands commands @input limit))
        {:item-render render-command
         :class       "cp__command-palette-results"
-        :on-chosen   (fn [{:keys [action]}]
-                       (state/set-state! :ui/command-palette-open? false)
-                       (action))})]]))
-
+        :on-chosen   (fn [cmd] (cp/invoke-command cmd))})]]))
 
 (rum/defc command-palette-modal < rum/reactive
   []

+ 30 - 1
src/main/frontend/handler/command_palette.cljs

@@ -3,7 +3,8 @@
             [frontend.modules.shortcut.data-helper :as shortcut-helper]
             [frontend.spec :as spec]
             [frontend.state :as state]
-            [lambdaisland.glogi :as log]))
+            [lambdaisland.glogi :as log]
+            [frontend.storage :as storage]))
 
 (s/def :command/id keyword?)
 (s/def :command/desc string?)
@@ -30,6 +31,34 @@
   (->> (get @state/state :command-palette/commands)
        (sort-by :id)))
 
+(defn history []
+  (or (storage/get "commands-history") []))
+
+(defn- assoc-invokes [cmds]
+  (let [invokes (->> (history)
+                     (map :id)
+                     (frequencies))]
+    (mapv (fn [{:keys [id] :as cmd}]
+            (if (contains? invokes id)
+              (assoc cmd :invokes-count (get invokes id))
+              cmd))
+          cmds)))
+
+(defn add-history [{:keys [id]}]
+  (storage/set "commands-history" (conj (history) {:id id :timestamp (.getTime (js/Date.))})))
+
+(defn invoke-command [{:keys [action] :as cmd}]
+  (add-history cmd)
+  (state/set-state! :ui/command-palette-open? false)
+  (js/setTimeout (fn [] (action)) 200))
+
+(defn top-commands [limit]
+  (->> (get-commands)
+       (assoc-invokes)
+       (sort-by :invokes-count)
+       (reverse)
+       (take limit)))
+
 (defn register [{:keys [id] :as command}]
   (spec/validate :command/command command)
   (let [cmds (get-commands)]