package tui import ( "fmt" "github.com/NimbleMarkets/ntcharts/linechart/streamlinechart" 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 } func InitialModel(addresses []string) Model { var model Model for _, address := range addresses { var addr Address addr.max_results = 999 addr.Address = address model.Addresses = append(model.Addresses, addr) } return model } func (m Model) Init() tea.Cmd { return m.Poll } 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 } case tea.KeyMsg: return m, tea.Quit case pollMsg: m.Poll() } return m, m.Poll } func (m Model) View() string { var headerStyle = lipgloss.NewStyle(). Bold(true). Italic(true) var blockStyle = lipgloss.NewStyle(). Width(m.width). Align(lipgloss.Center) output := "Results:\n\n" for _, address := range m.Addresses { if len(address.results) == 0 { output = output + fmt.Sprintf("%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()) } } } return output } // 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] // // NOTE(async): this function fully blocks execution of the current thread. func (m Model) Poll() tea.Msg { for i, element := range m.Addresses { element.Poll() m.Addresses[i] = element } return true }