84 lines
2.4 KiB
Clojure
84 lines
2.4 KiB
Clojure
(ns examples.timer
|
|
"Countdown timer example - demonstrates async commands.
|
|
Mirrors bubbletea's stopwatch/timer examples."
|
|
(:require [tui.core :as tui]
|
|
[tui.events :as ev]))
|
|
|
|
;; === Model ===
|
|
(def initial-model
|
|
{:seconds 10
|
|
:running true
|
|
:done false})
|
|
|
|
;; === Update ===
|
|
(defn update-fn [{:keys [model event]}]
|
|
(cond
|
|
;; Quit
|
|
(or (ev/key= event \q)
|
|
(ev/key= event \c #{:ctrl}))
|
|
{:model model :events [(ev/quit)]}
|
|
|
|
;; Timer tick - decrement timer
|
|
(= (:type event) :timer-tick)
|
|
(if (:running model)
|
|
(let [new-seconds (dec (:seconds model))]
|
|
(if (<= new-seconds 0)
|
|
;; Timer done
|
|
{:model (assoc model :seconds 0 :done true :running false)}
|
|
;; Continue countdown
|
|
{:model (assoc model :seconds new-seconds)
|
|
:events [(ev/delayed-event 1000 {:type :timer-tick})]}))
|
|
{:model model})
|
|
|
|
;; Space - pause/resume
|
|
(ev/key= event \space)
|
|
(let [new-running (not (:running model))]
|
|
{:model (assoc model :running new-running)
|
|
:events (when new-running [(ev/delayed-event 1000 {:type :timer-tick})])})
|
|
|
|
;; r - reset
|
|
(ev/key= event \r)
|
|
{:model (assoc model :seconds 10 :done false :running true)
|
|
:events [(ev/delayed-event 1000 {:type :timer-tick})]}
|
|
|
|
:else
|
|
{:model model}))
|
|
|
|
;; === View ===
|
|
(defn format-time [seconds]
|
|
(let [mins (quot seconds 60)
|
|
secs (mod seconds 60)]
|
|
(format "%02d:%02d" mins secs)))
|
|
|
|
(defn view [{:keys [seconds running done]}]
|
|
[:col {:gap 1}
|
|
[:box {:border :rounded :padding [1 2]}
|
|
[:col
|
|
[:text {:bold true} "Countdown Timer"]
|
|
[:text ""]
|
|
[:text {:fg (cond
|
|
done :green
|
|
(< seconds 5) :red
|
|
:else :cyan)
|
|
:bold true}
|
|
(if done
|
|
"Time's up!"
|
|
(format-time seconds))]
|
|
[:text ""]
|
|
[:text {:fg :gray}
|
|
(cond
|
|
done "Press r to restart"
|
|
running "Running..."
|
|
:else "Paused")]]]
|
|
[:text {:fg :gray} "space: pause/resume r: reset q: quit"]])
|
|
|
|
;; === Main ===
|
|
(defn -main [& _args]
|
|
(println "Starting timer...")
|
|
(let [final-model (tui/run {:init initial-model
|
|
:update update-fn
|
|
:view view
|
|
:init-events [(ev/delayed-event 1000 {:type :timer-tick})]})]
|
|
(when (:done final-model)
|
|
(println "Timer completed!"))))
|