Skip to content

Instantly share code, notes, and snippets.

@monjohn
Created October 27, 2015 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monjohn/b90a18d551e7ed7403f0 to your computer and use it in GitHub Desktop.
Save monjohn/b90a18d551e7ed7403f0 to your computer and use it in GitHub Desktop.
Not refreshing ui on change of top-level val
;;; The Card component calls transact, to advance to the next item in :word-list,
;;; when it gets to the end of the sequence, the 'card/advance mutation, changes :location to a new value,
;;; this should cause a rerender from the Root Component
(def init-data
{:location :welcome
:current-list
{:german? true
:number-correct 0
:total 2
:current 0
:word-list
[{:ger "Stollen" :eng "Cleats" :level :daily :score 1}
{:ger "Ball" :eng "Ball" :level :daily :score 0}
{:ger "Torhüter" :eng "Goal Keeper" :level :daily :score 2}
{:ger "Gras" :eng "Grass" :score 0 :level :daily}
{:ger "Strafenstoß" :eng "Penalty Kick" :score 1 :level :daily}
{:ger "Vorwärts" :eng "Forward" :score 0 :level :daily}
{:ger "Mittelfeld" :eng "Midfield" :score 2 :level :daily}
{:ger "Eckball" :eng "Corner" :score 3 :level :daily}
{:ger "Tor" :eng "Goal" :score 3 :level :daily}
{:ger "Pass" :eng "Pass" :score 2 :level :daily}
{:ger "Verlängerung" :eng "Overtime" :score 5 :level :daily}
{:ger "Schiedsrichter" :eng "Referee" :score 3 :level :daily}]}})
(def app-state (atom init-data))
(defmulti read om/dispatch)
(defmethod read :default
[{:keys [state] :as env} key params]
(let [st @state]
(if-let [[_ value] (find st key)]
{:value value}
{:value :not-found})))
(defmulti mutate om/dispatch)
(defmethod mutate 'card/advance
[{:keys [state]} key params]
(let [{:keys [current total]} (get-in @state [:current-list])]
(println params)
(println current " " total "location: " (:location @state))
(if (= total current); go to :finished if done with list
{:value [:location]
:action #(swap! state assoc :location :finished)}
{:value [:current]
:action #(swap! state update-in [:current-list :current] inc)})))
(defmethod mutate 'card/flip
[{:keys [state]} _ _]
{:value [:german?]
:action #(swap! state update-in [:current-list :german?] not)})
(defmethod mutate 'score/increment
[{:keys [state]} _ _]
(let [current (get-in @state [:current-list :current])]
{:value [:word-list :correct]
:action #(-> state
(swap! update-in [:current-list :word-list current :score] inc)
(swap! update-in [:correct] inc))}))
(defmethod mutate 'location/goto
[{:keys [state]} _ params]
{:value [:location]
:action #(swap! state assoc :location (:page params))})
(def reconciler
(om/reconciler
{:state app-state
:parser (om/parser {:read read :mutate mutate})}))
(defui Word
static om/Ident
(ident [this {:keys [ger]}]
[:pair/by-ger ger])
static om/IQuery
(query [this]
[:ger :eng :score :level]))
(defui Card
static om/IQuery
(query [this]
[:word-list :german? :current])
Object
(render [this]
(let [{:keys [word-list german? current]} (-> this om/props )
{:keys [ger eng]} (get word-list current)]
(dom/section #js {:className "container"}
(dom/div #js {:id "card"
:className (if-not german? "flipped" "non-flipped")}
(dom/figure #js {:className "front"
:onClick #(om/transact! this '[(card/flip)])} ger)
(dom/figure #js {:className "back"} eng
(dom/div #js {:className "buttons"}
(dom/div #js
{:id "wrong"
:onClick #(om/transact! this '[(card/advance {:k :location}) (card/flip) :location])}
"Wrong")
(dom/div #js
{:id "correct"
:onClick #(om/transact! this '[(score/increment) (card/advance) (card/flip)])}
"Correct"))))))))
(def card (om/factory Card))
(defn row [{:keys [ger eng level score]}]
(dom/tr #js {:className "ger" :key ger}
(dom/td nil ger)
(dom/td nil eng)
(dom/td nil (name level))
(dom/td nil score)))
(defn welcome [root]
(let [handler #(om/transact! root '[(location/goto {:page :review})])]
(dom/div #js {:onClick handler}
(dom/h2 #js {:className "container"} "Welcome"))))
(defui Scoreboard
static om/IQuery
(query [this] [:word-list :correct :total :number-correct])
Object
(render [this]
(let [{:keys [word-list correct total number-correct]} (om/props this)]
(dom/div #js {:id "scoreboard"}
(dom/p nil (str "You answered " number-correct " out of " total))
(dom/table nil
(dom/tbody nil
(dom/tr #js {:key 100}
(dom/th nil "German")
(dom/th nil "English")
(dom/th nil "Level")
(dom/th nil "Score"))
(map row word-list)))))))
(def scoreboard (om/factory Scoreboard))
(defui Root
static om/IQuery
(query [this]
[:location {:current-list (om/get-query Card)}
{:current-list (om/get-query Scoreboard)}])
Object
(render [this]
(println "root rendered")
(let [{:keys [location current-list]} (om/props this)]
(dom/div nil
(condp = location
:welcome (welcome this)
:review (card current-list)
:finished (scoreboard current-list))))))
(defn main []
(om/add-root! reconciler Root (gdom/getElement "app")))
(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment