Remove unused code from before
This commit is contained in:
parent
f11621c501
commit
b1d1f99231
4 changed files with 55 additions and 946 deletions
|
@ -1,300 +1,7 @@
|
|||
(ns grub.view
|
||||
(:require [dommy.core :as dommy]
|
||||
[cljs.core.async :as a :refer [<! >! chan]]
|
||||
[om.core :as om :include-macros true]
|
||||
[om.dom :as dom :include-macros true]
|
||||
(:require [om.core :as om :include-macros true]
|
||||
[sablono.core :as html :refer-macros [html]])
|
||||
(:require-macros [grub.macros :refer [log logs]]
|
||||
[dommy.macros :refer [sel1]]
|
||||
[cljs.core.async.macros :refer [go]]))
|
||||
|
||||
(defn listen
|
||||
([el type] (listen el type nil))
|
||||
([el type f] (listen el type f (chan)))
|
||||
([el type f out]
|
||||
(let [push-fn (fn [e] (when f (f e)) (go (>! out e)))
|
||||
unlisten #(do (dommy/unlisten! el type push-fn)
|
||||
(a/close! out))]
|
||||
(dommy/listen! el type push-fn)
|
||||
{:chan out :unlisten unlisten})))
|
||||
|
||||
(def ENTER-KEYCODE 13)
|
||||
|
||||
(defn listen-once
|
||||
([el type] (listen el type nil))
|
||||
([el type f] (listen el type f (chan)))
|
||||
([el type f out]
|
||||
(let [push-fn (fn [e] (when f (f e)) (go (>! out e)))
|
||||
unlisten #(do (dommy/unlisten! el type push-fn)
|
||||
(a/close! out))]
|
||||
(dommy/listen-once! el type push-fn)
|
||||
{:chan out :unlisten unlisten})))
|
||||
|
||||
(defn get-away-clicks [elem]
|
||||
(let [{c :chan unlisten :unlisten} (listen (sel1 :body) :click)
|
||||
filtered-chan (a/filter< #(not (dommy/descendant? (.-target %) elem)) c)]
|
||||
{:unlisten unlisten :chan filtered-chan}))
|
||||
|
||||
(defn get-clicks [elem]
|
||||
(listen elem :click))
|
||||
|
||||
(defn get-enters [elem]
|
||||
(let [{c :chan unlisten :unlisten} (listen elem :keyup)
|
||||
filtered-chan (a/filter< #(= (.-which %) ENTER-KEYCODE) c)]
|
||||
{:unlisten unlisten
|
||||
:chan filtered-chan}))
|
||||
|
||||
(defn get-ctrl-enters []
|
||||
(let [{c :chan unlisten :unlisten} (listen (sel1 :body) :keyup)
|
||||
filtered-chan (a/filter< #(and (= (.-which %) ENTER-KEYCODE)
|
||||
(.-ctrlKey %))
|
||||
c)]
|
||||
{:chan filtered-chan :unlisten unlisten}))
|
||||
|
||||
(defn get-body-enters []
|
||||
(get-enters (sel1 :body)))
|
||||
|
||||
(def add-grub-btn
|
||||
[:button.btn.btn-primary {:id "add-grub-btn" :type "button"} "Add"])
|
||||
|
||||
(def clear-all-btn
|
||||
[:button.btn.hidden.pull-right
|
||||
{:id "clear-all-btn" :type "button"}
|
||||
"Clear all"])
|
||||
|
||||
(defn clear-grubs! []
|
||||
(dommy/set-html! (sel1 :#grub-list) ""))
|
||||
|
||||
(defn get-grub-completed-glyph [completed]
|
||||
(if completed
|
||||
[:span.glyphicon.glyphicon-check]
|
||||
[:span.glyphicon.glyphicon-unchecked]))
|
||||
|
||||
(defn make-grub-node [id grub completed]
|
||||
[:li.list-group-item.grub-item
|
||||
{:id id
|
||||
:class (when completed "completed")}
|
||||
[:span.grub-static
|
||||
(get-grub-completed-glyph completed)
|
||||
[:span.grub-text grub]]
|
||||
[:input.grub-input {:type "text" :value grub}]])
|
||||
|
||||
(defn grubs-selector []
|
||||
[(sel1 :#grub-list) :.grub-item])
|
||||
|
||||
(defn make-recipe-node
|
||||
([id name grubs] (make-recipe-node id name grubs false))
|
||||
([id name grubs new-recipe]
|
||||
[:div.panel.panel-default.recipe-panel
|
||||
{:id id}
|
||||
[:div.panel-heading.recipe-header
|
||||
[:input.form-control.recipe-header-input
|
||||
{:id "recipe-name"
|
||||
:type "text"
|
||||
:placeholder "Grub pie"
|
||||
:value name}]
|
||||
(when-not new-recipe
|
||||
[:button.btn.btn-primary.btn-sm.recipe-add-grubs-btn {:type "button"} "Add Grubs"])]
|
||||
[:div.panel-body.recipe-grubs.hidden
|
||||
[:textarea.form-control.recipe-grubs-input
|
||||
{:id "recipe-grubs"
|
||||
:rows 3
|
||||
:placeholder "2 grubs"}
|
||||
grubs]
|
||||
[:button.btn.btn-primary.hidden.pull-right.recipe-btn.recipe-done-btn
|
||||
{:type "button"} "Done"]]]))
|
||||
|
||||
(def new-recipe (make-recipe-node "new-recipe" "" "" true))
|
||||
|
||||
(def new-recipe-done-btn
|
||||
(sel1 new-recipe ".recipe-done-btn"))
|
||||
|
||||
(defn recipes-selector []
|
||||
[(sel1 :#recipe-list) :.recipe-panel])
|
||||
|
||||
(defn recipe-done-btns-selector []
|
||||
[(sel1 :body) :.recipe-done-btn])
|
||||
|
||||
(defn recipe-done-btn-selector [recipe-elem]
|
||||
(sel1 recipe-elem :.recipe-done-btn))
|
||||
|
||||
(defn recipe-add-grubs-btns-selector []
|
||||
[(sel1 :body) :.recipe-add-grubs-btn])
|
||||
|
||||
(defn grub-list-template [grubs]
|
||||
(for [grub grubs]
|
||||
(make-grub-node (:id grub) (:grub grub) (:completed grub))))
|
||||
|
||||
(defn render-grub-list [grubs]
|
||||
(let [grub-list (sel1 :#grub-list)]
|
||||
(aset grub-list "innerHTML" "")
|
||||
(dommy/replace-contents! grub-list (grub-list-template grubs))))
|
||||
|
||||
(defn get-add-grub-text []
|
||||
(dommy/value (sel1 :#add-grub-input)))
|
||||
|
||||
(defn clear-add-grub-text []
|
||||
(dommy/set-value! (sel1 :#add-grub-input) ""))
|
||||
|
||||
(defn get-recipe-add-grubs-clicks []
|
||||
(->> (:chan (listen (recipe-add-grubs-btns-selector) :click))
|
||||
(a/map< #(dommy/closest (.-selectedTarget %) :.recipe-panel))))
|
||||
|
||||
(defn get-edit-recipe-input-click []
|
||||
(->> (:chan (listen-once (recipes-selector) :click))
|
||||
(a/filter< #(not (dommy/has-class? (.-selectedTarget %) :btn)))
|
||||
(a/map< #(.-selectedTarget %))))
|
||||
|
||||
(defprotocol IHideable
|
||||
(-hide! [this])
|
||||
(-show! [this]))
|
||||
|
||||
(defprotocol IGrub
|
||||
(-activate! [this])
|
||||
(-deactivate! [this])
|
||||
|
||||
(-id [this])
|
||||
(-grub-text [this])
|
||||
|
||||
(-complete! [this])
|
||||
(-uncomplete! [this])
|
||||
(-completed? [this])
|
||||
|
||||
(-set-editing! [this])
|
||||
(-unset-editing! [this])
|
||||
(-editing? [this])
|
||||
(-update-grub! [this grub]))
|
||||
|
||||
(defprotocol IRecipe
|
||||
(-expand! [this])
|
||||
(-unexpand! [this])
|
||||
|
||||
(-update-recipe! [this])
|
||||
|
||||
(-get-name [this])
|
||||
(-get-grubs-str [this])
|
||||
(-get-grubs [this]))
|
||||
|
||||
(defprotocol IClearable
|
||||
(-clear! [this]))
|
||||
|
||||
(extend-type js/HTMLElement
|
||||
IHideable
|
||||
(-hide! [this]
|
||||
(dommy/add-class! this :hidden))
|
||||
(-show! [this]
|
||||
(dommy/remove-class! this :hidden)))
|
||||
|
||||
|
||||
(extend-type js/HTMLElement
|
||||
IGrub
|
||||
(-activate! [this]
|
||||
(dommy/add-class! this :grub-active))
|
||||
(-deactivate! [this]
|
||||
(dommy/remove-class! this :grub-active))
|
||||
|
||||
(-id [this]
|
||||
(.-id this))
|
||||
(-grub-text [this]
|
||||
(.-value (sel1 this :.grub-input)))
|
||||
|
||||
(-complete! [this]
|
||||
(dommy/add-class! this :completed)
|
||||
(dommy/replace! (sel1 this ".glyphicon")
|
||||
(get-grub-completed-glyph true)))
|
||||
(-uncomplete! [this]
|
||||
(dommy/remove-class! this :completed)
|
||||
(dommy/replace! (sel1 this ".glyphicon")
|
||||
(get-grub-completed-glyph false)))
|
||||
(-completed? [this]
|
||||
(dommy/has-class? this :completed))
|
||||
|
||||
(-set-editing! [this]
|
||||
(-deactivate! this)
|
||||
(dommy/add-class! this :edit)
|
||||
(.focus (sel1 this :input)))
|
||||
(-unset-editing! [this]
|
||||
(dommy/remove-class! this :edit))
|
||||
(-editing? [this]
|
||||
(dommy/has-class? this :edit)))
|
||||
|
||||
(defrecord Grub [elem id grub completed]
|
||||
dommy.template/PElement
|
||||
(-elem [this] elem)
|
||||
|
||||
IGrub
|
||||
(-set-editing! [this] (-set-editing! elem))
|
||||
(-unset-editing! [this] (-unset-editing! elem))
|
||||
(-editing? [this] (-editing? elem))
|
||||
|
||||
(-complete! [this] (-complete! elem))
|
||||
(-uncomplete! [this] (-uncomplete! elem))
|
||||
(-completed? [this] (-completed? elem))
|
||||
|
||||
(-set-editing! [this] (-set-editing! elem))
|
||||
(-unset-editing! [this] (-unset-editing! elem))
|
||||
(-editing? [this] (-editing? elem))
|
||||
|
||||
(-update-grub! [this grub]
|
||||
(dommy/set-text! (sel1 elem ".grub-text") grub)
|
||||
(dommy/set-value! (sel1 elem ".grub-input") grub)))
|
||||
|
||||
(defn make-new-grub [id grub completed]
|
||||
(let [node (make-grub-node id grub completed)
|
||||
grub (Grub. node id grub completed)
|
||||
grub-list (sel1 :#grub-list)]
|
||||
grub))
|
||||
|
||||
(defn clear-new-grub-input! []
|
||||
(dommy/set-value! (sel1 :#add-grub-input) ""))
|
||||
|
||||
(defn focus-new-grub-input! []
|
||||
(.focus (sel1 :#add-grub-input)))
|
||||
|
||||
(extend-type js/HTMLDivElement
|
||||
IRecipe
|
||||
(-expand! [this]
|
||||
(dommy/remove-class! (sel1 this ".recipe-grubs") :hidden)
|
||||
(dommy/remove-class! (sel1 this ".recipe-done-btn") :hidden))
|
||||
(-unexpand! [this]
|
||||
(dommy/add-class! (sel1 this ".recipe-grubs") :hidden)
|
||||
(dommy/add-class! (sel1 this ".recipe-done-btn") :hidden))
|
||||
|
||||
(-get-name [this]
|
||||
(dommy/value (sel1 this :#recipe-name)))
|
||||
(-get-grubs-str [this]
|
||||
(dommy/value (sel1 this :#recipe-grubs)))
|
||||
(-get-grubs [this]
|
||||
(let [split-grubs (clojure.string/split-lines (-get-grubs-str this))]
|
||||
(when split-grubs (into [] split-grubs)))))
|
||||
|
||||
|
||||
(extend-type js/HTMLDivElement
|
||||
IClearable
|
||||
(-clear! [this]
|
||||
(dommy/set-value! (sel1 this "#recipe-name") "")
|
||||
(dommy/set-value! (sel1 this "#recipe-grubs") "")))
|
||||
|
||||
(defrecord Recipe [elem id name grubs]
|
||||
dommy.template/PElement
|
||||
(-elem [this] elem)
|
||||
|
||||
IRecipe
|
||||
(-expand! [this] (-expand! elem))
|
||||
(-unexpand! [this] (-unexpand! elem))
|
||||
|
||||
(-clear! [this] (-clear! elem))
|
||||
|
||||
(-update-recipe! [this]
|
||||
(dommy/set-value! (sel1 this :#recipe-name) name)
|
||||
(dommy/set-text! (sel1 this :#recipe-grubs) grubs)))
|
||||
|
||||
(defn add-new-recipe! [id name grubs]
|
||||
(let [node (make-recipe-node id name grubs)
|
||||
recipe (Recipe. node id name grubs)
|
||||
recipe-list (sel1 :#recipe-list)]
|
||||
(dommy/append! recipe-list recipe)
|
||||
recipe))
|
||||
(:require-macros [grub.macros :refer [log logs]]))
|
||||
|
||||
(defn recipe-view [recipe owner]
|
||||
(reify
|
||||
|
@ -323,6 +30,31 @@
|
|||
[:button.btn.btn-primary.hidden.pull-right.recipe-btn.recipe-done-btn
|
||||
{:type "button"} "Done"]]])))))
|
||||
|
||||
(defn recipes-view [recipes owner]
|
||||
(reify
|
||||
om/IRender
|
||||
(render [this]
|
||||
(html
|
||||
[:div
|
||||
[:h3.recipes-title "Recipes"]
|
||||
[:div.panel.panel-default.recipe-panel
|
||||
[:div.panel-heading.recipe-header
|
||||
[:input.form-control.recipe-header-input
|
||||
{:id "recipe-name"
|
||||
:type "text"
|
||||
:placeholder "Grub pie"}]
|
||||
[:button.btn.btn-primary.btn-sm.recipe-add-grubs-btn {:type "button"} "Add Grubs"]]
|
||||
[:div.panel-body.recipe-grubs.hidden
|
||||
[:textarea.form-control.recipe-grubs-input
|
||||
{:id "recipe-grubs"
|
||||
:rows 3
|
||||
:placeholder "2 grubs"}]
|
||||
[:button.btn.btn-primary.hidden.pull-right.recipe-btn.recipe-done-btn
|
||||
{:type "button"} "Done"]]]
|
||||
[:ul#recipe-list.list-group.recipe-list
|
||||
(for [recipe (vals recipes)]
|
||||
(om/build recipe-view recipe))]]))))
|
||||
|
||||
(defn grub-view [grub-state owner]
|
||||
(reify
|
||||
om/IRender
|
||||
|
@ -333,7 +65,9 @@
|
|||
{:id id
|
||||
:class (when completed "completed")}
|
||||
[:span.grub-static
|
||||
(get-grub-completed-glyph completed)
|
||||
(if completed
|
||||
[:span.glyphicon.glyphicon-check]
|
||||
[:span.glyphicon.glyphicon-unchecked])
|
||||
[:span.grub-text grub]]
|
||||
[:input.grub-input {:type "text" :value grub}]])))))
|
||||
|
||||
|
@ -345,46 +79,35 @@
|
|||
(defn sort-grubs [grubs]
|
||||
(sort-by (juxt :completed get-grub-ingredient) (vals grubs)))
|
||||
|
||||
(defn grubs-view [grubs owner]
|
||||
(reify
|
||||
om/IRender
|
||||
(render [this]
|
||||
(html
|
||||
[:div
|
||||
[:h3 "Grub List"]
|
||||
[:div.input-group.add-grub-input-form
|
||||
[:span.input-group-btn
|
||||
[:input.form-control#add-grub-input {:type "text" :placeholder "2 grubs"}]]
|
||||
[:button.btn.btn-primary {:id "add-grub-btn" :type "button"} "Add"]]
|
||||
[:ul#grub-list.list-group
|
||||
(for [grub (sort-grubs grubs)]
|
||||
(om/build grub-view grub))]
|
||||
[:button.btn.hidden.pull-right
|
||||
{:id "clear-all-btn" :type "button"}
|
||||
"Clear all"]]))))
|
||||
|
||||
(defn app-view [state owner]
|
||||
(reify
|
||||
om/IRender
|
||||
(render [this]
|
||||
(let [sorted-grubs (sort-grubs (:grubs state))]
|
||||
(html
|
||||
[:div.container
|
||||
[:div.row
|
||||
[:div.col-sm-6.leftmost-column
|
||||
[:h3 "Grub List"]
|
||||
[:div.input-group.add-grub-input-form
|
||||
[:span.input-group-btn
|
||||
[:input.form-control#add-grub-input {:type "text" :placeholder "2 grubs"}]]
|
||||
[:button.btn.btn-primary {:id "add-grub-btn" :type "button"} "Add"]]
|
||||
[:ul#grub-list.list-group
|
||||
(for [grub (vals (:grubs state))]
|
||||
(om/build grub-view grub))]
|
||||
[:button.btn.hidden.pull-right
|
||||
{:id "clear-all-btn" :type "button"}
|
||||
"Clear all"]]
|
||||
[:div.col-sm-6
|
||||
[:h3.recipes-title "Recipes"]
|
||||
[:div.panel.panel-default.recipe-panel
|
||||
[:div.panel-heading.recipe-header
|
||||
[:input.form-control.recipe-header-input
|
||||
{:id "recipe-name"
|
||||
:type "text"
|
||||
:placeholder "Grub pie"}]
|
||||
[:button.btn.btn-primary.btn-sm.recipe-add-grubs-btn {:type "button"} "Add Grubs"]]
|
||||
[:div.panel-body.recipe-grubs.hidden
|
||||
[:textarea.form-control.recipe-grubs-input
|
||||
{:id "recipe-grubs"
|
||||
:rows 3
|
||||
:placeholder "2 grubs"}]
|
||||
[:button.btn.btn-primary.hidden.pull-right.recipe-btn.recipe-done-btn
|
||||
{:type "button"} "Done"]]]
|
||||
[:ul#recipe-list.list-group.recipe-list
|
||||
(for [recipe (vals (:recipes state))]
|
||||
(om/build recipe-view recipe))]]]])))))
|
||||
(html
|
||||
[:div.container
|
||||
[:div.row
|
||||
[:div.col-sm-6.leftmost-column
|
||||
(om/build grubs-view (:grubs state))]
|
||||
[:div.col-sm-6
|
||||
(om/build recipes-view (:recipes state))]]]))))
|
||||
|
||||
(defn render-app [state]
|
||||
(logs state)
|
||||
(om/root app-view state {:target (.getElementById js/document "container")}))
|
||||
|
|
|
@ -1,334 +0,0 @@
|
|||
(ns grub.view.dom
|
||||
(:require [dommy.core :as dommy]
|
||||
[cljs.core.async :as a :refer [<! >! chan]]
|
||||
[om.core :as om :include-macros true]
|
||||
[om.dom :as dom :include-macros true]
|
||||
[sablono.core :as html :refer-macros [html]])
|
||||
(:require-macros [grub.macros :refer [log logs]]
|
||||
[dommy.macros :refer [sel1]]
|
||||
[cljs.core.async.macros :refer [go]]))
|
||||
|
||||
(defn listen
|
||||
([el type] (listen el type nil))
|
||||
([el type f] (listen el type f (chan)))
|
||||
([el type f out]
|
||||
(let [push-fn (fn [e] (when f (f e)) (go (>! out e)))
|
||||
unlisten #(do (dommy/unlisten! el type push-fn)
|
||||
(a/close! out))]
|
||||
(dommy/listen! el type push-fn)
|
||||
{:chan out :unlisten unlisten})))
|
||||
|
||||
(def ENTER-KEYCODE 13)
|
||||
|
||||
(defn listen-once
|
||||
([el type] (listen el type nil))
|
||||
([el type f] (listen el type f (chan)))
|
||||
([el type f out]
|
||||
(let [push-fn (fn [e] (when f (f e)) (go (>! out e)))
|
||||
unlisten #(do (dommy/unlisten! el type push-fn)
|
||||
(a/close! out))]
|
||||
(dommy/listen-once! el type push-fn)
|
||||
{:chan out :unlisten unlisten})))
|
||||
|
||||
(defn get-away-clicks [elem]
|
||||
(let [{c :chan unlisten :unlisten} (listen (sel1 :body) :click)
|
||||
filtered-chan (a/filter< #(not (dommy/descendant? (.-target %) elem)) c)]
|
||||
{:unlisten unlisten :chan filtered-chan}))
|
||||
|
||||
(defn get-clicks [elem]
|
||||
(listen elem :click))
|
||||
|
||||
(defn get-enters [elem]
|
||||
(let [{c :chan unlisten :unlisten} (listen elem :keyup)
|
||||
filtered-chan (a/filter< #(= (.-which %) ENTER-KEYCODE) c)]
|
||||
{:unlisten unlisten
|
||||
:chan filtered-chan}))
|
||||
|
||||
(defn get-ctrl-enters []
|
||||
(let [{c :chan unlisten :unlisten} (listen (sel1 :body) :keyup)
|
||||
filtered-chan (a/filter< #(and (= (.-which %) ENTER-KEYCODE)
|
||||
(.-ctrlKey %))
|
||||
c)]
|
||||
{:chan filtered-chan :unlisten unlisten}))
|
||||
|
||||
(defn get-body-enters []
|
||||
(get-enters (sel1 :body)))
|
||||
|
||||
(def add-grub-btn
|
||||
[:button.btn.btn-primary {:id "add-grub-btn" :type "button"} "Add"])
|
||||
|
||||
(def clear-all-btn
|
||||
[:button.btn.hidden.pull-right
|
||||
{:id "clear-all-btn" :type "button"}
|
||||
"Clear all"])
|
||||
|
||||
(defn clear-grubs! []
|
||||
(dommy/set-html! (sel1 :#grub-list) ""))
|
||||
|
||||
(defn get-grub-completed-glyph [completed]
|
||||
(if completed
|
||||
[:span.glyphicon.glyphicon-check]
|
||||
[:span.glyphicon.glyphicon-unchecked]))
|
||||
|
||||
(defn make-grub-node [id grub completed]
|
||||
[:li.list-group-item.grub-item
|
||||
{:id id
|
||||
:class (when completed "completed")}
|
||||
[:span.grub-static
|
||||
(get-grub-completed-glyph completed)
|
||||
[:span.grub-text grub]]
|
||||
[:input.grub-input {:type "text" :value grub}]])
|
||||
|
||||
(defn grubs-selector []
|
||||
[(sel1 :#grub-list) :.grub-item])
|
||||
|
||||
(defn make-recipe-node
|
||||
([id name grubs] (make-recipe-node id name grubs false))
|
||||
([id name grubs new-recipe]
|
||||
[:div.panel.panel-default.recipe-panel
|
||||
{:id id}
|
||||
[:div.panel-heading.recipe-header
|
||||
[:input.form-control.recipe-header-input
|
||||
{:id "recipe-name"
|
||||
:type "text"
|
||||
:placeholder "Grub pie"
|
||||
:value name}]
|
||||
(when-not new-recipe
|
||||
[:button.btn.btn-primary.btn-sm.recipe-add-grubs-btn {:type "button"} "Add Grubs"])]
|
||||
[:div.panel-body.recipe-grubs.hidden
|
||||
[:textarea.form-control.recipe-grubs-input
|
||||
{:id "recipe-grubs"
|
||||
:rows 3
|
||||
:placeholder "2 grubs"}
|
||||
grubs]
|
||||
[:button.btn.btn-primary.hidden.pull-right.recipe-btn.recipe-done-btn
|
||||
{:type "button"} "Done"]]]))
|
||||
|
||||
(def new-recipe (make-recipe-node "new-recipe" "" "" true))
|
||||
|
||||
(def new-recipe-done-btn
|
||||
(sel1 new-recipe ".recipe-done-btn"))
|
||||
|
||||
(defn recipes-selector []
|
||||
[(sel1 :#recipe-list) :.recipe-panel])
|
||||
|
||||
(defn recipe-done-btns-selector []
|
||||
[(sel1 :body) :.recipe-done-btn])
|
||||
|
||||
(defn recipe-done-btn-selector [recipe-elem]
|
||||
(sel1 recipe-elem :.recipe-done-btn))
|
||||
|
||||
(defn recipe-add-grubs-btns-selector []
|
||||
[(sel1 :body) :.recipe-add-grubs-btn])
|
||||
|
||||
(defn grub-list-template [grubs]
|
||||
(for [grub grubs]
|
||||
(make-grub-node (:id grub) (:grub grub) (:completed grub))))
|
||||
|
||||
(defn render-grub-list [grubs]
|
||||
(let [grub-list (sel1 :#grub-list)]
|
||||
(aset grub-list "innerHTML" "")
|
||||
(dommy/replace-contents! grub-list (grub-list-template grubs))))
|
||||
|
||||
(defn get-add-grub-text []
|
||||
(dommy/value (sel1 :#add-grub-input)))
|
||||
|
||||
(defn clear-add-grub-text []
|
||||
(dommy/set-value! (sel1 :#add-grub-input) ""))
|
||||
|
||||
(defn get-recipe-add-grubs-clicks []
|
||||
(->> (:chan (listen (recipe-add-grubs-btns-selector) :click))
|
||||
(a/map< #(dommy/closest (.-selectedTarget %) :.recipe-panel))))
|
||||
|
||||
(defn get-edit-recipe-input-click []
|
||||
(->> (:chan (listen-once (recipes-selector) :click))
|
||||
(a/filter< #(not (dommy/has-class? (.-selectedTarget %) :btn)))
|
||||
(a/map< #(.-selectedTarget %))))
|
||||
|
||||
(defprotocol IHideable
|
||||
(-hide! [this])
|
||||
(-show! [this]))
|
||||
|
||||
(defprotocol IGrub
|
||||
(-activate! [this])
|
||||
(-deactivate! [this])
|
||||
|
||||
(-id [this])
|
||||
(-grub-text [this])
|
||||
|
||||
(-complete! [this])
|
||||
(-uncomplete! [this])
|
||||
(-completed? [this])
|
||||
|
||||
(-set-editing! [this])
|
||||
(-unset-editing! [this])
|
||||
(-editing? [this])
|
||||
(-update-grub! [this grub]))
|
||||
|
||||
(defprotocol IRecipe
|
||||
(-expand! [this])
|
||||
(-unexpand! [this])
|
||||
|
||||
(-update-recipe! [this])
|
||||
|
||||
(-get-name [this])
|
||||
(-get-grubs-str [this])
|
||||
(-get-grubs [this]))
|
||||
|
||||
(defprotocol IClearable
|
||||
(-clear! [this]))
|
||||
|
||||
(extend-type js/HTMLElement
|
||||
IHideable
|
||||
(-hide! [this]
|
||||
(dommy/add-class! this :hidden))
|
||||
(-show! [this]
|
||||
(dommy/remove-class! this :hidden)))
|
||||
|
||||
|
||||
(extend-type js/HTMLElement
|
||||
IGrub
|
||||
(-activate! [this]
|
||||
(dommy/add-class! this :grub-active))
|
||||
(-deactivate! [this]
|
||||
(dommy/remove-class! this :grub-active))
|
||||
|
||||
(-id [this]
|
||||
(.-id this))
|
||||
(-grub-text [this]
|
||||
(.-value (sel1 this :.grub-input)))
|
||||
|
||||
(-complete! [this]
|
||||
(dommy/add-class! this :completed)
|
||||
(dommy/replace! (sel1 this ".glyphicon")
|
||||
(get-grub-completed-glyph true)))
|
||||
(-uncomplete! [this]
|
||||
(dommy/remove-class! this :completed)
|
||||
(dommy/replace! (sel1 this ".glyphicon")
|
||||
(get-grub-completed-glyph false)))
|
||||
(-completed? [this]
|
||||
(dommy/has-class? this :completed))
|
||||
|
||||
(-set-editing! [this]
|
||||
(-deactivate! this)
|
||||
(dommy/add-class! this :edit)
|
||||
(.focus (sel1 this :input)))
|
||||
(-unset-editing! [this]
|
||||
(dommy/remove-class! this :edit))
|
||||
(-editing? [this]
|
||||
(dommy/has-class? this :edit)))
|
||||
|
||||
(defrecord Grub [elem id grub completed]
|
||||
dommy.template/PElement
|
||||
(-elem [this] elem)
|
||||
|
||||
IGrub
|
||||
(-set-editing! [this] (-set-editing! elem))
|
||||
(-unset-editing! [this] (-unset-editing! elem))
|
||||
(-editing? [this] (-editing? elem))
|
||||
|
||||
(-complete! [this] (-complete! elem))
|
||||
(-uncomplete! [this] (-uncomplete! elem))
|
||||
(-completed? [this] (-completed? elem))
|
||||
|
||||
(-set-editing! [this] (-set-editing! elem))
|
||||
(-unset-editing! [this] (-unset-editing! elem))
|
||||
(-editing? [this] (-editing? elem))
|
||||
|
||||
(-update-grub! [this grub]
|
||||
(dommy/set-text! (sel1 elem ".grub-text") grub)
|
||||
(dommy/set-value! (sel1 elem ".grub-input") grub)))
|
||||
|
||||
(defn make-new-grub [id grub completed]
|
||||
(let [node (make-grub-node id grub completed)
|
||||
grub (Grub. node id grub completed)
|
||||
grub-list (sel1 :#grub-list)]
|
||||
grub))
|
||||
|
||||
(defn clear-new-grub-input! []
|
||||
(dommy/set-value! (sel1 :#add-grub-input) ""))
|
||||
|
||||
(defn focus-new-grub-input! []
|
||||
(.focus (sel1 :#add-grub-input)))
|
||||
|
||||
(extend-type js/HTMLDivElement
|
||||
IRecipe
|
||||
(-expand! [this]
|
||||
(dommy/remove-class! (sel1 this ".recipe-grubs") :hidden)
|
||||
(dommy/remove-class! (sel1 this ".recipe-done-btn") :hidden))
|
||||
(-unexpand! [this]
|
||||
(dommy/add-class! (sel1 this ".recipe-grubs") :hidden)
|
||||
(dommy/add-class! (sel1 this ".recipe-done-btn") :hidden))
|
||||
|
||||
(-get-name [this]
|
||||
(dommy/value (sel1 this :#recipe-name)))
|
||||
(-get-grubs-str [this]
|
||||
(dommy/value (sel1 this :#recipe-grubs)))
|
||||
(-get-grubs [this]
|
||||
(let [split-grubs (clojure.string/split-lines (-get-grubs-str this))]
|
||||
(when split-grubs (into [] split-grubs)))))
|
||||
|
||||
|
||||
(extend-type js/HTMLDivElement
|
||||
IClearable
|
||||
(-clear! [this]
|
||||
(dommy/set-value! (sel1 this "#recipe-name") "")
|
||||
(dommy/set-value! (sel1 this "#recipe-grubs") "")))
|
||||
|
||||
(defrecord Recipe [elem id name grubs]
|
||||
dommy.template/PElement
|
||||
(-elem [this] elem)
|
||||
|
||||
IRecipe
|
||||
(-expand! [this] (-expand! elem))
|
||||
(-unexpand! [this] (-unexpand! elem))
|
||||
|
||||
(-clear! [this] (-clear! elem))
|
||||
|
||||
(-update-recipe! [this]
|
||||
(dommy/set-value! (sel1 this :#recipe-name) name)
|
||||
(dommy/set-text! (sel1 this :#recipe-grubs) grubs)))
|
||||
|
||||
(defn add-new-recipe! [id name grubs]
|
||||
(let [node (make-recipe-node id name grubs)
|
||||
recipe (Recipe. node id name grubs)
|
||||
recipe-list (sel1 :#recipe-list)]
|
||||
(dommy/append! recipe-list recipe)
|
||||
recipe))
|
||||
|
||||
(defn grub-view []
|
||||
(om/component
|
||||
(html
|
||||
[:div.container
|
||||
[:div.row
|
||||
[:div.col-sm-6.leftmost-column
|
||||
[:h3 "Grub List"]
|
||||
[:div.input-group.add-grub-input-form
|
||||
[:span.input-group-btn
|
||||
[:input.form-control#add-grub-input {:type "text" :placeholder "2 grubs"}]]
|
||||
[:button.btn.btn-primary {:id "add-grub-btn" :type "button"} "Add"]]
|
||||
[:ul#grub-list.list-group]
|
||||
[:button.btn.hidden.pull-right
|
||||
{:id "clear-all-btn" :type "button"}
|
||||
"Clear all"]]
|
||||
[:div.col-sm-6
|
||||
[:h3.recipes-title "Recipes"]
|
||||
[:div.panel.panel-default.recipe-panel
|
||||
[:div.panel-heading.recipe-header
|
||||
[:input.form-control.recipe-header-input
|
||||
{:id "recipe-name"
|
||||
:type "text"
|
||||
:placeholder "Grub pie"}]
|
||||
[:button.btn.btn-primary.btn-sm.recipe-add-grubs-btn {:type "button"} "Add Grubs"]]
|
||||
[:div.panel-body.recipe-grubs.hidden
|
||||
[:textarea.form-control.recipe-grubs-input
|
||||
{:id "recipe-grubs"
|
||||
:rows 3
|
||||
:placeholder "2 grubs"}]
|
||||
[:button.btn.btn-primary.hidden.pull-right.recipe-btn.recipe-done-btn
|
||||
{:type "button"} "Done"]]]
|
||||
[:ul#recipe-list.list-group.recipe-list]]]])))
|
||||
|
||||
(defn render-body [state]
|
||||
(logs state)
|
||||
(om/root grub-view state {:target (.getElementById js/document "container")}))
|
|
@ -1,129 +0,0 @@
|
|||
(ns grub.view.grub
|
||||
(:require [grub.view.dom :as dom]
|
||||
[cljs.core.async :as a :refer [<! >! chan]])
|
||||
(:require-macros [grub.macros :refer [log logs and-let]]
|
||||
[cljs.core.async.macros :refer [go go-loop]]
|
||||
[dommy.macros :refer [sel1]]))
|
||||
|
||||
(defn get-add-grub-clicks []
|
||||
(:chan (dom/get-clicks (sel1 :#add-grub-btn))))
|
||||
|
||||
(defn get-add-grub-enters []
|
||||
(:chan (dom/get-enters (sel1 :#add-grub-input))))
|
||||
|
||||
(defn get-create-events []
|
||||
(let [events (a/merge [(get-add-grub-clicks)
|
||||
(get-add-grub-enters)])]
|
||||
(->> events
|
||||
(a/map< #(dom/get-add-grub-text))
|
||||
(a/filter< #(not (empty? %)))
|
||||
(a/map< (fn [g]
|
||||
{:event :add-grub
|
||||
:id (str "grub-" (.now js/Date))
|
||||
:grub g
|
||||
:completed false})))))
|
||||
|
||||
(defn parse-complete-event [elem]
|
||||
(let [id (.-id elem)
|
||||
completed (dom/-completed? elem)
|
||||
event-type (if completed :uncomplete-grub :complete-grub)]
|
||||
{:id id
|
||||
:event event-type}))
|
||||
|
||||
(defn get-complete-events []
|
||||
(->> (:chan (dom/listen (dom/grubs-selector) :click))
|
||||
(a/map< #(.-selectedTarget %))
|
||||
(a/filter< #(not (dom/-editing? %)))
|
||||
(a/map< parse-complete-event)))
|
||||
|
||||
(defn get-clear-all-events []
|
||||
(->> (:chan (dom/listen (sel1 :#clear-all-btn) :click))
|
||||
(a/map< (fn [e] {:event :clear-all-grubs}))))
|
||||
|
||||
(defn get-grub-mousedown-events []
|
||||
(let [{c :chan unlisten :unlisten} (dom/listen (dom/grubs-selector) :mousedown)]
|
||||
{:unlisten unlisten
|
||||
:chan (a/map< (fn [e] {:selected-grub (.-selectedTarget e)}) c)}))
|
||||
|
||||
(defn get-grub-mouseup-events [grub-elem]
|
||||
(dom/listen grub-elem :mouseup))
|
||||
|
||||
(defn get-grub-mouseleave-events [grub-elem]
|
||||
(dom/listen grub-elem :mouseleave))
|
||||
|
||||
(defn wait-for-mousedown-on-grub []
|
||||
(let [out (chan)]
|
||||
(go (let [{mousedown :chan unlisten :unlisten} (get-grub-mousedown-events)
|
||||
event (<! mousedown)
|
||||
selected-grub (:selected-grub event)]
|
||||
(unlisten)
|
||||
(>! out selected-grub)))
|
||||
out))
|
||||
|
||||
(defn wait-for-grub-mousedown-timeout [grub]
|
||||
(let [out (chan)]
|
||||
(dom/-activate! grub)
|
||||
(go (let [{mouseup :chan
|
||||
unlisten-mouseup :unlisten} (get-grub-mouseup-events grub)
|
||||
{mouseleave :chan
|
||||
unlisten-mouseleave :unlisten } (get-grub-mouseleave-events grub)
|
||||
timeout (a/timeout 500)
|
||||
[_ c] (a/alts! [mouseup mouseleave timeout])]
|
||||
(unlisten-mouseleave)
|
||||
(unlisten-mouseup)
|
||||
(dom/-deactivate! grub)
|
||||
(>! out (= c timeout))))
|
||||
out))
|
||||
|
||||
(defn make-grub-update-event [grub-elem orig-grub-text]
|
||||
(let [grub-text (dom/-grub-text grub-elem)
|
||||
id (dom/-id grub-elem)]
|
||||
(when (not (= grub-text orig-grub-text))
|
||||
{:event :update-grub
|
||||
:grub grub-text
|
||||
:id id})))
|
||||
|
||||
(defn wait-for-update-event [grub]
|
||||
(let [out (chan)
|
||||
orig-grub (dom/-grub-text grub)]
|
||||
(go (let [{bodyclick :chan
|
||||
unlisten-bodyclick :unlisten} (dom/get-away-clicks grub)
|
||||
{enter :chan
|
||||
unlisten-enter :unlisten} (dom/get-body-enters)]
|
||||
(dom/-set-editing! grub)
|
||||
(a/alts! [bodyclick enter])
|
||||
(unlisten-bodyclick)
|
||||
(unlisten-enter)
|
||||
(dom/-unset-editing! grub)
|
||||
(if-let [update-event (make-grub-update-event grub orig-grub)]
|
||||
(>! out update-event)
|
||||
(a/close! out))))
|
||||
out))
|
||||
|
||||
(defn get-update-events []
|
||||
(let [out (chan)]
|
||||
(go-loop []
|
||||
(and-let [grub (<! (wait-for-mousedown-on-grub))
|
||||
timeout? (<! (wait-for-grub-mousedown-timeout grub))
|
||||
update-event (<! (wait-for-update-event grub))]
|
||||
(>! out update-event))
|
||||
(recur))
|
||||
out))
|
||||
|
||||
(defn get-grub-with-index [grubs id]
|
||||
(let [grub-index (->> grubs
|
||||
(map-indexed vector)
|
||||
(filter #(= (:id (second %)) id))
|
||||
(first)
|
||||
(first))
|
||||
grub (grubs grub-index)]
|
||||
[grub-index grub]))
|
||||
|
||||
(defn get-grub-ingredient [grub]
|
||||
(let [text (clojure.string/lower-case (:grub grub))
|
||||
match (re-find #"[a-z]{3}.*$" text)]
|
||||
match))
|
||||
|
||||
(defn sort-and-render-grub-list! [grubs]
|
||||
(let [sorted-grubs (sort-by (juxt :completed get-grub-ingredient) (vals grubs))]
|
||||
(dom/render-grub-list sorted-grubs)))
|
|
@ -1,151 +0,0 @@
|
|||
(ns grub.view.recipe
|
||||
(:require [grub.view.dom :as dom]
|
||||
[cljs.core.async :as a :refer [<! >! chan]])
|
||||
(:require-macros [grub.macros :refer [log logs and-let]]
|
||||
[cljs.core.async.macros :refer [go go-loop]]))
|
||||
|
||||
(defn wait-for-new-recipe-input-click []
|
||||
(:chan (dom/listen-once dom/new-recipe :click)))
|
||||
|
||||
(defn parse-new-recipe-event []
|
||||
(let [name (dom/-get-name dom/new-recipe)
|
||||
grubs (dom/-get-grubs-str dom/new-recipe)]
|
||||
(when (not (or (empty? name) (empty? grubs)))
|
||||
(let [id (str "recipe-" (.now js/Date))]
|
||||
{:event :add-recipe
|
||||
:name name
|
||||
:grubs grubs
|
||||
:id id}))))
|
||||
|
||||
(defn wait-for-create-event []
|
||||
(let [out (chan)
|
||||
{ctrl-enters :chan
|
||||
ctrl-enters-unlisten :unlisten} (dom/get-ctrl-enters)
|
||||
{away-clicks :chan
|
||||
away-clicks-unlisten :unlisten} (dom/get-away-clicks dom/new-recipe)
|
||||
{done-clicks :chan
|
||||
done-clicks-unlisten :unlisten} (dom/get-clicks dom/new-recipe-done-btn)]
|
||||
(go (a/alts! [ctrl-enters away-clicks done-clicks])
|
||||
(ctrl-enters-unlisten)
|
||||
(away-clicks-unlisten)
|
||||
(done-clicks-unlisten)
|
||||
(when-let [event (parse-new-recipe-event)]
|
||||
(>! out event))
|
||||
(a/close! out))
|
||||
out))
|
||||
|
||||
(defn get-create-events []
|
||||
(let [out (chan)]
|
||||
(go-loop []
|
||||
(<! (wait-for-new-recipe-input-click))
|
||||
(dom/-expand! dom/new-recipe)
|
||||
(when-let [create-event (<! (wait-for-create-event))]
|
||||
(>! out create-event)
|
||||
(dom/-clear! dom/new-recipe))
|
||||
(dom/-unexpand! dom/new-recipe)
|
||||
(recur))
|
||||
out))
|
||||
|
||||
(defn wait-for-edit-recipe-input-click []
|
||||
(dom/get-edit-recipe-input-click))
|
||||
|
||||
(defn parse-update-recipe-event [elem]
|
||||
(let [id (.-id elem)
|
||||
name (dom/-get-name elem)
|
||||
grubs (dom/-get-grubs-str elem)]
|
||||
(when (not (or (empty? name) (empty? grubs)))
|
||||
{:event :update-recipe
|
||||
:name name
|
||||
:grubs grubs
|
||||
:id id})))
|
||||
|
||||
(defn wait-for-update-event [elem]
|
||||
(let [out (chan)
|
||||
{ctrl-enters :chan
|
||||
ctrl-enters-unlisten :unlisten} (dom/get-ctrl-enters)
|
||||
{away-clicks :chan
|
||||
away-clicks-unlisten :unlisten} (dom/get-away-clicks elem)
|
||||
{done-clicks :chan
|
||||
done-clicks-unlisten :unlisten} (dom/get-clicks (dom/recipe-done-btn-selector elem))]
|
||||
(go (a/alts! [ctrl-enters away-clicks done-clicks])
|
||||
(ctrl-enters-unlisten)
|
||||
(away-clicks-unlisten)
|
||||
(done-clicks-unlisten)
|
||||
(when-let [event (parse-update-recipe-event elem)]
|
||||
(>! out event))
|
||||
(a/close! out))
|
||||
out))
|
||||
|
||||
(defn get-update-events []
|
||||
(let [out (chan)]
|
||||
(go-loop []
|
||||
(let [recipe-elem (<! (wait-for-edit-recipe-input-click))]
|
||||
(dom/-expand! recipe-elem)
|
||||
(when-let [update-event (<! (wait-for-update-event recipe-elem))]
|
||||
(>! out update-event))
|
||||
(dom/-unexpand! recipe-elem)
|
||||
(recur)))
|
||||
out))
|
||||
|
||||
(defn get-add-grub-events []
|
||||
(let [out (chan)
|
||||
recipe-add-grubs-clicks (dom/get-recipe-add-grubs-clicks)]
|
||||
(go-loop []
|
||||
(let [elem (<! recipe-add-grubs-clicks)
|
||||
grub-texts (dom/-get-grubs elem)
|
||||
grubs (map-indexed (fn [index g] {:id (str "grub-" (.now js/Date) index)
|
||||
:grub g
|
||||
:completed false})
|
||||
grub-texts)
|
||||
event {:event :add-grub-list
|
||||
:grubs grubs}]
|
||||
(>! out event))
|
||||
(recur))
|
||||
out))
|
||||
|
||||
(defmulti handle-event (fn [event recipes] (:event event))
|
||||
:default :unknown-event)
|
||||
|
||||
(defmethod handle-event :unknown-event [event recipes]
|
||||
;(logs "Cannot handle unknown event:" event)
|
||||
recipes)
|
||||
|
||||
(defmethod handle-event :add-recipe [event recipes]
|
||||
(let [recipe (dom/add-new-recipe! (:id event)
|
||||
(:name event)
|
||||
(:grubs event))]
|
||||
(assoc recipes (:id recipe) recipe)))
|
||||
|
||||
(defn assoc-new-recipe! [current new]
|
||||
(assoc current (:id new)
|
||||
(dom/add-new-recipe! (:id new) (:name new) (:grubs new))))
|
||||
|
||||
(defn add-new-recipes! [recipe-events]
|
||||
(reduce assoc-new-recipe! {} recipe-events))
|
||||
|
||||
(defmethod handle-event :add-recipe-list [event recipes]
|
||||
(let [add-recipe-events (:recipes event)
|
||||
added-recipes (add-new-recipes! add-recipe-events)
|
||||
new-recipes (merge recipes added-recipes)]
|
||||
new-recipes))
|
||||
|
||||
(defmethod handle-event :update-recipe [event recipes]
|
||||
(let [recipe (get recipes (:id event))
|
||||
updated-recipe (-> recipe
|
||||
(assoc :name (:name event))
|
||||
(assoc :grubs (:grubs event)))]
|
||||
(dom/-update-recipe! updated-recipe)
|
||||
(assoc recipes (:id recipes) updated-recipe)))
|
||||
|
||||
(defn handle-recipes [remote-events]
|
||||
(let [out (chan)
|
||||
local-events [(get-create-events)
|
||||
(get-update-events)]
|
||||
add-grub-events (get-add-grub-events)]
|
||||
(a/pipe add-grub-events out)
|
||||
(go-loop [recipes {}]
|
||||
(let [[event c] (a/alts! (conj local-events remote-events))]
|
||||
(when-not (= c remote-events)
|
||||
(>! out event))
|
||||
(recur (handle-event event recipes))))
|
||||
out))
|
Loading…
Reference in a new issue