       (reset! fb-messages fb-item)
       (bind-to-ratom messages fb-item))))
 
-;; -------------------------
-;; Views
+;; -- Subscriptions ---------
 
-(defn ^:export toggle-showing-state! []
-  (swap! show-state? not))
+(register-sub
+  :username-input
+  (fn [db _]
+    (reaction (:username @db))))
 
-(defn text-input [value]
-  [:input {:type "text"
-           :value @value
-           :on-change #(reset! value (-> % .-target .-value))}])
+;; -- Event Handlers --------
+
+(register-handler
+  :initialize
+  (fn [db _]
+    (merge db initial-state)))
+
+(register-handler
+  :set-username-input
+  (fn [db [_ value]]
+    (assoc db :username value)))
+
+;; -- View Components -------
+
+(defn username-input []
+  (let [username (subscribe [:username-input])]
+    [:input {:type "text"
+             :value @username
+             :on-change #(dispatch [:set-username-input (-> % .-target .-value)])}]))
+
+(defn message-form []
+  (let [message  (reagent/atom "")
+        username (subscribe [:username-input])]
+    [:form {:on-submit (fn [e]
+                         (.preventDefault e)
+                         (firebase-swap! @fb-messages conj [@username @message]))}
+     [:input {:type "text"
+              :on-change #(reset! message (-> % .-target .-value))}]
+     [:button {:type "submit"} "Send"]]))
+
+;; -- Views -----------------
 
 (defn on-going-chat []
   [:div
-   [:label "Your username:"]
-   [text-input username]
+   [:label "Your username: "]
+   [username-input]
 
    [:div#messages
     (for [[message index] (map vector (take-last 30 @messages) (range))]
       ^{:key (str "message-" index)}
       [:div [:span.username (first message) ": "] [:span.message (second message)]])]
 
-   (let [users-message (reagent/atom "")]
-     [:form {:on-submit (fn [e]
-                          (.preventDefault e)
-                          (firebase-swap! @fb-messages conj [@username @users-message]))}
-      [text-input users-message]
-      [:button {:type "submit"} "Send"]])])
+   [message-form]])
 
 (defn join-room-view []
   (let [this-room (atom (random-four-characters))

;; -------------------------
;; History
;; must be called after routes have been defined
(defn hook-browser-navigation! []
  (doto (History.)
    (events/listen

      [on-going-chat]
      [join-room-view])

    [:div [:br] [:br] [:br]
     "STATE!!!!"
     [:div "Messages: " (pr-str @messages)]]]])

(defn current-page []
  [:div [(session/get :current-page)]])

;; -------------------------
;; Routes

(secretary/defroute "/" []
  (reset! chat-room nil)
