fix: debounce stopwatch and timer

This keeps them from ticking too fast.

Fixes #661.
This commit is contained in:
Christian Rocha
2024-11-05 22:06:53 -05:00
parent 20a65e5655
commit 730f5a29e2
2 changed files with 27 additions and 6 deletions
+16 -5
View File
@@ -23,7 +23,8 @@ type TickMsg struct {
// Note, however, that a stopwatch will reject ticks from other
// stopwatches, so it's safe to flow all TickMsgs through all stopwatches
// and have them still behave appropriately.
ID int
ID int
tag int
}
// StartStopMsg is sent when the stopwatch should start or stop.
@@ -41,6 +42,7 @@ type ResetMsg struct {
type Model struct {
d time.Duration
id int
tag int
running bool
// How long to wait before every tick. Defaults to 1 second.
@@ -75,7 +77,7 @@ func (m Model) Init() tea.Cmd {
func (m Model) Start() tea.Cmd {
return tea.Batch(func() tea.Msg {
return StartStopMsg{ID: m.id, running: true}
}, tick(m.id, m.Interval))
}, tick(m.id, m.tag, m.Interval))
}
// Stop stops the stopwatch.
@@ -122,8 +124,17 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
if !m.running || msg.ID != m.id {
break
}
// If a tag is set, and it's not the one we expect, reject the message.
// This prevents the stopwatch from receiving too many messages and
// thus ticking too fast.
if msg.tag > 0 && msg.tag != m.tag {
return m, nil
}
m.d += m.Interval
return m, tick(m.id, m.Interval)
m.tag++
return m, tick(m.id, m.tag, m.Interval)
}
return m, nil
@@ -139,8 +150,8 @@ func (m Model) View() string {
return m.d.String()
}
func tick(id int, d time.Duration) tea.Cmd {
func tick(id int, tag int, d time.Duration) tea.Cmd {
return tea.Tick(d, func(_ time.Time) tea.Msg {
return TickMsg{ID: id}
return TickMsg{ID: id, tag: tag}
})
}
+11 -1
View File
@@ -61,6 +61,8 @@ type TickMsg struct {
// Timeout returns whether or not this tick is a timeout tick. You can
// alternatively listen for TimeoutMsg.
Timeout bool
tag int
}
// TimeoutMsg is a message that is sent once when the timer times out.
@@ -80,6 +82,7 @@ type Model struct {
Interval time.Duration
id int
tag int
running bool
}
@@ -137,6 +140,13 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
break
}
// If a tag is set, and it's not the one we expect, reject the message.
// This prevents the ticker from receiving too many messages and
// thus ticking too fast.
if msg.tag > 0 && msg.tag != m.tag {
return m, nil
}
m.Timeout -= m.Interval
return m, tea.Batch(m.tick(), m.timedout())
}
@@ -166,7 +176,7 @@ func (m *Model) Toggle() tea.Cmd {
func (m Model) tick() tea.Cmd {
return tea.Tick(m.Interval, func(_ time.Time) tea.Msg {
return TickMsg{ID: m.id, Timeout: m.Timedout()}
return TickMsg{ID: m.id, tag: m.tag, Timeout: m.Timedout()}
})
}