package tracker import ( "container/heap" "time" ) const alertSpeed = 10 // units: fadeLevels per second const defaultAlertDuration = time.Second * 3 type ( Alert struct { Name string Priority AlertPriority Message string Duration time.Duration FadeLevel float64 } AlertPriority int AlertYieldFunc func(index int, alert Alert) bool Alerts Model ) const ( None AlertPriority = iota Info Warning Error ) // Model methods func (m *Model) Alerts() *Alerts { return (*Alerts)(m) } // Alerts methods func (m *Alerts) Iterate(yield func(index int, alert Alert) bool) { for i, a := range m.alerts { if !yield(i, a) { break } } } func (m *Alerts) Update(d time.Duration) (animating bool) { for i := len(m.alerts) - 1; i >= 0; i-- { if m.alerts[i].Duration >= d { m.alerts[i].Duration -= d if m.alerts[i].FadeLevel < 1 { animating = true m.alerts[i].FadeLevel += float64(alertSpeed*d) / float64(time.Second) if m.alerts[i].FadeLevel > 1 { m.alerts[i].FadeLevel = 1 } } } else { m.alerts[i].Duration = 0 m.alerts[i].FadeLevel -= float64(alertSpeed*d) / float64(time.Second) animating = true if m.alerts[i].FadeLevel < 0 { heap.Remove(m, i) } } } return } func (m *Alerts) Add(message string, priority AlertPriority) { m.AddAlert(Alert{ Priority: priority, Message: message, Duration: defaultAlertDuration, }) } func (m *Alerts) AddNamed(name, message string, priority AlertPriority) { m.AddAlert(Alert{ Name: name, Priority: priority, Message: message, Duration: defaultAlertDuration, }) } func (m *Alerts) AddAlert(a Alert) { for i := range m.alerts { if n := m.alerts[i].Name; n != "" && n == a.Name { a.FadeLevel = m.alerts[i].FadeLevel m.alerts[i] = a heap.Fix(m, i) return } } heap.Push(m, a) } func (m *Alerts) Push(x any) { m.alerts = append(m.alerts, x.(Alert)) } func (m *Alerts) Pop() any { old := m.alerts n := len(old) x := old[n-1] m.alerts = old[0 : n-1] return x } func (m Alerts) Len() int { return len(m.alerts) } func (m Alerts) Less(i, j int) bool { return m.alerts[i].Priority < m.alerts[j].Priority } func (m Alerts) Swap(i, j int) { m.alerts[i], m.alerts[j] = m.alerts[j], m.alerts[i] }