Refactor sidebar to make it reloadable without losing state
This commit is contained in:
parent
867d8fab56
commit
2702283490
@ -84,30 +84,34 @@
|
|||||||
item
|
item
|
||||||
(get-in-item (nth (:children item) fdepth) rdepth)))
|
(get-in-item (nth (:children item) fdepth) rdepth)))
|
||||||
|
|
||||||
(defn model
|
(defonce state
|
||||||
"Returns initial sidebar state"
|
(atom {:item nil
|
||||||
[]
|
:hits nil
|
||||||
{:item nil
|
:depth []
|
||||||
:hits nil
|
:loading false}))
|
||||||
:depth []
|
|
||||||
:loading false})
|
|
||||||
|
|
||||||
(defn update-state
|
(defn update-state
|
||||||
"Given a message and the old state, returns the new state"
|
"Given a message, returns the new state"
|
||||||
[msg state]
|
[msg]
|
||||||
(case (:type msg)
|
(case (:type msg)
|
||||||
:got-item (-> state
|
:got-item (swap! state
|
||||||
(assoc :item (:item msg))
|
#(-> %
|
||||||
(assoc :loading false))
|
(assoc :item (:item msg))
|
||||||
:got-hits (-> state
|
(assoc :loading false)))
|
||||||
(assoc :hits (:hits msg))
|
:got-hits (swap! state
|
||||||
(assoc :loading false))
|
#(-> %
|
||||||
:enq-depth (assoc state :depth (conj (:depth state) (:index msg)))
|
(assoc :hits (:hits msg))
|
||||||
:deq-depth (assoc state :depth
|
(assoc :loading false)))
|
||||||
(subvec (:depth state) 0 (- (count (:depth state)) 1)))
|
:enq-depth (swap! state
|
||||||
:clear-item (assoc state :item nil)
|
#(assoc % :depth (conj (:depth @state) (:index msg))))
|
||||||
:loading (assoc state :loading (:loading msg))
|
:deq-depth (swap! state
|
||||||
state))
|
#(assoc % :depth
|
||||||
|
(subvec (:depth @state) 0 (- (count (:depth @state)) 1))))
|
||||||
|
:clear-item (swap! state
|
||||||
|
#(assoc % :item nil))
|
||||||
|
:loading (swap! state
|
||||||
|
#(assoc % :loading (:loading msg)))
|
||||||
|
@state))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
"Given a callback to dispatch an update message and the sidebar state, returns the sidebar DOM"
|
"Given a callback to dispatch an update message and the sidebar state, returns the sidebar DOM"
|
||||||
@ -244,14 +248,17 @@
|
|||||||
(dispatch-message
|
(dispatch-message
|
||||||
{:type :clear-item})))))))
|
{:type :clear-item})))))))
|
||||||
|
|
||||||
|
(declare run-render-loop)
|
||||||
|
|
||||||
|
(defn dispatch-message [msg]
|
||||||
|
(let [new-state (update-state msg)]
|
||||||
|
(run-render-loop new-state)))
|
||||||
|
|
||||||
(defn run-render-loop
|
(defn run-render-loop
|
||||||
"Runs the model-update-view loop"
|
"Runs the model-update-view loop"
|
||||||
[state]
|
[state]
|
||||||
(let [dispatch-message (fn [msg]
|
(render (view dispatch-message state))
|
||||||
(let [new-state (update-state msg state)]
|
(handle-events dispatch-message state))
|
||||||
(run-render-loop new-state)))]
|
|
||||||
(render (view dispatch-message state))
|
|
||||||
(handle-events dispatch-message state)))
|
|
||||||
|
|
||||||
(defn fetch-hits
|
(defn fetch-hits
|
||||||
"Fetch hits in the Algolia API matching the URL"
|
"Fetch hits in the Algolia API matching the URL"
|
||||||
@ -267,12 +274,12 @@
|
|||||||
(defn init
|
(defn init
|
||||||
"Initializes the sidebar"
|
"Initializes the sidebar"
|
||||||
[]
|
[]
|
||||||
(let [initial-state (update-state {:type :loading :loading true} (model))]
|
(let [initial-state (update-state {:type :loading :loading true})]
|
||||||
(run-render-loop initial-state)
|
(run-render-loop initial-state)
|
||||||
(go (-> (fetch-hits)
|
(go (-> (fetch-hits)
|
||||||
(<!)
|
(<!)
|
||||||
(#(update-state {:type :got-hits
|
(#(update-state {:type :got-hits
|
||||||
:hits %} initial-state))
|
:hits %}))
|
||||||
(run-render-loop)))))
|
(run-render-loop)))))
|
||||||
|
|
||||||
(init)
|
(init)
|
||||||
|
Loading…
Reference in New Issue
Block a user