From 4ddae6203a6b2ad01be61996ec840acf708901b4 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 4 Sep 2021 11:02:01 -0300 Subject: [PATCH 1/6] feat: simple timer component Signed-off-by: Carlos Alexandro Becker --- timer/timer.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 timer/timer.go diff --git a/timer/timer.go b/timer/timer.go new file mode 100644 index 00000000..4bb16cd5 --- /dev/null +++ b/timer/timer.go @@ -0,0 +1,52 @@ +// Package timer provides a simple timeout component that ticks every second. +package timer + +import ( + "time" + + tea "github.com/charmbracelet/bubbletea" +) + +type tickMsg struct{} + +// Model of the timer component. +type Model struct { + // How long until the timer expires. + Timeout time.Duration + + // What to do when the timer expires. + OnTimeout func() tea.Cmd +} + +// Init starts the timer. +func (m Model) Init() tea.Cmd { + return m.tick() +} + +// Update handles the timer tick. +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg.(type) { + case tickMsg: + m.Timeout -= time.Second + if m.Timeout <= 0 { + if m.OnTimeout != nil { + return m, m.OnTimeout() + } + return m, nil + } + return m, m.tick() + } + + return m, nil +} + +// View of the timer component. +func (m Model) View() string { + return m.Timeout.String() +} + +func (m Model) tick() tea.Cmd { + return tea.Every(time.Second, func(_ time.Time) tea.Msg { + return tickMsg{} + }) +} From 404e61101965e0397f2e354abfb42ddcec2112f6 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 4 Sep 2021 11:26:17 -0300 Subject: [PATCH 2/6] fix: tick Signed-off-by: Carlos Alexandro Becker --- timer/timer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timer/timer.go b/timer/timer.go index 4bb16cd5..3e769137 100644 --- a/timer/timer.go +++ b/timer/timer.go @@ -46,7 +46,7 @@ func (m Model) View() string { } func (m Model) tick() tea.Cmd { - return tea.Every(time.Second, func(_ time.Time) tea.Msg { + return tea.Tick(time.Second, func(_ time.Time) tea.Msg { return tickMsg{} }) } From 43a68b98c7b107fed3eb9777b2297065b73b1275 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 4 Sep 2021 17:33:44 -0300 Subject: [PATCH 3/6] code review Signed-off-by: Carlos Alexandro Becker --- timer/timer.go | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/timer/timer.go b/timer/timer.go index 3e769137..66634a54 100644 --- a/timer/timer.go +++ b/timer/timer.go @@ -7,34 +7,53 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -type tickMsg struct{} +// TickMsg is a message that is sent on every timer tick. +type TickMsg struct{} + +// TimeoutMsg is a message that is sent once when the timer times out. +type TimeoutMsg struct{} // Model of the timer component. type Model struct { // How long until the timer expires. Timeout time.Duration - // What to do when the timer expires. - OnTimeout func() tea.Cmd + // How long to wait before every tick. Defaults to 1 second. + TickEvery time.Duration +} + +// NewWithInterval creates a new timer with the given timeout and tick interval. +func NewWithInterval(timeout, interval time.Duration) Model { + return Model{ + Timeout: timeout, + TickEvery: interval, + } +} + +// New creates a new timer with the given timeout and default 1s interval. +func New(timeout time.Duration) Model { + return NewWithInterval(timeout, time.Second) } // Init starts the timer. func (m Model) Init() tea.Cmd { - return m.tick() + if m.TickEvery == 0 { + m.TickEvery = time.Second + } + return tick(m.TickEvery) } // Update handles the timer tick. -func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { switch msg.(type) { - case tickMsg: - m.Timeout -= time.Second + case TickMsg: + m.Timeout -= m.TickEvery if m.Timeout <= 0 { - if m.OnTimeout != nil { - return m, m.OnTimeout() + return m, func() tea.Msg { + return TimeoutMsg{} } - return m, nil } - return m, m.tick() + return m, tick(m.TickEvery) } return m, nil @@ -45,8 +64,8 @@ func (m Model) View() string { return m.Timeout.String() } -func (m Model) tick() tea.Cmd { - return tea.Tick(time.Second, func(_ time.Time) tea.Msg { - return tickMsg{} +func tick(d time.Duration) tea.Cmd { + return tea.Tick(d, func(_ time.Time) tea.Msg { + return TickMsg{} }) } From 3d5be561beeb9e9f00344154bc10f1bc52c19e1f Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 4 Sep 2021 17:36:30 -0300 Subject: [PATCH 4/6] godoc fix Signed-off-by: Carlos Alexandro Becker --- timer/timer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timer/timer.go b/timer/timer.go index 66634a54..14a3af40 100644 --- a/timer/timer.go +++ b/timer/timer.go @@ -1,4 +1,4 @@ -// Package timer provides a simple timeout component that ticks every second. +// Package timer provides a simple timeout component. package timer import ( From c254f6ce6fc3434c1f11beb2d5171727b56b9c3a Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 4 Sep 2021 17:38:00 -0300 Subject: [PATCH 5/6] fix init Signed-off-by: Carlos Alexandro Becker --- timer/timer.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/timer/timer.go b/timer/timer.go index 14a3af40..ab8b13f8 100644 --- a/timer/timer.go +++ b/timer/timer.go @@ -37,9 +37,6 @@ func New(timeout time.Duration) Model { // Init starts the timer. func (m Model) Init() tea.Cmd { - if m.TickEvery == 0 { - m.TickEvery = time.Second - } return tick(m.TickEvery) } From 9a7fcdaad65b29254ec685a568bf7c4b2a15418f Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 7 Sep 2021 10:36:47 -0300 Subject: [PATCH 6/6] fix: rename to interval Signed-off-by: Carlos Alexandro Becker --- timer/timer.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/timer/timer.go b/timer/timer.go index ab8b13f8..5de4eee5 100644 --- a/timer/timer.go +++ b/timer/timer.go @@ -19,14 +19,14 @@ type Model struct { Timeout time.Duration // How long to wait before every tick. Defaults to 1 second. - TickEvery time.Duration + Interval time.Duration } // NewWithInterval creates a new timer with the given timeout and tick interval. func NewWithInterval(timeout, interval time.Duration) Model { return Model{ - Timeout: timeout, - TickEvery: interval, + Timeout: timeout, + Interval: interval, } } @@ -37,20 +37,20 @@ func New(timeout time.Duration) Model { // Init starts the timer. func (m Model) Init() tea.Cmd { - return tick(m.TickEvery) + return tick(m.Interval) } // Update handles the timer tick. func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { switch msg.(type) { case TickMsg: - m.Timeout -= m.TickEvery + m.Timeout -= m.Interval if m.Timeout <= 0 { return m, func() tea.Msg { return TimeoutMsg{} } } - return m, tick(m.TickEvery) + return m, tick(m.Interval) } return m, nil