Use state machine for new recipes

This commit is contained in:
Nicholas Kariniemi 2014-08-06 00:09:25 +03:00
parent 00efd3d53a
commit 0db764b145

View file

@ -14,77 +14,69 @@
(not (empty? grubs))) (not (empty? grubs)))
(om/set-state! owner :new-recipe-name "") (om/set-state! owner :new-recipe-name "")
(om/set-state! owner :new-recipe-grubs "") (om/set-state! owner :new-recipe-grubs "")
(om/set-state! owner :editing false)
(put! ch (recipe/add-event name grubs)))) (put! ch (recipe/add-event name grubs))))
(def transitions
{:waiting {:click :editing}
:editing {:body-mousedown :waiting
:save :waiting}})
(defn transition-state [owner event]
(let [current (om/get-state owner :edit-state)
next (or (get-in transitions [current event]) current)]
(condp = [current event next]
[:editing :save :waiting] (let [add-ch (om/get-shared owner :recipe-add)
name (om/get-state owner :new-recipe-name)
grubs (om/get-state owner :new-recipe-grubs)]
(add-recipe add-ch name grubs owner))
nil)
(om/set-state! owner :edit-state next)))
(defn new-recipe-view [_ owner] (defn new-recipe-view [_ owner]
(reify (reify
om/IInitState om/IInitState
(init-state [_] (init-state [_]
(let [publisher (chan)] (let [publisher (chan)]
{:editing false {:edit-state :waiting
:>local-events publisher
:<local-events (a/pub publisher identity)
:new-recipe-name "" :new-recipe-name ""
:new-recipe-grubs ""})) :new-recipe-grubs ""}))
om/IRenderState om/IRenderState
(render-state [this {:keys [editing >local-events new-recipe-name new-recipe-grubs]}] (render-state [this {:keys [edit-state new-recipe-name new-recipe-grubs]}]
(let [add (om/get-shared owner :recipe-add)] (html
(html [:div.panel.panel-default.recipe-panel
[:div.panel.panel-default.recipe-panel {:on-click #(when (not (dom/click-on-elem? % (om/get-node owner :save-btn)))
{:on-click #(put! >local-events :click)} (transition-state owner :click))}
[:div.panel-heading.recipe-header [:div.panel-heading.recipe-header
[:input.form-control.recipe-header-input [:input.form-control.recipe-header-input
{:id "new-recipe-name" {:id "new-recipe-name"
:type "text" :type "text"
:placeholder "New recipe" :placeholder "New recipe"
:value new-recipe-name :value new-recipe-name
:on-change #(om/set-state! owner :new-recipe-name (dom/event-val %))}]] :on-change #(om/set-state! owner :new-recipe-name (dom/event-val %))}]]
[:div.panel-body.recipe-grubs [:div.panel-body.recipe-grubs
{:class (when (not editing) "hidden")} {:class (when (= edit-state :waiting) "hidden")}
[:textarea.form-control.recipe-grubs-input [:textarea.form-control.recipe-grubs-input
{:id "new-recipe-grubs" {:id "new-recipe-grubs"
:rows 3 :rows 3
:placeholder "Recipe ingredients" :placeholder "Recipe ingredients"
:value new-recipe-grubs :value new-recipe-grubs
:on-change #(om/set-state! owner :new-recipe-grubs (dom/event-val %))}] :on-change #(om/set-state! owner :new-recipe-grubs (dom/event-val %))}]
[:button.btn.btn-primary.pull-right.recipe-btn.recipe-done-btn [:button.btn.btn-primary.pull-right.recipe-btn.recipe-done-btn
{:type "button" {:type "button"
:on-click #(put! >local-events :done)} :ref :save-btn
"Done"]]]))) :on-click #(transition-state owner :save)}
"Save"]]]))
om/IWillMount om/IWillMount
(will-mount [_] (will-mount [_]
(let [<local-events (om/get-state owner :<local-events) (let [<events (om/get-shared owner :<events)
<events (om/get-shared owner :<events) subscriber (chan)]
add (om/get-shared owner :recipe-add) (a/sub <events :body-mousedown subscriber)
] (go-loop [] (let [event (<! subscriber)]
(go-loop [] (when-not (dom/click-on-self? (:event event) (om/get-node owner))
(let [subscriber (chan)] (transition-state owner :body-mousedown))
(a/sub <local-events :click subscriber) (recur)))))))
(<! subscriber)
(a/unsub <local-events :click subscriber)
(a/close! subscriber))
(om/set-state! owner :editing true)
(let [subscriber (chan)]
(a/sub <events :body-mousedown subscriber)
(a/sub <local-events :done subscriber)
(loop []
(let [event (<! subscriber)]
(if-not (and (= (:type event) :body-mousedown)
(dom/click-on-self? (:event event) (om/get-node owner)))
(when (= event :done)
(add-recipe add
(om/get-state owner :new-recipe-name)
(om/get-state owner :new-recipe-grubs)
owner))
(recur))))
(a/unsub <events :body-mousedown subscriber)
(a/unsub <local-events :done subscriber)
(a/close! subscriber))
(om/set-state! owner :editing false)
(recur))))))
(defn view [recipes owner] (defn view [recipes owner]
(reify (reify