git.fiddlerwoaroof.com
Raw Blame History
(page "index.html"
  (:import goog.html.sanitizer.HtmlSanitizer
           goog.html.sanitizer.HtmlSanitizer.Builder
           goog.html.sanitizer.unsafe
           goog.html.sanitizer.AttributeWhitelist
           goog.string.Const
           goog.functions
           goog.html.SafeUrl
           goog.html.SafeHtml)
  (:require-macros [feed-archive.let-promise :refer [let-promise]]))

(defc state
  {"base-url" nil
   "pull-time" ""
   "feeds" []
   :items {}})

(defc= base-url
  (get state "base-url")
  #(swap! state assoc-in ["base-url"] %))

(defc= pull-time
  (get state "pull-time"))

(defc= feeds
  (get state "feeds"))

(defn setup-state [base-url]
  (let-promise [[resp (js/fetch (str base-url
                                     "/current"))]
                [data (.json resp)]]
    (swap! state merge
           (js->clj data))))

(cell= (when base-url
         (setup-state base-url)))

(defn make-feed-getter [out-cell]
  (fn [base-url path]
    (let-promise [[resp (js/fetch (str base-url "/" path))]
                  [data (.json resp)]]
      (reset! out-cell (js->clj data)))))

(defn get-feed-entry-cells [base-url feed]
  (let [feed-cell (cell {})
        items (cell= (get feed-cell "items"))
        item-count (cell= (count items))
        get-feed (make-feed-getter feed-cell)
        path (cell= (get feed "path" "<No PATH>"))
        url (cell= (get feed "url" "<No URL>"))
        title (cell= (get feed "title" "<No TITLE>"))]
    (cell= (get-feed base-url path))
    [url title path feed-cell items item-count]))

(defn make-item-getter [out-cell]
  (fn [base-url feed-path item-path]
    (let-promise [[resp (js/fetch (str base-url "/" feed-path item-path))]
                  [data (.json resp)]]
      (reset! out-cell (js->clj data)))))

(defn get-sanitizer []
  (let [r (Builder.)
        justification (.from Const "Because images are ok, silly")]
    (.alsoAllowAttributes unsafe justification
                          r #js [#js {:tagName "img" :attributeName "src" :policy nil}])
    (.build r)))

(defn sanitize-html [html]
  (let [result (.sanitize (get-sanitizer) html)]
    (.log js/console result)
    (.unwrap SafeHtml result)))

(defn get-item-cells [item]
  (let* [key (get @item "path")
         item-cell (cell= (get (:items state) key)
                          #(swap! state assoc-in [:items key] %))
         get-item (make-item-getter item-cell)]
    [get-item
     (cell= (get item "title"))
     (cell= (get item "path"))
     (cell= (get item-cell "link"))
     (cell= (sanitize-html (get item-cell "content")))]))

(cell= (.log js/console (clj->js base-url)))


(html
 (head
  (link :href "app.css" :rel "stylesheet" :type "text/css"))
 (body
  (input :type "text" :value base-url
         :change #(reset! base-url (.-value (.-target %))))
  (loop-tpl :bindings [feed feeds]
    (let [[url title path feed-cell items item-count] (get-feed-entry-cells base-url feed)]
      (section
       (if-tpl (cell= (> item-count 0))
         (article
          (h2 title) (p url)
          (ul (loop-tpl :bindings [item items]
                (let [[get-item title item-path link content] (get-item-cells item)]
                  (li (h3 (a :href link title) " "
                          (button :click #(get-item @base-url @path @item-path)
                                  ">>"))
                      (p :html content)
                      )))))))))))