 
 (defn millis [] (.now js/performance))
 
-(defn click [app owner]
+(defn tap-tempo-button [_ owner]
   (reify
     om/IInitState
-    (init-state [_] {:previous-click nil})
+    (init-state [_] {:previous-click nil
+                     :should-stop false})
+    om/IDidMount
+    (did-mount [_]
+      (letfn [(key-handler [e] (when (= "Shift" (.-key e)) (om/set-state! owner :should-stop (= "keydown" (.-type e)))))]
+        (.addEventListener js/document "keydown" key-handler)
+        (.addEventListener js/document "keyup" key-handler)))
     om/IRenderState
-    (render-state [_ {:keys [click-channel previous-click]}]
+    (render-state [_ {:keys [tempo-channel previous-click should-stop]}]
                   (dom/button #js {:className "btn btn-default btn-lg btn-block btn-tap-tempo"
                                    :onClick (fn []
                                               (let [m (millis)]
                                                 (om/set-state! owner :previous-click m)
                                                 (when-not (nil? previous-click)
-                                                  (put! click-channel (if (:should-stop app) false (- m previous-click))))))}
-                              (if (:should-stop app) "stop" "tap tempo")))))
+                                                  (put! tempo-channel (if should-stop false (- m previous-click))))))}
+                              (if should-stop "stop" "tap tempo")))))
 
 (defn dots [meter owner]
   (reify

                             (om/update! bpm :next-beat (+ t interval))))))
                     (when (om/get-state owner :mounted)
                       (.requestAnimationFrame js/window cb))))
                 (let [click-channel (om/get-state owner :click-channel)]
                   (go (loop []
                         (let [new-interval-millis (<! click-channel)]
                           (if (false? new-interval-millis)
                             (stop-interval)
                             (start-interval new-interval-millis))

  (:require-macros [cljs.core.async.macros :refer [go]]))

(defonce app-setup

  (do
    (enable-console-print!)))

(defonce app-state (atom {:bpm {} 
                          :meter {:count 0}}))

(defn clock [bpm owner]
  (letfn [(start-interval [millis] 
            (om/update! bpm :interval millis)
            (om/update! bpm :next-beat nil))
          (stop-interval []
            (om/update! bpm :interval nil))]
    (reify
      om/IInitState
