From d0ede7329514c670318c65e8faa2924454ae82cf Mon Sep 17 00:00:00 2001 From: Nicholas Kariniemi Date: Sun, 4 Aug 2013 09:56:49 +0300 Subject: [PATCH] Synced checking of items --- src-cljs/grub_client/async-utils.cljs | 14 ++++-- src-cljs/grub_client/core.cljs | 69 +++++++++++++++++---------- src-cljs/grub_client/view.cljs | 63 +++++++++++++++++++----- 3 files changed, 107 insertions(+), 39 deletions(-) diff --git a/src-cljs/grub_client/async-utils.cljs b/src-cljs/grub_client/async-utils.cljs index 6f196ec..c3724c2 100644 --- a/src-cljs/grub_client/async-utils.cljs +++ b/src-cljs/grub_client/async-utils.cljs @@ -23,9 +23,9 @@ (defn fan-in ([ins] (fan-in (chan) ins)) ([c ins] - (go (while true - (let [[x] (alts! ins)] - (>! c x)))) + (go-loop + (let [[x] (alts! ins)] + (>! c x))) c)) (defn copy-chan @@ -63,4 +63,12 @@ (go-loop (let [v (! out v))) + out)) diff --git a/src-cljs/grub_client/core.cljs b/src-cljs/grub_client/core.cljs index ee38b5f..ff3df28 100644 --- a/src-cljs/grub_client/core.cljs +++ b/src-cljs/grub_client/core.cljs @@ -1,42 +1,63 @@ (ns grub-client.core - (:require [cljs.core.async :refer [! >!! chan close! timeout]] - [grub-client.async-utils - :refer [fan-in fan-out event-chan filter-chan do-chan!]] - [grub-client.view :as view]) - (:require-macros [cljs.core.async.macros :refer [go]] - [grub-client.macros :refer [log go-loop]])) + (:require [grub-client.async-utils + :refer [fan-in fan-out event-chan filter-chan do-chan do-chan! map-chan]] + [grub-client.view :as view] + [cljs.core.async :refer [! >!! chan close! timeout]] + [cljs.reader]) + (:require-macros [grub-client.macros :refer [log go-loop]] + [cljs.core.async.macros :refer [go]])) (def websocket* (atom nil)) (defn connect-to-server [] (reset! websocket* (js/WebSocket. "ws://localhost:3000/ws"))) -(defn get-local-added-grubs [] - (let [grubs (fan-in [(view/get-grubs-from-clicks) (view/get-grubs-from-enter)])] - (filter-chan #(not (empty? %)) grubs))) +(defn get-local-events [] + (let [added-events (view/get-added-events) + completed-events (view/get-completed-events)] + (fan-in [added-events completed-events]))) -(defn push-grubs-to-server [in] - (do-chan! #(.send @websocket* %) in)) - -(defn get-remote-added-grubs [] +(defn get-remote-events [] (let [out (chan)] (aset @websocket* "onmessage" (fn [event] - (let [grub (.-data event)] - (log "Received grub:" grub) - (go (>! out grub))))) + (log "event:" event) + (let [grub-event (cljs.reader/read-string (.-data event))] + (log "Received grub event:" (str grub-event)) + (go (>! out grub-event))))) out)) -(defn add-new-grubs-as-they-come [] - (let [added-local (get-local-added-grubs) - [added-local' added-local''] (fan-out added-local 2) - added-remote (get-remote-added-grubs) - added (fan-in [added-local' added-remote])] - (do-chan! view/append-new-grub added) - (push-grubs-to-server added-local''))) +(defn send-to-server [event] + (.send @websocket* event)) + +(defn handle-added [in] + (->> in + (filter-chan #(= (:event %) :create)) + (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 [] (view/render-body) (connect-to-server) - (add-new-grubs-as-they-come)) + (handle-grub-events)) (init) diff --git a/src-cljs/grub_client/view.cljs b/src-cljs/grub_client/view.cljs index 82c4f7d..4acae89 100644 --- a/src-cljs/grub_client/view.cljs +++ b/src-cljs/grub_client/view.cljs @@ -1,13 +1,18 @@ (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]]) - (: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]])) (deftemplate grub-template [grub] [:tr [:td - [:div.checkbox [:label [:input {:type "checkbox"}] grub]]]]) + [:div.checkbox.grubCheckbox [:label {:id (:id grub)} + [:input {:type "checkbox"}] + (:grub grub)]]]]) (def add-grub-text (node [:input.form-control {:type "text" :placeholder "2 grubs"}])) @@ -15,13 +20,13 @@ (def add-grub-btn (node [:button.btn.btn-default {:type "button"} "Add"])) -(deftemplate main-template [grubs] +(deftemplate main-template [] [:div.container [:div.row.show-grid [:div.col-lg-4] [:div.col-lg-4 [:h3 "Grub List"] - [:div.input-group + [:div.input-group add-grub-text [:span.input-group-btn add-grub-btn]] @@ -32,22 +37,34 @@ (defn render-body [] (dommy/prepend! (sel1 :body) (main-template))) -(defn append-new-grub [grub] - (dommy/append! (sel1 :#grubList) (grub-template grub))) +(defn add-grub-to-dom [grub-obj] + (log "Adding" (str grub-obj)) + (dommy/append! (sel1 :#grubList) (grub-template grub-obj))) -(defn push-new-grub [out] - (let [new-grub (dommy/value add-grub-text)] +(defn add-grub [grub] + (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 "") - (go (>! out new-grub)))) + text)) (defn get-grubs-from-clicks [] (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)) (defn put-grubs-if-enter-pressed [out event] (when (= (.-keyIdentifier event) "Enter") - (push-new-grub out))) + (go (>! out (get-add-grub-text))))) (defn get-grubs-from-enter [] (let [out (chan)] @@ -55,3 +72,25 @@ :keyup (partial put-grubs-if-enter-pressed 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)) +