소스 검색

Moved all code related to actually being a TUI to cmd/pingo.go

arianagiroux 1 주 전
부모
커밋
db721eb4bb
2개의 변경된 파일118개의 추가작업 그리고 97개의 파일을 삭제
  1. 84 6
      cmd/pingo.go
  2. 34 91
      tui.go

+ 84 - 6
cmd/pingo.go

@@ -12,11 +12,93 @@ import (
 	"pingo"
 	"time"
 
+	"charm.land/bubbles/v2/viewport"
 	tea "charm.land/bubbletea/v2"
+	"charm.land/lipgloss/v2"
 )
 
+type md struct {
+	viewport viewport.Model
+	p        pingo.Model
+}
+
+type timingMsg time.Time
+
+var (
+	// 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)
+)
+
+func (m md) Init() tea.Cmd {
+	return tea.Tick(100*time.Millisecond, func(t time.Time) tea.Msg { return timingMsg(t) })
+}
+
+func (m md) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+	var cmds []tea.Cmd
+	var cmd tea.Cmd
+
+	switch msg := msg.(type) {
+	case tea.WindowSizeMsg:
+		m.p.Width = msg.Width
+		m.p.Height = msg.Height
+		if m.viewport.Width() == 0 && m.viewport.Height() == 0 {
+			m.viewport = viewport.New(
+				viewport.WithHeight(msg.Height),
+				viewport.WithWidth(msg.Width),
+			)
+		}
+		m.viewport.SetHeight(msg.Height - m.getVerticalMargin())
+		m.viewport.SetWidth(msg.Width)
+		m.viewport.YPosition = 1
+	case tea.KeyPressMsg:
+		k := msg.String()
+		if k == "ctrl+c" {
+			return m, tea.Quit
+		}
+	case timingMsg:
+		cmd = tea.Tick(100*time.Millisecond, func(t time.Time) tea.Msg { return timingMsg(t) })
+		cmds = append(cmds, cmd, m.p.Poll())
+	}
+
+	m.viewport.SetContent(m.p.View().Content)
+	m.viewport, cmd = m.viewport.Update(msg)
+	cmds = append(cmds, cmd)
+
+	m.p, cmd = m.p.Update(msg)
+	cmds = append(cmds, cmd)
+
+	return m, tea.Batch(cmds...)
+}
+
+func (m md) View() tea.View {
+	m.viewport.SetContent(m.p.View().Content)
+	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 md) header() string { return titleStyle.Width(m.viewport.Width()).Render("pingo v0") }
+
+func (m md) footer() string {
+	return footerStyle.Width(m.viewport.Width()).Render("j/k: down/up\t|\tq/ctrl-c/esc: quit")
+}
+
+func (m md) getVerticalMargin() int { return lipgloss.Height(m.header() + m.footer()) }
+
 func main() {
-	speed := flag.Int("s", 80, "the speed with which the UI runs")
+	// speed := flag.Int("s", 80, "the speed with which the UI runs")
 	chartHeight := flag.Int("h", 0,
 		"the height of the latency chart. set to 0 to render charts full screen.")
 	flag.Parse()
@@ -26,12 +108,8 @@ func main() {
 		fmt.Println("Must specify hosts!")
 		return
 	}
-	var model = pingo.InitialModel(
-		hosts, time.Duration(*speed), *chartHeight,
-	)
 
-	p := tea.NewProgram(model) // tea.WithAltScreen(), // use the full size of the terminal in its "alternate screen buffer"
-	// tea.WithMouseCellMotion(), // turn on mouse support so we can track the mouse wheel
+	p := tea.NewProgram(md{p: pingo.InitialModel([]string{"google.ca", "asdf"}, 20, 10, *chartHeight)})
 
 	if _, err := p.Run(); err != nil {
 		fmt.Printf("Alas, there's been an error: %v", err)

+ 34 - 91
tui.go

@@ -56,9 +56,7 @@ package pingo
 import (
 	"fmt"
 	"slices"
-	"time"
 
-	"charm.land/bubbles/v2/viewport"
 	tea "charm.land/bubbletea/v2"
 	"charm.land/lipgloss/v2"
 	"github.com/NimbleMarkets/ntcharts/linechart/streamlinechart"
@@ -66,6 +64,17 @@ import (
 
 // Style Definitions
 var (
+	// 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)
 	// A style for chart headers
 	headerStyle = lipgloss.NewStyle().
 			Bold(true).
@@ -92,22 +101,9 @@ var (
 	// 		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
-	tickMsg       time.Time
 	pollResultMsg struct {
 		results []float64
 		index   int
@@ -117,19 +113,17 @@ type ( // tea.Msg signatures
 
 // Bubbletea model
 type Model struct {
-	Addresses   []Address      // as defined in internal/tui/types.go
-	viewport    viewport.Model // mark: opinionated render
-	UpdateSpeed time.Duration
+	Addresses   []Address // as defined in internal/tui/types.go
 	ChartHeight int
 	Height      int
 	Width       int
 }
 
-func InitialModel(addresses []string, speed time.Duration, chartHeight int) Model {
+func InitialModel(addresses []string, width, height, chartHeight int) Model {
 	var model Model
-	model.viewport.MouseWheelEnabled = true // mark: opinionated render
-	model.UpdateSpeed = speed
 	model.ChartHeight = chartHeight
+	model.Width = width
+	model.Height = height
 
 	for _, address := range addresses {
 		var addr Address
@@ -141,94 +135,46 @@ func InitialModel(addresses []string, speed time.Duration, chartHeight int) Mode
 }
 
 func (m Model) Init() tea.Cmd {
-	return m.Tick()
-}
-
-func (m Model) Tick() tea.Cmd {
-	return tea.Tick(time.Millisecond*m.UpdateSpeed, func(t time.Time) tea.Msg {
-		return tickMsg(t)
-	})
+	return m.Poll()
 }
 
-func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // mark: opinionated render
+func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
 	var cmd tea.Cmd
 	var cmds []tea.Cmd
 
 	switch msg := msg.(type) {
-	// if case is KeyMsg (keypress)
-	case tea.WindowSizeMsg: // mark: opinionated render
-		if m.Width == 0 && m.Height == 0 {
-			m.viewport = viewport.New(
-				viewport.WithHeight(10),
-				viewport.WithWidth(msg.Width),
-			)
-		}
-
-		m.Width = msg.Width
-		m.Height = msg.Height
-		for i, address := range m.Addresses {
-			address.MaxResults = m.Width
-			m.Addresses[i] = address
-		}
-		m.viewport.SetHeight(m.Height - m.getVerticalMargin())
-		m.viewport.SetWidth(m.Width)
-		m.viewport.YPosition = 1
-
-	case tea.KeyPressMsg: // mark: opinionated render
-		if k := msg.String(); k == "j" { // scroll down
-			m.viewport.ScrollDown(1)
-		} else if k == "k" { // scroll up
-			m.viewport.ScrollUp(1)
-		} else {
-			if k == "ctrl+c" {
-				cmds = append(cmds, tea.Quit)
-			}
-		}
-
-	case tickMsg:
-		cmds = append(cmds, m.Tick(), m.Poll())
-
 	case pollResultMsg:
 		m.Addresses[msg.index].Results = msg.results
 	}
-
-	m.viewport.SetContent(m.Render())
-	m.viewport, cmd = m.viewport.Update(msg)
+	for i := range m.Addresses {
+		m.Addresses[i].MaxResults = m.Width
+	}
 	cmds = append(cmds, cmd)
-	// cmds = append(cmds, m.Poll)
 
 	return m, tea.Batch(cmds...)
 }
 
-func (m Model) View() tea.View { // mark: opinionated render
-	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 { // mark: opinionated render
-	var output string
+func (m Model) View() tea.View {
+	var content string
 	for _, address := range m.Addresses {
 		if len(address.Results) == 0 {
-			output = output + fmt.Sprintf("\n%s\tloading...", headerStyle.Render(address.Address))
+			content = content + fmt.Sprintf("\n%s\tloading...", headerStyle.Render(address.Address))
 		} else if m.Width != 0 && m.Height != 0 {
 			if slices.Contains(address.Results, -1) {
-				output = output + blockStyle.Width(m.Width).Render(headerStyle.Render(
-					fmt.Sprintf("\n%s\t%s",
+				content = content + fmt.Sprintf("\n%s",
+					blockStyle.Width(m.Width).Render(headerStyle.Render(
 						secondaryColor.Render(address.Address),
 						infoStyle.Render("(connection unstable)"),
 					),
-				))
+					))
 			} else {
-				output = output + fmt.Sprintf("\n%s",
+				content = content + fmt.Sprintf("\n%s",
 					blockStyle.Width(m.Width).Render(headerStyle.Render(address.Address)))
 			}
 
 			// Linechart
 			// set chartHeight - vertical margin
-			chartHeight := m.Height - m.getVerticalMargin()
+			chartHeight := m.Height - 2 // m.getVerticalMargin()
 
 			var slc streamlinechart.Model
 
@@ -247,21 +193,18 @@ func (m Model) Render() string { // mark: opinionated render
 			}
 
 			slc.Draw()
-			output = output + fmt.Sprintf("\n%s", slc.View())
+			content = content + fmt.Sprintf("\n%s", slc.View())
 		}
 	}
 
-	return output
-}
-
-func (m Model) header() string { return titleStyle.Width(m.Width).Render("pingo v0") } // mark: opinionated render
+	content = content + "\n"
 
-func (m Model) footer() string { // mark: opinionated render
-	return footerStyle.Width(m.Width).Render("j/k: down/up\t|\tq/ctrl-c/esc: quit")
+	var v tea.View
+	v.SetContent(content)
+	v.AltScreen = true
+	return v
 }
 
-func (m Model) getVerticalMargin() int { return lipgloss.Height(m.header() + m.footer()) } // mark: opinionated render
-
 // Returns a batched set of tea.Cmd functions for each address.
 func (m Model) Poll() tea.Cmd {
 	var cmds []tea.Cmd