Use state machine for new recipes
This commit is contained in:
parent
00efd3d53a
commit
0db764b145
1 changed files with 50 additions and 58 deletions
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue