tui.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package tui
  2. import (
  3. "fmt"
  4. "github.com/NimbleMarkets/ntcharts/linechart/streamlinechart"
  5. tea "github.com/charmbracelet/bubbletea"
  6. )
  7. // Bubbletea model
  8. //
  9. // BUG(state): how do declare pointer here?
  10. type Model struct {
  11. Addresses []Address // as defined in internal/tui/types.go
  12. }
  13. func InitialModel(addresses []string, max_results int) Model {
  14. var model Model
  15. for _, address := range addresses {
  16. var addr Address
  17. addr.Address = address
  18. addr.max_results = max_results
  19. model.Addresses = append(model.Addresses, addr)
  20. }
  21. return model
  22. }
  23. func (m Model) Init() tea.Cmd {
  24. return m.Poll
  25. }
  26. func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
  27. switch msg.(type) {
  28. // if case is KeyMsg (keypress)
  29. case tea.KeyMsg:
  30. return m, tea.Quit
  31. // switch msg.String() {
  32. // case "ctrl+c", "q": // These keys should exit the program.
  33. // return m, tea.Quit
  34. // }
  35. case pollMsg:
  36. m.Poll()
  37. }
  38. return m, m.Poll
  39. }
  40. func (m Model) View() string {
  41. output := "Results:\n\n"
  42. for _, address := range m.Addresses {
  43. last := address.Last()
  44. if last == -1 {
  45. output = output + fmt.Sprintf("- %s\tloading...\n\n", address.Address)
  46. } else {
  47. output = output + fmt.Sprintf("- %s\n\n", address.Address)
  48. }
  49. // Linechart
  50. slc := streamlinechart.New(address.max_results, 10)
  51. for _, v := range address.results {
  52. slc.Push(v)
  53. }
  54. slc.Draw()
  55. output = output + fmt.Sprintf("%s\n\n", slc.View())
  56. }
  57. return output
  58. }
  59. // A wrapper for the underlying [tui.Address.Poll] function. For each address in
  60. // [tui.Model.Addresses], run its respective Poll function and update [tui.Model]
  61. //
  62. // NOTE(async): this function fully blocks execution of the current thread.
  63. func (m Model) Poll() tea.Msg {
  64. for i, element := range m.Addresses {
  65. element.Poll()
  66. m.Addresses[i] = element
  67. }
  68. return true
  69. }