Explorar el Código

Refactored "content()" to "Render()" for extensibility

arianagiroux hace 1 semana
padre
commit
e65a202d89
Se han modificado 1 ficheros con 97 adiciones y 70 borrados
  1. 97 70
      tui.go

+ 97 - 70
tui.go

@@ -1,5 +1,9 @@
-// TODO(doc): document TUI lifecycle
-// TODO(test): write unittests for types.go
+// TODO document TUI lifecycle
+// TODO viewport separation
+//
+//	BLOCKERS: header/footer height func
+//
+// TODO header/footer height func
 package pingo
 
 import (
@@ -14,7 +18,6 @@ import (
 )
 
 // Style Defintions
-
 var (
 	// A style for chart headers
 	headerStyle = lipgloss.NewStyle().
@@ -33,6 +36,27 @@ var (
 	// A style for the primary colour
 	//  primaryColor = lipgloss.NewStyle().
 	// 	Foreground(lipgloss.Color("#f0f3f5"))
+
+	// A style for handling center-aligning
+	blockStyle = lipgloss.NewStyle().
+			Align(lipgloss.Center)
+
+	// borderStyle = lipgloss.NewStyle().
+	// 		BorderForeground(lipgloss.Color("8")).
+	// 	// Padding(1, 2).
+	// 	BorderStyle(lipgloss.NormalBorder())
+
+	// footer styles
+	titleStyle = lipgloss.NewStyle().
+			Align(lipgloss.Center). // implies consumer functions will apply a width
+			Italic(true).
+			Faint(true)
+
+	// footer style
+	footerStyle = lipgloss.NewStyle().
+			Align(lipgloss.Center). // implies consumer functions will apply a width
+			Italic(true).
+			Faint(true)
 )
 
 type ( // tea.Msg signatures
@@ -51,6 +75,8 @@ type Model struct {
 	viewport    viewport.Model
 	UpdateSpeed time.Duration
 	ChartHeight int
+	ModelHeight int
+	ModelWidth  int
 }
 
 func InitialModel(addresses []string, speed time.Duration, chartHeight int) Model {
@@ -78,51 +104,6 @@ func (m Model) Tick() tea.Cmd {
 	})
 }
 
-func (m Model) content() string {
-	var blockStyle = lipgloss.NewStyle().
-		Width(m.width).
-		Align(lipgloss.Center)
-
-	output := "\n"
-	for _, address := range m.Addresses {
-		if len(address.results) == 0 {
-			output = output + fmt.Sprintf("%s\tloading...", headerStyle.Render(address.Address))
-
-		} else if m.viewport.Width() != 0 && m.viewport.Height() != 0 {
-			if slices.Contains(address.results, -1) {
-				output = output + blockStyle.Render(headerStyle.Render(
-					fmt.Sprintf("\n%s\t%s",
-						secondaryColor.Render(address.Address),
-						infoStyle.Render("(connection unstable)"),
-					),
-				))
-			} else {
-				output = output + fmt.Sprintf("\n%s",
-					blockStyle.Render(headerStyle.Render(address.Address)))
-			}
-
-			// Linechart
-			viewportHeight := m.viewport.Height() - 4
-			var slc streamlinechart.Model
-			if m.ChartHeight == 0 && len(m.Addresses) == 1 {
-				slc = streamlinechart.New(m.width, viewportHeight)
-			} else if m.ChartHeight == 0 && len(m.Addresses) > 1 {
-				slc = streamlinechart.New(m.width, viewportHeight-5)
-			} else {
-				slc = streamlinechart.New(m.width, m.ChartHeight)
-			}
-
-			for _, v := range address.results {
-				slc.Push(v)
-			}
-			slc.Draw()
-			output = output + blockStyle.Render(fmt.Sprintf("\n%s\n", slc.View()))
-		}
-	}
-
-	return output
-}
-
 func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	var cmd tea.Cmd
 	var cmds []tea.Cmd
@@ -130,13 +111,21 @@ 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
+		if m.ModelWidth == 0 && m.ModelHeight == 0 {
+			m.viewport = viewport.New(
+				viewport.WithHeight(10),
+				viewport.WithWidth(msg.Width),
+			)
+		}
+
+		m.ModelWidth = msg.Width
+		m.ModelHeight = msg.Height
 		for i, address := range m.Addresses {
-			address.max_results = m.width
+			address.max_results = m.ModelWidth
 			m.Addresses[i] = address
 		}
-		m.viewport.SetHeight(msg.Height - 4)
-		m.viewport.SetWidth(msg.Width)
+		m.viewport.SetHeight(m.ModelHeight - m.getVerticalMargin())
+		m.viewport.SetWidth(m.ModelWidth)
 		m.viewport.YPosition = 1
 
 	case tea.KeyPressMsg:
@@ -151,14 +140,13 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		}
 
 	case tickMsg:
-		cmds = append(cmds, m.Tick())
-		cmds = append(cmds, m.Poll())
+		cmds = append(cmds, m.Tick(), m.Poll())
 
 	case pollResultMsg:
 		m.Addresses[msg.index].results = msg.results
 	}
 
