|
|
@@ -2,23 +2,31 @@ package tui
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "time"
|
|
|
|
|
|
"github.com/NimbleMarkets/ntcharts/linechart/streamlinechart"
|
|
|
+ "github.com/charmbracelet/bubbles/viewport"
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
|
)
|
|
|
|
|
|
// Bubbletea model
|
|
|
type Model struct {
|
|
|
- width int
|
|
|
- Addresses []Address // as defined in internal/tui/types.go
|
|
|
+ width int
|
|
|
+ Addresses []Address // as defined in internal/tui/types.go
|
|
|
+ viewport viewport.Model
|
|
|
+ UpdateSpeed time.Duration
|
|
|
}
|
|
|
|
|
|
-func InitialModel(addresses []string) Model {
|
|
|
+func InitialModel(addresses []string, speed time.Duration) Model {
|
|
|
var model Model
|
|
|
+ model.viewport = viewport.New(0, 0)
|
|
|
+ model.viewport.MouseWheelEnabled = true
|
|
|
+ model.UpdateSpeed = speed
|
|
|
+
|
|
|
for _, address := range addresses {
|
|
|
var addr Address
|
|
|
- addr.max_results = 999
|
|
|
+ addr.max_results = 80
|
|
|
addr.Address = address
|
|
|
model.Addresses = append(model.Addresses, addr)
|
|
|
}
|
|
|
@@ -26,29 +34,18 @@ func InitialModel(addresses []string) Model {
|
|
|
}
|
|
|
|
|
|
func (m Model) Init() tea.Cmd {
|
|
|
- return m.Poll
|
|
|
+ return m.Tick()
|
|
|
}
|
|
|
|
|
|
-func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
- switch msg := msg.(type) {
|
|
|
- // if case is KeyMsg (keypress)
|
|
|
- case tea.WindowSizeMsg:
|
|
|
- m.width = msg.Width
|
|
|
- for i, address := range m.Addresses {
|
|
|
- address.max_results = m.width
|
|
|
- m.Addresses[i] = address
|
|
|
- }
|
|
|
+type tickMsg time.Time
|
|
|
|
|
|
- case tea.KeyMsg:
|
|
|
- return m, tea.Quit
|
|
|
-
|
|
|
- case pollMsg:
|
|
|
- m.Poll()
|
|
|
- }
|
|
|
- return m, m.Poll
|
|
|
+func (m Model) Tick() tea.Cmd {
|
|
|
+ return tea.Tick(time.Millisecond*m.UpdateSpeed, func(t time.Time) tea.Msg {
|
|
|
+ return tickMsg(t)
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
-func (m Model) View() string {
|
|
|
+func (m Model) content() string {
|
|
|
var headerStyle = lipgloss.NewStyle().
|
|
|
Bold(true).
|
|
|
Italic(true)
|
|
|
@@ -57,28 +54,74 @@ func (m Model) View() string {
|
|
|
Width(m.width).
|
|
|
Align(lipgloss.Center)
|
|
|
|
|
|
- output := "Results:\n\n"
|
|
|
- for _, address := range m.Addresses {
|
|
|
+ var footerStyle = lipgloss.NewStyle().
|
|
|
+ Width(m.width).
|
|
|
+ Align(lipgloss.Center).
|
|
|
+ Italic(true).
|
|
|
+ Faint(true)
|
|
|
|
|
|
+ output := "\n"
|
|
|
+ for _, address := range m.Addresses {
|
|
|
if len(address.results) == 0 {
|
|
|
- output = output + fmt.Sprintf("%s\tloading...\n\n", headerStyle.Render(address.Address))
|
|
|
+ output = output + fmt.Sprintf("\n%s\tloading...\n\n", headerStyle.Render(address.Address))
|
|
|
} else {
|
|
|
- output = output + fmt.Sprintf("%s\n\n", blockStyle.Render(headerStyle.Render(address.Address)))
|
|
|
-
|
|
|
- if m.width > 0 {
|
|
|
- // Linechart
|
|
|
- slc := streamlinechart.New(m.width, 10)
|
|
|
- for _, v := range address.results {
|
|
|
- slc.Push(v)
|
|
|
- }
|
|
|
- slc.Draw()
|
|
|
- output = output + fmt.Sprintf("%s\n\n", slc.View())
|
|
|
+ output = output + fmt.Sprintf("\n%s\n\n", blockStyle.Render(headerStyle.Render(address.Address)))
|
|
|
+
|
|
|
+ // Linechart
|
|
|
+ slc := streamlinechart.New(m.width, 7)
|
|
|
+ for _, v := range address.results {
|
|
|
+ slc.Push(v)
|
|
|
}
|
|
|
+ slc.Draw()
|
|
|
+ output = output + blockStyle.Render(fmt.Sprintf("\n%s\n", slc.View()))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ output = output + footerStyle.Render("\n--------\npingo v0\n")
|
|
|
+
|
|
|
return output
|
|
|
}
|
|
|
+func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
+ var cmd tea.Cmd
|
|
|
+ var cmds []tea.Cmd
|
|
|
+
|
|
|
+ switch msg := msg.(type) {
|
|
|
+ // if case is KeyMsg (keypress)
|
|
|
+ case tea.WindowSizeMsg:
|
|
|
+ m.width = msg.Width
|
|
|
+ for i, address := range m.Addresses {
|
|
|
+ address.max_results = m.width
|
|
|
+ m.Addresses[i] = address
|
|
|
+ }
|
|
|
+ m.viewport.Height = msg.Height
|
|
|
+ m.viewport.Width = msg.Width
|
|
|
+ // m.viewport.YPosition = 0
|
|
|
+
|
|
|
+ case tea.KeyMsg:
|
|
|
+ if k := msg.String(); k == "j" { // scroll down
|
|
|
+ m.viewport.HalfViewDown()
|
|
|
+ } else if k == "k" { // scroll up
|
|
|
+ m.viewport.HalfViewUp()
|
|
|
+ } else {
|
|
|
+ return m, tea.Quit
|
|
|
+ }
|
|
|
+
|
|
|
+ case tickMsg:
|
|
|
+ cmds = append(cmds, m.Tick())
|
|
|
+ cmds = append(cmds, m.Poll)
|
|
|
+ }
|
|
|
+
|
|
|
+ m.viewport, cmd = m.viewport.Update(msg)
|
|
|
+ m.viewport.SetContent(m.content())
|
|
|
+ cmds = append(cmds, cmd)
|
|
|
+ // cmds = append(cmds, m.Poll)
|
|
|
+
|
|
|
+ return m, tea.Batch(cmds...)
|
|
|
+}
|
|
|
+
|
|
|
+func (m Model) View() string {
|
|
|
+ return fmt.Sprintf("\n%s\n", m.viewport.View())
|
|
|
+}
|
|
|
|
|
|
// A wrapper for the underlying [tui.Address.Poll] function. For each address in
|
|
|
// [tui.Model.Addresses], run its respective Poll function and update [tui.Model]
|
|
|
@@ -87,7 +130,8 @@ func (m Model) View() string {
|
|
|
func (m Model) Poll() tea.Msg {
|
|
|
for i, element := range m.Addresses {
|
|
|
element.Poll()
|
|
|
+ // element.results = append(element.results, -1)
|
|
|
m.Addresses[i] = element
|
|
|
}
|
|
|
- return true
|
|
|
+ return nil
|
|
|
}
|