Color price green/red based on direction, fix SSE middleware error

Show price in green when rising, red when falling. Use Tailwind
classes with a safelist comment so JIT includes them. Remove
middleware from SSE route to prevent "response already started" error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 16:32:40 +01:00
co-authored by Claude Opus 4.6
parent 08793c5099
commit 8169796eb9
3 changed files with 30 additions and 14 deletions
File diff suppressed because one or more lines are too long
+18 -4
View File
@@ -12,8 +12,14 @@
[io.undertow.server HttpServerExchange]
[io.undertow.util HttpString]
[java.io BufferedWriter OutputStreamWriter]
[java.time ZoneId]
[java.time.format DateTimeFormatter]
[java.util.concurrent LinkedBlockingQueue TimeUnit]))
(def ^:private time-fmt
(-> (DateTimeFormatter/ofPattern "dd-MM HH:mm:ss")
(.withZone (ZoneId/systemDefault))))
(defn home-page [_req]
(page {:title "BTC Price"}
[:header.text-center.mb-8
@@ -25,15 +31,22 @@
[:div.bg-white.rounded-2xl.shadow-sm.border.border-gray-200.p-6
[:p.text-center.text-gray-400.text-sm "Connecting..."]]]]))
(defn- render-price-html [{:keys [price recorded-at]}]
;; Tailwind classes referenced for price color:
;; text-green-600 text-red-600 text-gray-900
(defn- render-price-html [{:keys [price prev-price recorded-at]}]
(let [color (cond
(nil? prev-price) "text-gray-900"
(> price prev-price) "text-green-600"
(< price prev-price) "text-red-600"
:else "text-gray-900")]
(str
(h/html
[:div.bg-white.rounded-2xl.shadow-sm.border.border-gray-200.p-6
[:div.text-center
[:p.text-4xl.font-bold.text-gray-900
[:p {:class (str "text-4xl font-bold " color)}
(str "$" (format "%,.2f" (double price)))]
[:p.text-xs.text-gray-400.mt-2
(str "Updated " recorded-at)]]])))
(str "Updated " (.format time-fmt recorded-at))]]]))))
(defn- format-sse [event data]
(str "event: " event "\n"
@@ -76,7 +89,8 @@
[["/"
{:get home-page}]
["/price/stream"
{:get (fn [req] (price-stream-handler opts req))}]])
{:get (fn [req] (price-stream-handler opts req))
:middleware []}]])
(defn route-data [opts]
(merge
+3 -1
View File
@@ -40,9 +40,11 @@
(swap! state assoc :last-write now)
(log/info "BTC price:" (str price))
(save-price! query-fn price)
(let [prev-price (:price @latest-price)]
(reset! latest-price
{:price price
:recorded-at (java.time.Instant/now)})))))
:prev-price prev-price
:recorded-at (java.time.Instant/now)}))))))
(catch Exception e
(log/error e "Failed to parse Binance message")))))
(let [^CompletionStage cf (CompletableFuture/completedFuture nil)]