-	m.viewport.SetContent(m.content())
+	m.viewport.SetContent(m.Render())
 	m.viewport, cmd = m.viewport.Update(msg)
 	cmds = append(cmds, cmd)
 	// cmds = append(cmds, m.Poll)
@@ -167,27 +155,66 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 }
 
 func (m Model) View() tea.View {
-	var headerStyle = lipgloss.NewStyle().
-		Width(m.width).
-		Align(lipgloss.Center).
-		Italic(true).
-		Faint(true)
-
-	var footerStyle = lipgloss.NewStyle().
-		Width(m.width).
-		Align(lipgloss.Center).
-		Italic(true).
-		Faint(true)
-
-	header := headerStyle.Render("pingo v0")
-	footer := footerStyle.Render("\nj/k: down/up\t|\tq/ctrl-c/esc: quit\n")
-	content := fmt.Sprintf("\n%s\n%s\n%s", header, m.viewport.View(), footer)
+	content := fmt.Sprintf("%s%s\n%s", m.header(), m.viewport.View(), m.footer())
 
 	var v tea.View
 	v.SetContent(content)
 	v.AltScreen = true
 	return v
 }
+func (m Model) Render() string {
+	var output 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 {
+			if slices.Contains(address.results, -1) {
+				output = output + blockStyle.Width(m.ModelWidth).Render(headerStyle.Render(
+					fmt.Sprintf("\n%s\t%s",
+						secondaryColor.Render(address.Address),
+						infoStyle.Render("(connection unstable)"),
+					),
+				))
+			} else {
+				output = output + fmt.Sprintf("\n%s",
+					blockStyle.Width(m.ModelWidth).Render(headerStyle.Render(address.Address)))
+			}
+
+			// Linechart
+			// set chartHeight - vertical margin
+			chartHeight := m.ModelHeight - 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(80, 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)
+			} else {
+				slc = streamlinechart.New(m.ModelWidth, m.ChartHeight)
+			}
+
+			for _, v := range address.results {
+				slc.Push(v)
+			}
+
+			slc.Draw()
+			output = output + fmt.Sprintf("\n%s", slc.View())
+		}
+	}
+
+	return output
+}
+
+func (m Model) header() string { return titleStyle.Width(m.ModelWidth).Render("pingo v0") }
+
+func (m Model) footer() string {
+	return footerStyle.Width(m.ModelWidth).Render("j/k: down/up\t|\tq/ctrl-c/esc: quit")
+}
+
+func (m Model) getVerticalMargin() int { return lipgloss.Height(m.header() + m.footer()) }
 
 // Returns a batched set of tea.Cmd functions for each address.
 func (m Model) Poll() tea.Cmd {