|
@@ -12,7 +12,8 @@
|
|
|
// NOTE: the bubbletea framework and subsequent "bubble" concept are beyond the
|
|
// NOTE: the bubbletea framework and subsequent "bubble" concept are beyond the
|
|
|
// scope of this documentation. For more, see the Readme.
|
|
// scope of this documentation. For more, see the Readme.
|
|
|
//
|
|
//
|
|
|
-// Pingo defines a constructor function for the Model. It takes three arguments:
|
|
|
|
|
|
|
+// Pingo defines a constructor function for the Peak bubble. It takes three
|
|
|
|
|
+// arguments:
|
|
|
//
|
|
//
|
|
|
// - addresses([]string): the hosts to ping. The length must be greater than
|
|
// - addresses([]string): the hosts to ping. The length must be greater than
|
|
|
// or equal to 1
|
|
// or equal to 1
|
|
@@ -27,30 +28,14 @@
|
|
|
//
|
|
//
|
|
|
// NOTE: chartHeight is ignored when only one address or host is provided
|
|
// NOTE: chartHeight is ignored when only one address or host is provided
|
|
|
//
|
|
//
|
|
|
-// For more, please please see InitialModel()
|
|
|
|
|
|
|
+// For more, please please see InitialPeakBubble()
|
|
|
//
|
|
//
|
|
|
-// Pingo defines two bubbletea.Cmd functions:
|
|
|
|
|
-//
|
|
|
|
|
-// - Model.Tick() tea.Cmd: emits a bubbletea.TickMsg after the time.Duration
|
|
|
|
|
-// specified via Model.UpdateSpeed
|
|
|
|
|
-//
|
|
|
|
|
-// NOTE: Model.Tick() is optional. If you choose not to use Model.Tick(),
|
|
|
|
|
-// it is recommended to enforce some minimum rate mechanism for calling
|
|
|
|
|
-// Poll(). Some servers maintain a ping rate limit, and is is possible to
|
|
|
|
|
-// exceed this rate trivially with the Poll() function. (Trust us, we know
|
|
|
|
|
-// from experience)
|
|
|
|
|
-//
|
|
|
|
|
-// NOTE: Model.Tick() is automatically emit by Model.Init() - therefore,
|
|
|
|
|
-// you can control the timing of polling by overloading the Init function.
|
|
|
|
|
|
|
+// Pingo defines the following bubbletea.Cmd functions:
|
|
|
//
|
|
//
|
|
|
// - Model.Poll() tea.Msg: used to asynchronously call all Model.Addresses.Poll()
|
|
// - Model.Poll() tea.Msg: used to asynchronously call all Model.Addresses.Poll()
|
|
|
// functions.
|
|
// functions.
|
|
|
//
|
|
//
|
|
|
-// NOTE: Model.Poll() is automatically injected into the Model.Update()
|
|
|
|
|
-// life cycle after Model.Tick() resolves by Model.Update(). Functionally,
|
|
|
|
|
-// this means you can omit either Model.Tick() or Model.Poll(), respectively.
|
|
|
|
|
-//
|
|
|
|
|
-// For more, see the Readme or ./examples
|
|
|
|
|
|
|
+// For an example implementation, see cmd/pingo.go
|
|
|
package pingo
|
|
package pingo
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
@@ -111,16 +96,17 @@ type ( // tea.Msg signatures
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-// Bubbletea model
|
|
|
|
|
-type Model struct {
|
|
|
|
|
|
|
+// Bubbletea bubble
|
|
|
|
|
+type Peak struct {
|
|
|
Addresses []Address // as defined in internal/tui/types.go
|
|
Addresses []Address // as defined in internal/tui/types.go
|
|
|
ChartHeight int
|
|
ChartHeight int
|
|
|
Height int
|
|
Height int
|
|
|
Width int
|
|
Width int
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func InitialModel(addresses []string, width, height, chartHeight int) Model {
|
|
|
|
|
- var model Model
|
|
|
|
|
|
|
+// Instantiates a Peak bubble with the provided arguments.
|
|
|
|
|
+func InitialPeakBubble(addresses []string, width, height, chartHeight int) Peak {
|
|
|
|
|
+ var model Peak
|
|
|
model.ChartHeight = chartHeight
|
|
model.ChartHeight = chartHeight
|
|
|
model.Width = width
|
|
model.Width = width
|
|
|
model.Height = height
|
|
model.Height = height
|
|
@@ -134,58 +120,60 @@ func InitialModel(addresses []string, width, height, chartHeight int) Model {
|
|
|
return model
|
|
return model
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (m Model) Init() tea.Cmd {
|
|
|
|
|
- return m.Poll()
|
|
|
|
|
|
|
+// Provides initial polling for the bubble. Returns the result of Peak.Poll
|
|
|
|
|
+func (p Peak) Init() tea.Cmd {
|
|
|
|
|
+ return p.Poll()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
|
|
|
|
+// The update function for the Peak bubble.
|
|
|
|
|
+func (p Peak) Update(msg tea.Msg) (Peak, tea.Cmd) {
|
|
|
var cmd tea.Cmd
|
|
var cmd tea.Cmd
|
|
|
var cmds []tea.Cmd
|
|
var cmds []tea.Cmd
|
|
|
|
|
|
|
|
switch msg := msg.(type) {
|
|
switch msg := msg.(type) {
|
|
|
case pollResultMsg:
|
|
case pollResultMsg:
|
|
|
- m.Addresses[msg.index].Results = msg.results
|
|
|
|
|
|
|
+ p.Addresses[msg.index].Results = msg.results
|
|
|
}
|
|
}
|
|
|
- for i := range m.Addresses {
|
|
|
|
|
- m.Addresses[i].MaxResults = m.Width
|
|
|
|
|
|
|
+ for i := range p.Addresses {
|
|
|
|
|
+ p.Addresses[i].MaxResults = p.Width
|
|
|
}
|
|
}
|
|
|
cmds = append(cmds, cmd)
|
|
cmds = append(cmds, cmd)
|
|
|
|
|
|
|
|
- return m, tea.Batch(cmds...)
|
|
|
|
|
|
|
+ return p, tea.Batch(cmds...)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (m Model) View() tea.View {
|
|
|
|
|
|
|
+func (p Peak) View() tea.View {
|
|
|
var content string
|
|
var content string
|
|
|
- for _, address := range m.Addresses {
|
|
|
|
|
|
|
+ for _, address := range p.Addresses {
|
|
|
if len(address.Results) == 0 {
|
|
if len(address.Results) == 0 {
|
|
|
content = content + fmt.Sprintf("\n%s\tloading...", headerStyle.Render(address.Address))
|
|
content = content + fmt.Sprintf("\n%s\tloading...", headerStyle.Render(address.Address))
|
|
|
- } else if m.Width != 0 && m.Height != 0 {
|
|
|
|
|
|
|
+ } else if p.Width != 0 && p.Height != 0 {
|
|
|
if slices.Contains(address.Results, -1) {
|
|
if slices.Contains(address.Results, -1) {
|
|
|
content = content + fmt.Sprintf("\n%s",
|
|
content = content + fmt.Sprintf("\n%s",
|
|
|
- blockStyle.Width(m.Width).Render(headerStyle.Render(
|
|
|
|
|
|
|
+ blockStyle.Width(p.Width).Render(headerStyle.Render(
|
|
|
secondaryColor.Render(address.Address),
|
|
secondaryColor.Render(address.Address),
|
|
|
infoStyle.Render("(connection unstable)"),
|
|
infoStyle.Render("(connection unstable)"),
|
|
|
),
|
|
),
|
|
|
))
|
|
))
|
|
|
} else {
|
|
} else {
|
|
|
content = content + fmt.Sprintf("\n%s",
|
|
content = content + fmt.Sprintf("\n%s",
|
|
|
- blockStyle.Width(m.Width).Render(headerStyle.Render(address.Address)))
|
|
|
|
|
|
|
+ blockStyle.Width(p.Width).Render(headerStyle.Render(address.Address)))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Linechart
|
|
// Linechart
|
|
|
// set chartHeight - vertical margin
|
|
// set chartHeight - vertical margin
|
|
|
- // chartHeight := m.Height - 2 // m.getVerticalMargin()
|
|
|
|
|
|
|
+ // chartHeight := p.Height - 2 // p.getVerticalMargin()
|
|
|
|
|
|
|
|
var slc streamlinechart.Model
|
|
var slc streamlinechart.Model
|
|
|
|
|
|
|
|
- if m.ChartHeight == 0 && len(m.Addresses) == 1 { // catch user specified fullscreen
|
|
|
|
|
|
|
+ if p.ChartHeight == 0 && len(p.Addresses) == 1 { // catch user specified fullscreen
|
|
|
// render chart at fullscreen
|
|
// render chart at fullscreen
|
|
|
- slc = streamlinechart.New(m.Width, m.Height-1)
|
|
|
|
|
- } else if m.ChartHeight == 0 && len(m.Addresses) > 1 { // catch user specified fullscreen
|
|
|
|
|
|
|
+ slc = streamlinechart.New(p.Width, p.Height-1)
|
|
|
|
|
+ } else if p.ChartHeight == 0 && len(p.Addresses) > 1 { // catch user specified fullscreen
|
|
|
// render chart at fullscreen minus a few lines to hint at scrolling
|
|
// render chart at fullscreen minus a few lines to hint at scrolling
|
|
|
- slc = streamlinechart.New(m.Width, m.Height-2)
|
|
|
|
|
|
|
+ slc = streamlinechart.New(p.Width, p.Height-2)
|
|
|
} else {
|
|
} else {
|
|
|
- slc = streamlinechart.New(m.Width, m.ChartHeight-1)
|
|
|
|
|
|
|
+ slc = streamlinechart.New(p.Width, p.ChartHeight-1)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for _, v := range address.Results {
|
|
for _, v := range address.Results {
|
|
@@ -203,11 +191,12 @@ func (m Model) View() tea.View {
|
|
|
return v
|
|
return v
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// Returns a batched set of tea.Cmd functions for each address.
|
|
|
|
|
-func (m Model) Poll() tea.Cmd {
|
|
|
|
|
|
|
+// Returns a batched set of tea.Cmd that call Address.Poll functions for each
|
|
|
|
|
+// address.
|
|
|
|
|
+func (p Peak) Poll() tea.Cmd {
|
|
|
var cmds []tea.Cmd
|
|
var cmds []tea.Cmd
|
|
|
|
|
|
|
|
- for i, element := range m.Addresses {
|
|
|
|
|
|
|
+ for i, element := range p.Addresses {
|
|
|
cmds = append(cmds, func() tea.Msg {
|
|
cmds = append(cmds, func() tea.Msg {
|
|
|
results, err := element.Poll()
|
|
results, err := element.Poll()
|
|
|
return pollResultMsg{results: results, err: err, index: i}
|
|
return pollResultMsg{results: results, err: err, index: i}
|