Liking cljdoc? Tell your friends :D

Timer

Countdown timer component with start/stop controls and formatted display.

Quick Example

(require '[charm.components.timer :as timer])

(def my-timer (timer/timer :timeout 60000))  ; 60 seconds

;; Initialize to start countdown
(let [[t cmd] (timer/timer-init my-timer)]
  ;; t is ready, cmd starts the tick loop
  )

;; In update function
(let [[t cmd] (timer/timer-update t msg)]
  ;; Handle timer ticks
  )

;; In view function
(timer/timer-view t)  ; => "1:00"

Creation Options

(timer/timer & options)
OptionTypeDefaultDescription
:timeoutint0Time in milliseconds
:intervalint1000Tick interval in milliseconds
:runningbooleantrueStart running immediately
:stylestylenilStyle for timer display
:idanyrandomUnique identifier

Functions

timer-init

(timer/timer-init t) ; => [timer cmd]

Initialize the timer. Returns command to start ticking if :running is true.

timer-update

(timer/timer-update t msg) ; => [timer cmd]

Handle tick messages. Decrements timeout and continues ticking until timeout reaches 0.

timer-view

(timer/timer-view t) ; => "1:00"

Render the timer as formatted duration:

  • 5s for seconds only
  • 1:30 for minutes and seconds
  • 1:30:00 for hours, minutes, and seconds

Control Functions

;; Start the timer, returns [timer cmd]
(timer/start t)

;; Stop the timer, returns [timer nil]
(timer/stop t)

;; Toggle running state, returns [timer cmd-or-nil]
(timer/toggle t)

;; Reset to a timeout value, returns [timer cmd]
(timer/reset t 60000)

Accessors

(timer/timeout t)   ; Get remaining ms
(timer/interval t)  ; Get tick interval
(timer/running? t)  ; Check if running
(timer/timed-out? t) ; Check if <= 0

Full Example

(ns my-app
  (:require
   [charm.components.timer :as timer]
   [charm.message :as msg]
   [charm.program :as program]))

(def initial-time 30000)  ; 30 seconds

(defn init []
  (let [[t cmd] (timer/timer-init
                 (timer/timer :timeout initial-time
                              :interval 100
                              :running false))]
    [{:timer t
      :initial-time initial-time}
     cmd]))

(defn update-fn [state msg]
  (cond
    (msg/key-match? msg "q")
    [state program/quit-cmd]

    ;; Space to toggle
    (msg/key-match? msg " ")
    (let [[t cmd] (timer/toggle (:timer state))]
      [(assoc state :timer t) cmd])

    ;; R to reset
    (msg/key-match? msg "r")
    (let [[t cmd] (timer/reset (:timer state) (:initial-time state))]
      [(assoc state :timer t) cmd])

    ;; Handle timer ticks
    :else
    (let [[t cmd] (timer/timer-update (:timer state) msg)]
      [(assoc state :timer t) cmd])))

(defn view [state]
  (let [t (:timer state)
        status (cond
                 (timer/timed-out? t) "Time's up!"
                 (timer/running? t) "Running"
                 :else "Paused")]
    (str "Timer: " (timer/timer-view t) "\n"
         "Status: " status "\n\n"
         "Space: start/stop  R: reset  Q: quit")))

(program/run {:init init :update update-fn :view view :alt-screen true})

Styled Timer

(timer/timer :timeout 60000
             :style (style/style :fg style/cyan
                                 :bold true
                                 :padding [1 2]
                                 :border border/rounded))

Timer Events

The timer sends these message types:

;; Tick message (every interval)
{:type :timer-tick
 :timer-id <id>
 :tag <tag>}

;; Timeout message (when reaching 0)
{:type :timer-timeout
 :timer-id <id>}

Check if a message is for a specific timer:

(timer/for-timer? t msg) ; => boolean

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close