Synced checking of items
This commit is contained in:
parent
7473ed4120
commit
d0ede73295
3 changed files with 107 additions and 39 deletions
|
@ -23,9 +23,9 @@
|
||||||
(defn fan-in
|
(defn fan-in
|
||||||
([ins] (fan-in (chan) ins))
|
([ins] (fan-in (chan) ins))
|
||||||
([c ins]
|
([c ins]
|
||||||
(go (while true
|
(go-loop
|
||||||
(let [[x] (alts! ins)]
|
(let [[x] (alts! ins)]
|
||||||
(>! c x))))
|
(>! c x)))
|
||||||
c))
|
c))
|
||||||
|
|
||||||
(defn copy-chan
|
(defn copy-chan
|
||||||
|
@ -63,4 +63,12 @@
|
||||||
(go-loop
|
(go-loop
|
||||||
(let [v (<! source)]
|
(let [v (<! source)]
|
||||||
(f v))))
|
(f v))))
|
||||||
|
|
||||||
|
(defn do-chan [f source]
|
||||||
|
(let [out (chan)]
|
||||||
|
(go-loop
|
||||||
|
(let [v (<! source)]
|
||||||
|
(f v)
|
||||||
|
(>! out v)))
|
||||||
|
out))
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,63 @@
|
||||||
(ns grub-client.core
|
(ns grub-client.core
|
||||||
(:require [cljs.core.async :refer [<! >! >!! chan close! timeout]]
|
(:require [grub-client.async-utils
|
||||||
[grub-client.async-utils
|
:refer [fan-in fan-out event-chan filter-chan do-chan do-chan! map-chan]]
|
||||||
:refer [fan-in fan-out event-chan filter-chan do-chan!]]
|
[grub-client.view :as view]
|
||||||
[grub-client.view :as view])
|
[cljs.core.async :refer [<! >! >!! chan close! timeout]]
|
||||||
(:require-macros [cljs.core.async.macros :refer [go]]
|
[cljs.reader])
|
||||||
[grub-client.macros :refer [log go-loop]]))
|
(:require-macros [grub-client.macros :refer [log go-loop]]
|
||||||
|
[cljs.core.async.macros :refer [go]]))
|
||||||
|
|
||||||
(def websocket* (atom nil))
|
(def websocket* (atom nil))
|
||||||
|
|
||||||
(defn connect-to-server []
|
(defn connect-to-server []
|
||||||
(reset! websocket* (js/WebSocket. "ws://localhost:3000/ws")))
|
(reset! websocket* (js/WebSocket. "ws://localhost:3000/ws")))
|
||||||
|
|
||||||
(defn get-local-added-grubs []
|
(defn get-local-events []
|
||||||
(let [grubs (fan-in [(view/get-grubs-from-clicks) (view/get-grubs-from-enter)])]
|
(let [added-events (view/get-added-events)
|
||||||
(filter-chan #(not (empty? %)) grubs)))
|
completed-events (view/get-completed-events)]
|
||||||
|
(fan-in [added-events completed-events])))
|
||||||
|
|
||||||
(defn push-grubs-to-server [in]
|
(defn get-remote-events []
|
||||||
(do-chan! #(.send @websocket* %) in))
|
|
||||||
|
|
||||||
(defn get-remote-added-grubs []
|
|
||||||
(let [out (chan)]
|
(let [out (chan)]
|
||||||
(aset @websocket* "onmessage" (fn [event]
|
(aset @websocket* "onmessage" (fn [event]
|
||||||
(let [grub (.-data event)]
|
(log "event:" event)
|
||||||
(log "Received grub:" grub)
|
(let [grub-event (cljs.reader/read-string (.-data event))]
|
||||||
(go (>! out grub)))))
|
(log "Received grub event:" (str grub-event))
|
||||||
|
(go (>! out grub-event)))))
|
||||||
out))
|
out))
|
||||||
|
|
||||||
(defn add-new-grubs-as-they-come []
|
(defn send-to-server [event]
|
||||||
(let [added-local (get-local-added-grubs)
|
(.send @websocket* event))
|
||||||
[added-local' added-local''] (fan-out added-local 2)
|
|
||||||
added-remote (get-remote-added-grubs)
|
(defn handle-added [in]
|
||||||
added (fan-in [added-local' added-remote])]
|
(->> in
|
||||||
(do-chan! view/append-new-grub added)
|
(filter-chan #(= (:event %) :create))
|
||||||
(push-grubs-to-server added-local'')))
|
(do-chan! view/add-grub)))
|
||||||
|
|
||||||
|
(defn handle-completed [in]
|
||||||
|
(->> in
|
||||||
|
(filter-chan #(= (:event %) :complete))
|
||||||
|
(do-chan! view/complete-grub)))
|
||||||
|
|
||||||
|
(defn handle-uncompleted [in]
|
||||||
|
(->> in
|
||||||
|
(filter-chan #(= (:event %) :uncomplete))
|
||||||
|
(do-chan! view/uncomplete-grub)))
|
||||||
|
|
||||||
|
(defn handle-grub-events []
|
||||||
|
(let [local-events (get-local-events)
|
||||||
|
[local-events' local-events''] (fan-out local-events 2)
|
||||||
|
remote-events (get-remote-events)
|
||||||
|
[remote-events' remote-events'' remote-events'''] (fan-out remote-events 3)
|
||||||
|
events (fan-in [local-events' remote-events'])]
|
||||||
|
(do-chan! send-to-server local-events'')
|
||||||
|
(handle-added events)
|
||||||
|
(handle-completed remote-events'')
|
||||||
|
(handle-uncompleted remote-events''')))
|
||||||
|
|
||||||
(defn init []
|
(defn init []
|
||||||
(view/render-body)
|
(view/render-body)
|
||||||
(connect-to-server)
|
(connect-to-server)
|
||||||
(add-new-grubs-as-they-come))
|
(handle-grub-events))
|
||||||
|
|
||||||
(init)
|
(init)
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
(ns grub-client.view
|
(ns grub-client.view
|
||||||
(:require [dommy.core :as dommy]
|
(:require [grub-client.async-utils
|
||||||
|
:refer [do-chan! do-chan event-chan map-chan fan-in filter-chan]]
|
||||||
|
[dommy.core :as dommy]
|
||||||
[cljs.core.async :refer [<! >! chan]])
|
[cljs.core.async :refer [<! >! chan]])
|
||||||
(:require-macros [dommy.macros :refer [deftemplate sel1 node]]
|
(:require-macros [grub-client.macros :refer [log go-loop]]
|
||||||
|
[dommy.macros :refer [deftemplate sel1 node]]
|
||||||
[cljs.core.async.macros :refer [go]]))
|
[cljs.core.async.macros :refer [go]]))
|
||||||
|
|
||||||
(deftemplate grub-template [grub]
|
(deftemplate grub-template [grub]
|
||||||
[:tr
|
[:tr
|
||||||
[:td
|
[:td
|
||||||
[:div.checkbox [:label [:input {:type "checkbox"}] grub]]]])
|
[:div.checkbox.grubCheckbox [:label {:id (:id grub)}
|
||||||
|
[:input {:type "checkbox"}]
|
||||||
|
(:grub grub)]]]])
|
||||||
|
|
||||||
(def add-grub-text
|
(def add-grub-text
|
||||||
(node [:input.form-control {:type "text" :placeholder "2 grubs"}]))
|
(node [:input.form-control {:type "text" :placeholder "2 grubs"}]))
|
||||||
|
@ -15,13 +20,13 @@
|
||||||
(def add-grub-btn
|
(def add-grub-btn
|
||||||
(node [:button.btn.btn-default {:type "button"} "Add"]))
|
(node [:button.btn.btn-default {:type "button"} "Add"]))
|
||||||
|
|
||||||
(deftemplate main-template [grubs]
|
(deftemplate main-template []
|
||||||
[:div.container
|
[:div.container
|
||||||
[:div.row.show-grid
|
[:div.row.show-grid
|
||||||
[:div.col-lg-4]
|
[:div.col-lg-4]
|
||||||
[:div.col-lg-4
|
[:div.col-lg-4
|
||||||
[:h3 "Grub List"]
|
[:h3 "Grub List"]
|
||||||
[:div.input-group
|
[:div.input-group
|
||||||
add-grub-text
|
add-grub-text
|
||||||
[:span.input-group-btn
|
[:span.input-group-btn
|
||||||
add-grub-btn]]
|
add-grub-btn]]
|
||||||
|
@ -32,22 +37,34 @@
|
||||||
(defn render-body []
|
(defn render-body []
|
||||||
(dommy/prepend! (sel1 :body) (main-template)))
|
(dommy/prepend! (sel1 :body) (main-template)))
|
||||||
|
|
||||||
(defn append-new-grub [grub]
|
(defn add-grub-to-dom [grub-obj]
|
||||||
(dommy/append! (sel1 :#grubList) (grub-template grub)))
|
(log "Adding" (str grub-obj))
|
||||||
|
(dommy/append! (sel1 :#grubList) (grub-template grub-obj)))
|
||||||
|
|
||||||
(defn push-new-grub [out]
|
(defn add-grub [grub]
|
||||||
(let [new-grub (dommy/value add-grub-text)]
|
(add-grub-to-dom grub))
|
||||||
|
|
||||||
|
(defn complete-grub [grub]
|
||||||
|
(log "complete-grub:" (str grub))
|
||||||
|
(aset (sel1 [(str "#" (:id grub)) "input"]) "checked" true))
|
||||||
|
|
||||||
|
(defn uncomplete-grub [grub]
|
||||||
|
(log "uncomplete-grub:" (str grub))
|
||||||
|
(aset (sel1 [(str "#" (:id grub)) "input"]) "checked" false))
|
||||||
|
|
||||||
|
(defn get-add-grub-text []
|
||||||
|
(let [text (dommy/value add-grub-text)]
|
||||||
(dommy/set-value! add-grub-text "")
|
(dommy/set-value! add-grub-text "")
|
||||||
(go (>! out new-grub))))
|
text))
|
||||||
|
|
||||||
(defn get-grubs-from-clicks []
|
(defn get-grubs-from-clicks []
|
||||||
(let [out (chan)]
|
(let [out (chan)]
|
||||||
(dommy/listen! add-grub-btn :click #(push-new-grub out))
|
(dommy/listen! add-grub-btn :click #(go (>! out (get-add-grub-text))))
|
||||||
out))
|
out))
|
||||||
|
|
||||||
(defn put-grubs-if-enter-pressed [out event]
|
(defn put-grubs-if-enter-pressed [out event]
|
||||||
(when (= (.-keyIdentifier event) "Enter")
|
(when (= (.-keyIdentifier event) "Enter")
|
||||||
(push-new-grub out)))
|
(go (>! out (get-add-grub-text)))))
|
||||||
|
|
||||||
(defn get-grubs-from-enter []
|
(defn get-grubs-from-enter []
|
||||||
(let [out (chan)]
|
(let [out (chan)]
|
||||||
|
@ -55,3 +72,25 @@
|
||||||
:keyup
|
:keyup
|
||||||
(partial put-grubs-if-enter-pressed out))
|
(partial put-grubs-if-enter-pressed out))
|
||||||
out))
|
out))
|
||||||
|
|
||||||
|
(defn get-added-events []
|
||||||
|
(let [grubs (fan-in [(get-grubs-from-clicks)
|
||||||
|
(get-grubs-from-enter)])]
|
||||||
|
(->> grubs
|
||||||
|
(filter-chan #(not (empty? %)))
|
||||||
|
(map-chan (fn [g] {:event :create :grub g :id (str "grub-" (.now js/Date))})))))
|
||||||
|
|
||||||
|
(defn get-completed-event [event]
|
||||||
|
(let [target (.-target event)
|
||||||
|
checked (.-checked target)
|
||||||
|
event-type (if checked :complete :uncomplete)
|
||||||
|
label (aget (.-labels (.-target event)) 0)
|
||||||
|
grub (.-textContent label)
|
||||||
|
id (.-id label)]
|
||||||
|
{:grub grub :id id :event event-type}))
|
||||||
|
|
||||||
|
(defn get-completed-events []
|
||||||
|
(let [events (:chan (event-chan (sel1 :#grubList) "change"))
|
||||||
|
grubs (map-chan #(get-completed-event %) events)]
|
||||||
|
grubs))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue