init
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
(ns examples.http
|
||||
"HTTP request example - demonstrates async commands.
|
||||
Mirrors bubbletea's http example."
|
||||
(:require [tui.core :as tui]
|
||||
[clojure.java.io :as io])
|
||||
(:import [java.net URL HttpURLConnection]))
|
||||
|
||||
;; === HTTP Helpers ===
|
||||
(defn http-get
|
||||
"Simple HTTP GET request. Returns {:status code :body string} or {:error msg}"
|
||||
[url-str]
|
||||
(try
|
||||
(let [url (URL. url-str)
|
||||
conn ^HttpURLConnection (.openConnection url)]
|
||||
(.setRequestMethod conn "GET")
|
||||
(.setConnectTimeout conn 5000)
|
||||
(.setReadTimeout conn 5000)
|
||||
(let [status (.getResponseCode conn)
|
||||
body (with-open [r (io/reader (.getInputStream conn))]
|
||||
(slurp r))]
|
||||
{:status status :body body}))
|
||||
(catch Exception e
|
||||
{:error (.getMessage e)})))
|
||||
|
||||
;; === Model ===
|
||||
(def initial-model
|
||||
{:state :idle ; :idle, :loading, :success, :error
|
||||
:status nil
|
||||
:error nil
|
||||
:url "https://httpstat.us/200"})
|
||||
|
||||
;; === Commands ===
|
||||
(defn fetch-url [url]
|
||||
(fn []
|
||||
(let [result (http-get url)]
|
||||
(if (:error result)
|
||||
[:http-error (:error result)]
|
||||
[:http-success (:status result)]))))
|
||||
|
||||
;; === Update ===
|
||||
(defn update-model [{:keys [url] :as model} msg]
|
||||
(cond
|
||||
;; Quit
|
||||
(or (tui/key= msg "q")
|
||||
(tui/key= msg [:ctrl \c]))
|
||||
[model tui/quit]
|
||||
|
||||
;; Enter - start request
|
||||
(and (= (:state model) :idle)
|
||||
(tui/key= msg :enter))
|
||||
[(assoc model :state :loading) (fetch-url url)]
|
||||
|
||||
;; r - retry/reset
|
||||
(tui/key= msg "r")
|
||||
[(assoc model :state :idle :status nil :error nil) nil]
|
||||
|
||||
;; HTTP success
|
||||
(= (first msg) :http-success)
|
||||
[(assoc model :state :success :status (second msg)) nil]
|
||||
|
||||
;; HTTP error
|
||||
(= (first msg) :http-error)
|
||||
[(assoc model :state :error :error (second msg)) nil]
|
||||
|
||||
:else
|
||||
[model nil]))
|
||||
|
||||
;; === View ===
|
||||
(defn view [{:keys [state status error url]}]
|
||||
[:col {:gap 1}
|
||||
[:box {:border :rounded :padding [1 2]}
|
||||
[:col {:gap 1}
|
||||
[:text {:bold true} "HTTP Request Demo"]
|
||||
[:text ""]
|
||||
[:row {:gap 1}
|
||||
[:text {:fg :gray} "URL:"]
|
||||
[:text {:fg :cyan} url]]
|
||||
[:text ""]
|
||||
(case state
|
||||
:idle
|
||||
[:text {:fg :gray} "Press enter to fetch..."]
|
||||
|
||||
:loading
|
||||
[:row {:gap 1}
|
||||
[:text {:fg :yellow} "⠋"]
|
||||
[:text "Fetching..."]]
|
||||
|
||||
:success
|
||||
[:row {:gap 1}
|
||||
[:text {:fg :green} "✓"]
|
||||
[:text (str "Status: " status)]]
|
||||
|
||||
:error
|
||||
[:col
|
||||
[:row {:gap 1}
|
||||
[:text {:fg :red} "✗"]
|
||||
[:text {:fg :red} "Error:"]]
|
||||
[:text {:fg :red} error]])]]
|
||||
[:text {:fg :gray}
|
||||
(if (= state :idle)
|
||||
"enter: fetch q: quit"
|
||||
"r: retry q: quit")]])
|
||||
|
||||
;; === Main ===
|
||||
(defn -main [& _args]
|
||||
(println "Starting HTTP demo...")
|
||||
(let [final (tui/run {:init initial-model
|
||||
:update update-model
|
||||
:view view})]
|
||||
(when (= (:state final) :success)
|
||||
(println "Request completed with status:" (:status final)))))
|
||||
Reference in New Issue
Block a user