<commit_before>(ns ^{:doc "Render the views for the application."}
  one.repmax.view
  (:use [domina.xpath :only (xpath)])
  (:require-macros [one.repmax.snippets :as snippets])
  (:require [clojure.browser.event :as event]
            [domina :as d]
            [one.dispatch :as dispatch]))

(def ^{:doc "A map which contains chunks of HTML which may be used
  when rendering views."}
  snippets (snippets/snippets))

;; TODO Time this approach (i.e., "Scorched Earth") versus hiding/showing
;;      *existing* list items after a search
(defn- render-exercise-list [exercises]
  (let [content (xpath "//div[@id='exercise-list']/ol")]
    (d/destroy-children! content)
    (doseq [e exercises]
      (d/append! content (exercise-list-item e)))))

(defn- exercise-list-item [exercise]
  (let [li (d/clone (:exercises-list-item snippets))
        dom-id (str "exercise-" (:_id exercise))]
    (-> li
      (d/set-attr! "id" dom-id))
    (-> li (xpath "a")
      (d/set-attr! "href" (str "#")))
    (-> li (xpath ".//span[@class='list-item-label']")
      (d/set-text! (:name exercise)))
    li))

(defn- add-exercise-search-event-listener []
  (let [field (d/by-id "search-input")]
    (event/listen field
                  "keyup"
                  #(dispatch/fire :exercise-search-field-changed (d/value field)))))

(dispatch/react-to #{:exercise-search-results-ready}
                   (fn [_ exercises] (render-exercise-list exercises)))

(defmulti render
  "Accepts a map which represents the current state of the application
  and renders a view based on the value of the `:state` key."
  :state)

(defmethod render :exercise-list [_]
  (let [header (d/by-id "header")
        content (d/by-id "content")]
    (d/swap-content! header (:exercises-header snippets))
    (d/set-html! content (:exercises-search snippets))
    (d/append! content (:exercises-list snippets))
    (add-exercise-search-event-listener)))

(dispatch/react-to #{:state-change} (fn [_ m] (render m)))<commit_msg>Code organization: consolidate reactor registration<commit_after>(ns ^{:doc "Render the views for the application."}
  one.repmax.view
  (:use [domina.xpath :only (xpath)])
  (:require-macros [one.repmax.snippets :as snippets])
  (:require [clojure.browser.event :as event]
            [domina :as d]
            [one.dispatch :as dispatch]))

(def ^{:doc "A map which contains chunks of HTML which may be used
  when rendering views."}
  snippets (snippets/snippets))

;; TODO Time this approach (i.e., "Scorched Earth") versus hiding/showing
;;      *existing* list items after a search
(defn- render-exercise-list [exercises]
  (let [content (xpath "//div[@id='exercise-list']/ol")]
    (d/destroy-children! content)
    (doseq [e exercises]
      (d/append! content (exercise-list-item e)))))

(defn- exercise-list-item [exercise]
  (let [li (d/clone (:exercises-list-item snippets))
        dom-id (str "exercise-" (:_id exercise))]
    (-> li
      (d/set-attr! "id" dom-id))
    (-> li (xpath "a")
      (d/set-attr! "href" (str "#")))
    (-> li (xpath ".//span[@class='list-item-label']")
      (d/set-text! (:name exercise)))
    li))

(defn- add-exercise-search-event-listener []
  (let [field (d/by-id "search-input")]
    (event/listen field
                  "keyup"
                  #(dispatch/fire :exercise-search-field-changed (d/value field)))))

(defmulti render
  "Accepts a map which represents the current state of the application
  and renders a view based on the value of the `:state` key."
  :state)

(defmethod render :exercise-list [_]
  (let [header (d/by-id "header")
        content (d/by-id "content")]
    (d/swap-content! header (:exercises-header snippets))
    (d/set-html! content (:exercises-search snippets))
    (d/append! content (:exercises-list snippets))
    (add-exercise-search-event-listener)))

;; Register reactors

(dispatch/react-to #{:state-change} (fn [_ m] (render m)))
(dispatch/react-to #{:exercise-search-results-ready}
                   (fn [_ exercises] (render-exercise-list exercises)))

{'fraction_non_alphanumeric': 0.1665841584158416, 'fraction_numerical': 0.0, 'mean_word_length': 3.144615384615385, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2627352', 'n_tokens_mistral': 1406, 'n_tokens_neox': 1329, 'n_words': 365}