Pārlūkot izejas kodu

Added filedocs to tui

arianagiroux 1 nedēļu atpakaļ
vecāks
revīzija
2f7c41a2ab
2 mainītis faili ar 69 papildinājumiem un 27 dzēšanām
  1. 65 23
      tui.go
  2. 4 4
      tui_test.go

+ 65 - 23
tui.go

@@ -1,9 +1,52 @@
-// TODO document TUI lifecycle
-// TODO viewport separation
+// Pingo defines an extensible TUI based on the bubbletea framework (v2). An
+// executable entry point is defined via cmd/pingo.go. For more on this topic,
+// see the Readme.
 //
-//	BLOCKERS: header/footer height func
+// The pingo TUI is a fully fledged and extensible "bubble" (read: widget) that
+// can be fully implemented as an element in further terminal applications.
 //
-// TODO header/footer height func
+// NOTE: the bubbletea framework and subsequent "bubble" concept are beyond the
+// scope of this documentation. For more, see the Readme.
+//
+// Pingo defines a constructor function for the Model. It takes three arguments:
+//
+//   - addresses([]string): the hosts to ping. The length must be greater than
+//     or equal to 1
+//
+//   - speed(time.Duration): the polling interval
+//
+//   - chartHeight(int): the desired height of the resulting charts. This
+//     argument is integral to ensuring desired rendering of charts, when
+//     displaying multiple hosts.
+//
+//     NOTE: if chartHeight is 0, the chart will render to Model.Height
+//
+//     NOTE: chartHeight is ignored when only one address or host is provided
+//
+// For more, please please see InitialModel()
+//
+// 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.
+//
+//   - Model.Poll() tea.Msg: used to asynchronously call all Model.Addresses.Poll()
+//     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
 package pingo
 
 import (
@@ -17,7 +60,7 @@ import (
 	"github.com/NimbleMarkets/ntcharts/linechart/streamlinechart"
 )
 
-// Style Defintions
+// Style Definitions
 var (
 	// A style for chart headers
 	headerStyle = lipgloss.NewStyle().
@@ -70,13 +113,12 @@ type ( // tea.Msg signatures
 
 // Bubbletea model
 type Model struct {
-	width       int
 	Addresses   []Address // as defined in internal/tui/types.go
 	viewport    viewport.Model
 	UpdateSpeed time.Duration
 	ChartHeight int
-	ModelHeight int
-	ModelWidth  int
+	Height      int
+	Width       int
 }
 
 func InitialModel(addresses []string, speed time.Duration, chartHeight int) Model {
@@ -111,21 +153,21 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	switch msg := msg.(type) {
 	// if case is KeyMsg (keypress)
 	case tea.WindowSizeMsg:
-		if m.ModelWidth == 0 && m.ModelHeight == 0 {
+		if m.Width == 0 && m.Height == 0 {
 			m.viewport = viewport.New(
 				viewport.WithHeight(10),
 				viewport.WithWidth(msg.Width),
 			)
 		}
 
-		m.ModelWidth = msg.Width
-		m.ModelHeight = msg.Height
+		m.Width = msg.Width
+		m.Height = msg.Height
 		for i, address := range m.Addresses {
-			address.MaxResults = m.ModelWidth
+			address.MaxResults = m.Width
 			m.Addresses[i] = address
 		}
-		m.viewport.SetHeight(m.ModelHeight - m.getVerticalMargin())
-		m.viewport.SetWidth(m.ModelWidth)
+		m.viewport.SetHeight(m.Height - m.getVerticalMargin())
+		m.viewport.SetWidth(m.Width)
 		m.viewport.YPosition = 1
 
 	case tea.KeyPressMsg:
@@ -167,9 +209,9 @@ func (m Model) Render() string {
 	for _, address := range m.Addresses {
 		if len(address.Results) == 0 {
 			output = output + fmt.Sprintf("\n%s\tloading...", headerStyle.Render(address.Address))
-		} else if m.ModelWidth != 0 && m.ModelHeight != 0 {
+		} else if m.Width != 0 && m.Height != 0 {
 			if slices.Contains(address.Results, -1) {
-				output = output + blockStyle.Width(m.ModelWidth).Render(headerStyle.Render(
+				output = output + blockStyle.Width(m.Width).Render(headerStyle.Render(
 					fmt.Sprintf("\n%s\t%s",
 						secondaryColor.Render(address.Address),
 						infoStyle.Render("(connection unstable)"),
@@ -177,23 +219,23 @@ func (m Model) Render() string {
 				))
 			} else {
 				output = output + fmt.Sprintf("\n%s",
-					blockStyle.Width(m.ModelWidth).Render(headerStyle.Render(address.Address)))
+					blockStyle.Width(m.Width).Render(headerStyle.Render(address.Address)))
 			}
 
 			// Linechart
 			// set chartHeight - vertical margin
-			chartHeight := m.ModelHeight - m.getVerticalMargin()
+			chartHeight := m.Height - m.getVerticalMargin()
 
 			var slc streamlinechart.Model
 
 			if m.ChartHeight == 0 && len(m.Addresses) == 1 { // catch user specified fullscreen
 				// render chart at fullscreen
-				slc = streamlinechart.New(m.ModelWidth, chartHeight)
+				slc = streamlinechart.New(m.Width, chartHeight)
 			} else if m.ChartHeight == 0 && len(m.Addresses) > 1 { // catch user specified fullscreen
 				// render chart at fullscreen minus a few lines to hint at scrolling
-				slc = streamlinechart.New(m.ModelWidth, chartHeight-5)
+				slc = streamlinechart.New(m.Width, chartHeight-5)
 			} else {
-				slc = streamlinechart.New(m.ModelWidth, m.ChartHeight)
+				slc = streamlinechart.New(m.Width, m.ChartHeight)
 			}
 
 			for _, v := range address.Results {
@@ -208,10 +250,10 @@ func (m Model) Render() string {
 	return output
 }
 
-func (m Model) header() string { return titleStyle.Width(m.ModelWidth).Render("pingo v0") }
+func (m Model) header() string { return titleStyle.Width(m.Width).Render("pingo v0") }
 
 func (m Model) footer() string {
-	return footerStyle.Width(m.ModelWidth).Render("j/k: down/up\t|\tq/ctrl-c/esc: quit")
+	return footerStyle.Width(m.Width).Render("j/k: down/up\t|\tq/ctrl-c/esc: quit")
 }
 
 func (m Model) getVerticalMargin() int { return lipgloss.Height(m.header() + m.footer()) }

+ 4 - 4
tui_test.go

@@ -89,8 +89,8 @@ func spawnTestModel(addresses []string, points []float64, width, height, cHeight
 	for i := range testModel.Addresses {
 		testModel.Addresses[i].Results = points
 	}
-	testModel.ModelWidth = width
-	testModel.ModelHeight = height
+	testModel.Width = width
+	testModel.Height = height
 
 	return testModel
 }
@@ -218,8 +218,8 @@ func Test_Model_getVerticalMargin(t *testing.T) {
 	speed := time.Second * 1
 	chartHeight := 10
 	testModel := InitialModel(addresses, speed, chartHeight)
-	testModel.ModelWidth = 20
-	testModel.ModelHeight = 20
+	testModel.Width = 20
+	testModel.Height = 20
 	result := testModel.getVerticalMargin()
 	assert.IsType(t, *new(int), result)
 	assert.Equal(t, 2, result)