Synced deletion of grubs

This commit is contained in:
Nicholas Kariniemi 2013-08-04 12:15:22 +03:00
parent d0ede73295
commit e1efdd3ef1
3 changed files with 50 additions and 32 deletions

View file

@ -4,7 +4,7 @@
[grub-client.view :as view] [grub-client.view :as view]
[cljs.core.async :refer [<! >! >!! chan close! timeout]] [cljs.core.async :refer [<! >! >!! chan close! timeout]]
[cljs.reader]) [cljs.reader])
(:require-macros [grub-client.macros :refer [log go-loop]] (:require-macros [grub-client.macros :refer [log logs go-loop]]
[cljs.core.async.macros :refer [go]])) [cljs.core.async.macros :refer [go]]))
(def websocket* (atom nil)) (def websocket* (atom nil))
@ -13,47 +13,45 @@
(reset! websocket* (js/WebSocket. "ws://localhost:3000/ws"))) (reset! websocket* (js/WebSocket. "ws://localhost:3000/ws")))
(defn get-local-events [] (defn get-local-events []
(let [added-events (view/get-added-events) (fan-in [(view/get-added-events)
completed-events (view/get-completed-events)] (view/get-completed-events)
(fan-in [added-events completed-events]))) (view/get-deleted-events)]))
(defn get-remote-events [] (defn get-remote-events []
(let [out (chan)] (let [out (chan)]
(aset @websocket* "onmessage" (fn [event] (aset @websocket* "onmessage" (fn [event]
(log "event:" event)
(let [grub-event (cljs.reader/read-string (.-data event))] (let [grub-event (cljs.reader/read-string (.-data event))]
(log "Received grub event:" (str grub-event)) (logs "Received:" grub-event)
(go (>! out grub-event))))) (go (>! out grub-event)))))
out)) out))
(defn send-to-server [event] (defn send-to-server [event]
(.send @websocket* event)) (.send @websocket* event))
(defn handle-added [in] (defmulti handle-event :event :default :unknown-event)
(->> in
(filter-chan #(= (:event %) :create))
(do-chan! view/add-grub)))
(defn handle-completed [in] (defmethod handle-event :create [event]
(->> in (view/add-grub event))
(filter-chan #(= (:event %) :complete))
(do-chan! view/complete-grub)))
(defn handle-uncompleted [in] (defmethod handle-event :complete [event]
(->> in (view/complete-grub event))
(filter-chan #(= (:event %) :uncomplete))
(do-chan! view/uncomplete-grub))) (defmethod handle-event :uncomplete [event]
(view/uncomplete-grub event))
(defmethod handle-event :delete [event]
(view/delete-grub event))
(defmethod handle-event :unknown-event [event]
(logs "Cannot handle unknown event:" event))
(defn handle-grub-events [] (defn handle-grub-events []
(let [local-events (get-local-events) (let [local-events (get-local-events)
[local-events' local-events''] (fan-out local-events 2) [local-events' local-events''] (fan-out local-events 2)
remote-events (get-remote-events) remote-events (get-remote-events)
[remote-events' remote-events'' remote-events'''] (fan-out remote-events 3) events (fan-in [local-events' remote-events])]
events (fan-in [local-events' remote-events'])]
(do-chan! send-to-server local-events'') (do-chan! send-to-server local-events'')
(handle-added events) (go-loop (handle-event (<! events)))))
(handle-completed remote-events'')
(handle-uncompleted remote-events''')))
(defn init [] (defn init []
(view/render-body) (view/render-body)

View file

@ -3,6 +3,10 @@
(defmacro log [& args] (defmacro log [& args]
`(.log js/console ~@args)) `(.log js/console ~@args))
(defmacro logs [& args]
(let [strings (map (fn [a] `(str ~a)) args)]
`(.log js/console ~@strings)))
(defmacro go-loop [& body] (defmacro go-loop [& body]
`(cljs.core.async.macros/go `(cljs.core.async.macros/go
(while true (while true

View file

@ -3,16 +3,18 @@
:refer [do-chan! do-chan event-chan map-chan fan-in filter-chan]] :refer [do-chan! do-chan event-chan map-chan fan-in filter-chan]]
[dommy.core :as dommy] [dommy.core :as dommy]
[cljs.core.async :refer [<! >! chan]]) [cljs.core.async :refer [<! >! chan]])
(:require-macros [grub-client.macros :refer [log go-loop]] (:require-macros [grub-client.macros :refer [log logs go-loop]]
[dommy.macros :refer [deftemplate sel1 node]] [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 {:id (:id grub)}
[:td [:td
[:div.checkbox.grubCheckbox [:label {:id (:id grub)} [:div.checkbox.grubCheckbox [:label
[:input {:type "checkbox"}] [:input {:type "checkbox"}]
(:grub grub)]]]]) (:grub grub)]]]
[:td
[:button.close {:type "button"} "×"]]])
(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"}]))
@ -38,20 +40,24 @@
(dommy/prepend! (sel1 :body) (main-template))) (dommy/prepend! (sel1 :body) (main-template)))
(defn add-grub-to-dom [grub-obj] (defn add-grub-to-dom [grub-obj]
(log "Adding" (str grub-obj)) (logs "Adding" grub-obj)
(dommy/append! (sel1 :#grubList) (grub-template grub-obj))) (dommy/append! (sel1 :#grubList) (grub-template grub-obj)))
(defn add-grub [grub] (defn add-grub [grub]
(add-grub-to-dom grub)) (add-grub-to-dom grub))
(defn complete-grub [grub] (defn complete-grub [grub]
(log "complete-grub:" (str grub)) (logs "Complete" grub)
(aset (sel1 [(str "#" (:id grub)) "input"]) "checked" true)) (aset (sel1 [(str "#" (:id grub)) "input"]) "checked" true))
(defn uncomplete-grub [grub] (defn uncomplete-grub [grub]
(log "uncomplete-grub:" (str grub)) (logs "Uncomplete" grub)
(aset (sel1 [(str "#" (:id grub)) "input"]) "checked" false)) (aset (sel1 [(str "#" (:id grub)) "input"]) "checked" false))
(defn delete-grub [grub]
(let [elem (sel1 (str "#" (:id grub)))]
(.removeChild (.-parentNode elem) elem)))
(defn get-add-grub-text [] (defn get-add-grub-text []
(let [text (dommy/value add-grub-text)] (let [text (dommy/value add-grub-text)]
(dommy/set-value! add-grub-text "") (dommy/set-value! add-grub-text "")
@ -81,12 +87,13 @@
(map-chan (fn [g] {:event :create :grub g :id (str "grub-" (.now js/Date))}))))) (map-chan (fn [g] {:event :create :grub g :id (str "grub-" (.now js/Date))})))))
(defn get-completed-event [event] (defn get-completed-event [event]
(logs "completed-event:" event)
(let [target (.-target event) (let [target (.-target event)
checked (.-checked target) checked (.-checked target)
event-type (if checked :complete :uncomplete) event-type (if checked :complete :uncomplete)
label (aget (.-labels (.-target event)) 0) label (aget (.-labels (.-target event)) 0)
grub (.-textContent label) grub (.-textContent label)
id (.-id label)] id (.-id (.-parentNode (.-parentNode (.-parentNode (.-parentNode target)))))]
{:grub grub :id id :event event-type})) {:grub grub :id id :event event-type}))
(defn get-completed-events [] (defn get-completed-events []
@ -94,3 +101,12 @@
grubs (map-chan #(get-completed-event %) events)] grubs (map-chan #(get-completed-event %) events)]
grubs)) grubs))
(defn get-deleted-events []
(let [click-events (chan)]
(dommy/listen! [(sel1 :#grubList) ".close"]
:click
#(go (>! click-events %)))
(let [ids (map-chan #(.-id (.-parentNode (.-parentNode (.-target %)))) click-events)
grub-events (map-chan (fn [id] {:event :delete :id id}) ids)]
grub-events)))