Generate whole sidebar in cljs; change icon to back arrow based on context
This commit is contained in:
parent
a7c6f88581
commit
1865b70f73
@ -9,16 +9,7 @@
|
||||
<script src="js/generated/out/cljs_base.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sidebar">
|
||||
<div class="sidebarHeader">
|
||||
<img class="headerIcon" src="icons/icon48.png" width="16px" height="16px">
|
||||
<span class="body30 headerTitle">Looped In</span>
|
||||
<button class="iconButton" id="closeSidebar">
|
||||
<img src="icons/stop-16.svg" width="16px" height="16px">
|
||||
</button>
|
||||
</div>
|
||||
<div id="sidebarContent"></div>
|
||||
</div>
|
||||
<div id="sidebar"></div>
|
||||
<script src="js/generated/sidebar.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -24,6 +24,9 @@
|
||||
(dom/appendChild el child)
|
||||
el)
|
||||
|
||||
(defn sidebar-content [& body]
|
||||
(apply dom/createDom "div" (clj->js {:id "sidebarContent"}) body))
|
||||
|
||||
(defn comments-indicator [num-comments]
|
||||
(let [text (caption30 (str num-comments " comment" (when (not= num-comments 1) "s")))]
|
||||
(dom/createDom "div"
|
||||
@ -105,6 +108,22 @@
|
||||
(for [i (range 1 6)]
|
||||
(dom/createDom "div" (str "rect" i)))))
|
||||
|
||||
(defn sidebar-header [icon-src]
|
||||
(dom/createDom "div" "sidebarHeader"
|
||||
(dom/createDom "img"
|
||||
(clj->js {:class "headerIcon"
|
||||
:src icon-src
|
||||
:width "16px"
|
||||
:height "16px"}))
|
||||
(dom/createDom "span" "body30 headerTitle" "Looped In")
|
||||
(dom/createDom "button"
|
||||
(clj->js {:class "iconButton"
|
||||
:id "closeSidebar"})
|
||||
(dom/createDom "img"
|
||||
(clj->js {:src "icons/stop-16.svg"
|
||||
:width "16px"
|
||||
:height "16px"})))))
|
||||
|
||||
(defn with-classes [el & classes]
|
||||
(doseq [class (filter #(not (string/blank? %)) classes)]
|
||||
(classes/add el class))
|
||||
|
@ -76,117 +76,129 @@
|
||||
[dispatch-message state]
|
||||
(log/debug state)
|
||||
(cond
|
||||
(:loading state) (components/loader)
|
||||
(:item state) (let [current-item (get-in-item
|
||||
(:item state)
|
||||
(:depth state))]
|
||||
(cons
|
||||
(case (:type current-item)
|
||||
"story" (components/card
|
||||
(:loading state) (list (components/sidebar-header "icons/icon48.png")
|
||||
(components/sidebar-content (components/loader)))
|
||||
(:item state) (list
|
||||
(components/sidebar-header "icons/back-16.svg")
|
||||
(apply
|
||||
components/sidebar-content
|
||||
(let [current-item (get-in-item
|
||||
(:item state)
|
||||
(:depth state))]
|
||||
(cons
|
||||
(case (:type current-item)
|
||||
"story" (components/card
|
||||
(dom/createDom
|
||||
"div"
|
||||
"storyHeader"
|
||||
(components/body30 (:title current-item))
|
||||
(components/item-link (:id current-item)))
|
||||
(components/story-caption (:points current-item)
|
||||
(:author current-item)
|
||||
(* (:created_at_i current-item) 1000)))
|
||||
"comment" (components/card
|
||||
(dom/createDom
|
||||
"div"
|
||||
"commentHeader"
|
||||
(components/comment-caption (:author current-item)
|
||||
(* (:created_at_i current-item)
|
||||
1000))
|
||||
(components/item-link (:id current-item)))
|
||||
(components/comment-text (:text current-item))))
|
||||
(map-indexed (fn [index child]
|
||||
(-> (components/card
|
||||
(dom/createDom
|
||||
"div"
|
||||
"commentHeader"
|
||||
(components/comment-caption
|
||||
(:author child)
|
||||
(* (:created_at_i child) 1000))
|
||||
(components/item-link (:id child)))
|
||||
(components/comment-text (:text child))
|
||||
(-> (components/replies-indicator (count (:children child)))
|
||||
((fn [indicator]
|
||||
(if (> (count (:children child)) 0)
|
||||
(-> indicator
|
||||
(components/with-classes "clickable")
|
||||
(components/with-listener
|
||||
"click"
|
||||
(fn [e]
|
||||
(dispatch-message
|
||||
{:type :enq-depth
|
||||
:index index}))))
|
||||
indicator)))))
|
||||
(components/with-classes "child")
|
||||
((fn [card]
|
||||
(if (> (count (:children child)) 0)
|
||||
(components/with-classes card "clickable")
|
||||
card)))))
|
||||
(->> (:children current-item)
|
||||
(filter #(contains? % :text))
|
||||
(sort-by #(count (:children %)) #(compare %2 %1))))))))
|
||||
(:hits state) (list
|
||||
(components/sidebar-header "icons/icon48.png")
|
||||
(apply
|
||||
components/sidebar-content
|
||||
(map (fn [hit]
|
||||
(-> (components/card
|
||||
(dom/createDom
|
||||
"div"
|
||||
"storyHeader"
|
||||
(components/body30 (:title current-item))
|
||||
(components/item-link (:id current-item)))
|
||||
(components/story-caption (:points current-item)
|
||||
(:author current-item)
|
||||
(* (:created_at_i current-item) 1000)))
|
||||
"comment" (components/card
|
||||
(dom/createDom
|
||||
"div"
|
||||
"commentHeader"
|
||||
(components/comment-caption (:author current-item)
|
||||
(* (:created_at_i current-item) 1000))
|
||||
(components/item-link (:id current-item)))
|
||||
(components/comment-text (:text current-item))))
|
||||
(map-indexed (fn [index child]
|
||||
(-> (components/card
|
||||
(dom/createDom
|
||||
"div"
|
||||
"commentHeader"
|
||||
(components/comment-caption
|
||||
(:author child)
|
||||
(* (:created_at_i child) 1000))
|
||||
(components/item-link (:id child)))
|
||||
(components/comment-text (:text child))
|
||||
(-> (components/replies-indicator (count (:children child)))
|
||||
((fn [indicator]
|
||||
(if (> (count (:children child)) 0)
|
||||
(-> indicator
|
||||
(components/with-classes "clickable")
|
||||
(components/with-listener
|
||||
"click"
|
||||
(fn [e]
|
||||
(dispatch-message
|
||||
{:type :enq-depth
|
||||
:index index}))))
|
||||
indicator)))))
|
||||
(components/with-classes "child")
|
||||
((fn [card]
|
||||
(if (> (count (:children child)) 0)
|
||||
(components/with-classes card "clickable")
|
||||
card)))))
|
||||
(->> (:children current-item)
|
||||
(filter #(contains? % :text))
|
||||
(sort-by #(count (:children %)) #(compare %2 %1))))))
|
||||
(:hits state) (map (fn [hit]
|
||||
(-> (components/card
|
||||
(dom/createDom
|
||||
"div"
|
||||
"storyHeader"
|
||||
(components/body30 (:title hit))
|
||||
(components/item-link (:objectID hit)))
|
||||
(components/story-caption (:points hit)
|
||||
(:author hit)
|
||||
(* (:created_at_i hit) 1000))
|
||||
(-> (components/comments-indicator (:num_comments hit))
|
||||
((fn [indicator]
|
||||
(if (> (:num_comments hit) 0)
|
||||
(-> indicator
|
||||
(components/with-classes "clickable")
|
||||
(components/with-listener
|
||||
"click"
|
||||
(fn [e]
|
||||
(dispatch-message {:type :loading :loading true})
|
||||
(go
|
||||
(-> (fetch-item (:objectID hit))
|
||||
(<!)
|
||||
((fn [item]
|
||||
(dispatch-message
|
||||
{:type :got-item :item item}))))))))
|
||||
indicator)))))
|
||||
((fn [card]
|
||||
(if (> (:num_comments hit) 0)
|
||||
(components/with-classes card "clickable")
|
||||
card)))))
|
||||
(:hits state))
|
||||
#_(let [current-item (get-in-items (:items state) (:depth state))]
|
||||
(if (> (count current-item) 1)
|
||||
(map #(components/card (:title %)) current-item)
|
||||
()))))
|
||||
(components/body30 (:title hit))
|
||||
(components/item-link (:objectID hit)))
|
||||
(components/story-caption (:points hit)
|
||||
(:author hit)
|
||||
(* (:created_at_i hit) 1000))
|
||||
(-> (components/comments-indicator (:num_comments hit))
|
||||
((fn [indicator]
|
||||
(if (> (:num_comments hit) 0)
|
||||
(-> indicator
|
||||
(components/with-classes "clickable")
|
||||
(components/with-listener
|
||||
"click"
|
||||
(fn [e]
|
||||
(dispatch-message {:type :loading :loading true})
|
||||
(go
|
||||
(-> (fetch-item (:objectID hit))
|
||||
(<!)
|
||||
((fn [item]
|
||||
(dispatch-message
|
||||
{:type :got-item :item item}))))))))
|
||||
indicator)))))
|
||||
((fn [card]
|
||||
(if (> (:num_comments hit) 0)
|
||||
(components/with-classes card "clickable")
|
||||
card)))))
|
||||
(:hits state))))))
|
||||
|
||||
(defn render
|
||||
"Renders the new DOM
|
||||
|
||||
This is where clever diffing algorithms would go if this was React"
|
||||
[$sidebar-dom]
|
||||
(let [$container (dom/getElement "sidebarContent")]
|
||||
(let [$container (dom/getElement "sidebar")]
|
||||
(dom/removeChildren $container)
|
||||
(.scrollTo js/window 0 0)
|
||||
(if (seqable? $sidebar-dom)
|
||||
(apply dom/append $container $sidebar-dom)
|
||||
(dom/append $container $sidebar-dom))))
|
||||
|
||||
(defn handle-close-button [e]
|
||||
(.postMessage js/window.parent (clj->js {:type "closeSidebar"}) "*"))
|
||||
|
||||
(defn handle-events
|
||||
"Registers event listeners"
|
||||
[state]
|
||||
(events/listen (dom/getElement "closeSidebar") "click" handle-close-button))
|
||||
|
||||
(defn run-render-loop
|
||||
"Runs the model-update-view loop"
|
||||
[state]
|
||||
(let [dispatch-message (fn [msg]
|
||||
(let [new-state (update-state msg state)]
|
||||
(run-render-loop new-state)))]
|
||||
(render (view dispatch-message state))))
|
||||
|
||||
(defn handle-close-button [e]
|
||||
(.postMessage js/window.parent (clj->js {:type "closeSidebar"}) "*"))
|
||||
(render (view dispatch-message state))
|
||||
(handle-events state)))
|
||||
|
||||
(defn fetch-hits
|
||||
"Fetch hits in the Algolia API matching the URL"
|
||||
@ -202,7 +214,6 @@
|
||||
(defn init
|
||||
"Initializes the sidebar"
|
||||
[]
|
||||
(events/listen (dom/getElement "closeSidebar") "click" handle-close-button)
|
||||
(let [initial-state (update-state {:type :loading :loading true} (model))]
|
||||
(run-render-loop initial-state)
|
||||
(go (-> (fetch-hits)
|
||||
|
Loading…
Reference in New Issue
Block a user