Rework state/view handling
This commit is contained in:
parent
fe6514a5f5
commit
0bf23c9255
2 changed files with 70 additions and 61 deletions
|
@ -4,21 +4,21 @@
|
||||||
(:require-macros [grub.macros :refer [log logs]]
|
(:require-macros [grub.macros :refer [log logs]]
|
||||||
[cljs.core.async.macros :refer [go go-loop]]))
|
[cljs.core.async.macros :refer [go go-loop]]))
|
||||||
|
|
||||||
(def default-app-state {:grubs {}
|
(def app-state (atom {:grubs {}
|
||||||
:recipes {}})
|
:recipes {}}))
|
||||||
|
|
||||||
(defmulti handle-grub-event (fn [event state] (:event event))
|
(defmulti handle-event (fn [event state] (:event event))
|
||||||
:default :unknown-event)
|
:default :unknown-event)
|
||||||
|
|
||||||
(defmethod handle-grub-event :unknown-event [event grubs]
|
(defmethod handle-event :unknown-event [event state]
|
||||||
grubs)
|
state)
|
||||||
|
|
||||||
(defn new-grub [id grub completed]
|
(defn new-grub [id grub completed]
|
||||||
{:id id :grub grub :completed completed})
|
{:id id :grub grub :completed completed})
|
||||||
|
|
||||||
(defmethod handle-grub-event :add-grub [event grubs]
|
(defmethod handle-event :add-grub [event state]
|
||||||
(let [grub (new-grub (:id event) (:grub event) (:completed event))]
|
(let [grub (new-grub (:id event) (:grub event) (:completed event))]
|
||||||
(assoc grubs (:id grub) grub)))
|
(assoc-in state [:grubs (:id grub)] grub)))
|
||||||
|
|
||||||
(defn assoc-new-grub [current new]
|
(defn assoc-new-grub [current new]
|
||||||
(assoc current (:id new)
|
(assoc current (:id new)
|
||||||
|
@ -27,54 +27,49 @@
|
||||||
(defn make-add-grubs-map [grub-events]
|
(defn make-add-grubs-map [grub-events]
|
||||||
(reduce assoc-new-grub {} grub-events))
|
(reduce assoc-new-grub {} grub-events))
|
||||||
|
|
||||||
(defmethod handle-grub-event :add-grub-list [event grubs]
|
(defmethod handle-event :add-grub-list [event state]
|
||||||
(let [add-grub-events (:grubs event)
|
(let [add-grub-events (:grubs event)
|
||||||
add-grubs (make-add-grubs-map add-grub-events)]
|
add-grubs (make-add-grubs-map add-grub-events)]
|
||||||
(merge grubs add-grubs)))
|
(assoc state :grubs (merge (:grubs state) add-grubs))))
|
||||||
|
|
||||||
(defmethod handle-grub-event :complete-grub [event grubs]
|
(defmethod handle-event :complete-grub [event state]
|
||||||
(assoc-in grubs [(:id event) :completed] true))
|
(assoc-in state [:grubs (:id event) :completed] true))
|
||||||
|
|
||||||
(defmethod handle-grub-event :uncomplete-grub [event grubs]
|
(defmethod handle-event :uncomplete-grub [event state]
|
||||||
(assoc-in grubs [(:id event) :completed] false))
|
(assoc-in state [:grubs (:id event) :completed] false))
|
||||||
|
|
||||||
(defmethod handle-grub-event :update-grub [event grubs]
|
(defmethod handle-event :update-grub [event state]
|
||||||
(assoc-in grubs [(:id event) :grub] (:grub event)))
|
(assoc-in state [:grubs (:id event) :grub] (:grub event)))
|
||||||
|
|
||||||
(defmethod handle-grub-event :clear-all-grubs [event grubs]
|
(defmethod handle-event :clear-all-grubs [event state]
|
||||||
{})
|
(assoc state :grubs {}))
|
||||||
|
|
||||||
(defmulti handle-recipe-event (fn [event recipes] (:event event))
|
|
||||||
:default :unknown-event)
|
|
||||||
|
|
||||||
(defmethod handle-recipe-event :unknown-event [event recipes]
|
|
||||||
recipes)
|
|
||||||
|
|
||||||
(defn new-recipe [id name grubs]
|
(defn new-recipe [id name grubs]
|
||||||
{:id id :name name :grubs grubs})
|
{:id id :name name :grubs grubs})
|
||||||
|
|
||||||
(defmethod handle-recipe-event :add-recipe [event recipes]
|
(defmethod handle-event :add-recipe [event state]
|
||||||
(let [recipe (new-recipe (:id event) (:name event) (:grubs event))]
|
(let [recipe (new-recipe (:id event) (:name event) (:grubs event))]
|
||||||
(assoc recipes (:id recipe) recipe)))
|
(assoc-in state [:recipes (:id recipe)] recipe)))
|
||||||
|
|
||||||
(defmethod handle-recipe-event :add-recipe-list [event recipes]
|
(defmethod handle-event :add-recipe-list [event state]
|
||||||
(->> (:recipes event)
|
(->> (:recipes event)
|
||||||
(map #(new-recipe (:id %) (:name %) (:grubs %)))
|
(map #(new-recipe (:id %) (:name %) (:grubs %)))
|
||||||
(reduce (fn [recipes r] (assoc recipes (:id r) r)) recipes)))
|
(reduce (fn [recipes r] (assoc recipes (:id r) r)) (:recipes state))
|
||||||
|
(assoc state :recipes)))
|
||||||
|
|
||||||
(defmethod handle-recipe-event :update-recipe [event recipes]
|
(defmethod handle-event :update-recipe [event state]
|
||||||
(->> recipes
|
(->> state
|
||||||
(assoc-in [(:id event) :name] (:name event))
|
(assoc-in [:recipes (:id event) :name] (:name event))
|
||||||
(assoc-in [(:id event) :grubs] (:grubs event))))
|
(assoc-in [:recipes (:id event) :grubs] (:grubs event))))
|
||||||
|
|
||||||
(defn update-state-and-render [remote]
|
(defn update-state-and-render [remote]
|
||||||
(go-loop [state default-app-state]
|
(let [out (chan)
|
||||||
(let [event (<! (a/merge [remote view/out]))
|
view-events (view/render-app app-state)]
|
||||||
new-grubs (handle-grub-event event (:grubs state))
|
(go-loop []
|
||||||
new-recipes (handle-recipe-event event (:recipes state))
|
(let [[event ch] (alts! [remote view-events])
|
||||||
new-state (assoc state
|
new-state (handle-event event @app-state)]
|
||||||
:grubs new-grubs
|
(reset! app-state new-state)
|
||||||
:recipes new-recipes)]
|
(when (= ch view-events)
|
||||||
(view/render-app new-state)
|
(>! out event))
|
||||||
(recur new-state)))
|
(recur)))
|
||||||
view/out)
|
out))
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
(:require-macros [grub.macros :refer [log logs]]
|
(:require-macros [grub.macros :refer [log logs]]
|
||||||
[cljs.core.async.macros :refer [go go-loop]]))
|
[cljs.core.async.macros :refer [go go-loop]]))
|
||||||
|
|
||||||
(def add (chan))
|
|
||||||
(def out add)
|
|
||||||
|
|
||||||
(defn recipe-view [recipe owner]
|
(defn recipe-view [recipe owner]
|
||||||
(reify
|
(reify
|
||||||
om/IRender
|
om/IRender
|
||||||
|
@ -76,9 +73,10 @@
|
||||||
[:input.grub-input {:type "text" :value grub}]])))))
|
[:input.grub-input {:type "text" :value grub}]])))))
|
||||||
|
|
||||||
(defn get-grub-ingredient [grub]
|
(defn get-grub-ingredient [grub]
|
||||||
(let [text (clojure.string/lower-case (:grub grub))
|
(when-not (nil? (:grub grub))
|
||||||
match (re-find #"[a-z]{3}.*$" text)]
|
(let [text (clojure.string/lower-case (:grub grub))
|
||||||
match))
|
match (re-find #"[a-z]{3}.*$" text)]
|
||||||
|
match)))
|
||||||
|
|
||||||
(defn sort-grubs [grubs]
|
(defn sort-grubs [grubs]
|
||||||
(sort-by (juxt :completed get-grub-ingredient) (vals grubs)))
|
(sort-by (juxt :completed get-grub-ingredient) (vals grubs)))
|
||||||
|
@ -89,23 +87,35 @@
|
||||||
:grub grub
|
:grub grub
|
||||||
:completed false})
|
:completed false})
|
||||||
|
|
||||||
(defn add-grub [add owner]
|
(defn add-grub [add {:keys [new-grub]} owner]
|
||||||
(let [new-grub (.-value (om/get-node owner :new-grub))]
|
(logs "add-grub:" new-grub)
|
||||||
(when (not (empty? new-grub))
|
(when (not (empty? new-grub))
|
||||||
(put! add (add-grub-event new-grub)))))
|
(let [new-grub-event (add-grub-event new-grub)]
|
||||||
|
(logs "put event:" new-grub-event)
|
||||||
|
(go (>! add new-grub-event))
|
||||||
|
(om/set-state! owner :new-grub ""))
|
||||||
|
;(put! add (add-grub-event new-grub))
|
||||||
|
))
|
||||||
|
|
||||||
(defn enter-pressed? [event]
|
(defn enter-pressed? [event]
|
||||||
(let [enter-keycode 13]
|
(let [enter-keycode 13]
|
||||||
(= (.-which event) enter-keycode)))
|
(= (.-which event) enter-keycode)))
|
||||||
|
|
||||||
(defn add-grub-on-enter [add owner event]
|
(defn add-grub-on-enter [event add state owner]
|
||||||
(when (enter-pressed? event)
|
(when (enter-pressed? event)
|
||||||
(add-grub add owner)))
|
(log "enter pressed:" (:new-grub state))
|
||||||
|
(add-grub add state owner)))
|
||||||
|
|
||||||
|
(defn handle-new-grub-change [e owner {:keys [new-grub]}]
|
||||||
|
(om/set-state! owner :new-grub (.. e -target -value)))
|
||||||
|
|
||||||
(defn grubs-view [grubs owner]
|
(defn grubs-view [grubs owner]
|
||||||
(reify
|
(reify
|
||||||
om/IRender
|
om/IInitState
|
||||||
(render [this]
|
(init-state [_]
|
||||||
|
{:new-grub ""})
|
||||||
|
om/IRenderState
|
||||||
|
(render-state [this state]
|
||||||
(let [add (:add (om/get-shared owner))]
|
(let [add (:add (om/get-shared owner))]
|
||||||
(html
|
(html
|
||||||
[:div
|
[:div
|
||||||
|
@ -116,11 +126,12 @@
|
||||||
{:ref :new-grub
|
{:ref :new-grub
|
||||||
:type "text"
|
:type "text"
|
||||||
:placeholder "2 grubs"
|
:placeholder "2 grubs"
|
||||||
:on-key-up #(add-grub-on-enter add owner %)}]]
|
:on-key-up #(add-grub-on-enter % add state owner)
|
||||||
|
:on-change #(handle-new-grub-change % owner state)}]]
|
||||||
[:button.btn.btn-primary
|
[:button.btn.btn-primary
|
||||||
{:id "add-grub-btn"
|
{:id "add-grub-btn"
|
||||||
:type "button"
|
:type "button"
|
||||||
:on-click #(add-grub add owner)}
|
:on-click #(add-grub (:add (om/get-shared owner)) (:new-grub state) owner)}
|
||||||
"Add"]]
|
"Add"]]
|
||||||
[:ul#grub-list.list-group
|
[:ul#grub-list.list-group
|
||||||
(for [grub (sort-grubs grubs)]
|
(for [grub (sort-grubs grubs)]
|
||||||
|
@ -142,7 +153,10 @@
|
||||||
(om/build recipes-view (:recipes state))]]]))))
|
(om/build recipes-view (:recipes state))]]]))))
|
||||||
|
|
||||||
(defn render-app [state]
|
(defn render-app [state]
|
||||||
(om/root app-view
|
(let [out (chan)
|
||||||
state
|
add out]
|
||||||
{:target (.getElementById js/document "container")
|
(om/root app-view
|
||||||
:shared {:add add}}))
|
state
|
||||||
|
{:target (.getElementById js/document "container")
|
||||||
|
:shared {:add add}})
|
||||||
|
out))
|
||||||
|
|
Loading…
Add table
Reference in a new issue