From e0cb0adebdcdc420593664ad8d1a4ebd7c64855b Mon Sep 17 00:00:00 2001 From: Tyler Koenig Date: Thu, 4 Jun 2026 14:56:01 -0400 Subject: [PATCH] =?UTF-8?q?fix(tui):=20quick=20wins=20batch=20=E2=80=94=20?= =?UTF-8?q?version=20footer,=20column=20widths,=20zebra,=20sparkline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Show version in dashboard footer (wired from goreleaser ldflags) - Cap name column at 35, raise sparkline minimum to 15 chars - Preserve zebra background on group rows (was lost by style override) - Group sparkline uses bullet • instead of heavy circle ● --- cmd/uptop/main.go | 4 ++-- internal/tui/sparkline.go | 4 ++-- internal/tui/tab_sites.go | 8 ++++---- internal/tui/table_helpers.go | 3 +++ internal/tui/tui.go | 4 +++- internal/tui/view_dashboard.go | 5 +++-- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/cmd/uptop/main.go b/cmd/uptop/main.go index 04f974e..3163463 100644 --- a/cmd/uptop/main.go +++ b/cmd/uptop/main.go @@ -413,7 +413,7 @@ func runServe(args []string) { sshSrv := startSSHServer(*port, s, eng, kc) if isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) { - p := tea.NewProgram(tui.InitialModel(true, s, eng), tea.WithAltScreen(), tea.WithMouseCellMotion()) + p := tea.NewProgram(tui.InitialModel(true, s, eng, version), tea.WithAltScreen(), tea.WithMouseCellMotion()) if _, err := p.Run(); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) } @@ -449,7 +449,7 @@ func startSSHServer(port int, db store.Store, eng *monitor.Engine, kc *keyCache) }), wish.WithMiddleware( bm.Middleware(func(s ssh.Session) (tea.Model, []tea.ProgramOption) { - return tui.InitialModel(false, db, eng), []tea.ProgramOption{tea.WithAltScreen(), tea.WithMouseCellMotion()} + return tui.InitialModel(false, db, eng, version), []tea.ProgramOption{tea.WithAltScreen(), tea.WithMouseCellMotion()} }), ), ) diff --git a/internal/tui/sparkline.go b/internal/tui/sparkline.go index a639e1a..f659fda 100644 --- a/internal/tui/sparkline.go +++ b/internal/tui/sparkline.go @@ -131,9 +131,9 @@ func (m Model) groupSparkline(groupID int, width int) string { } for _, up := range aggregated { if up { - sb.WriteString(specialStyle.Render("●")) + sb.WriteString(specialStyle.Render("•")) } else { - sb.WriteString(dangerStyle.Render("●")) + sb.WriteString(dangerStyle.Render("•")) } } return sb.String() diff --git a/internal/tui/tab_sites.go b/internal/tui/tab_sites.go index 0644ee3..7e05227 100644 --- a/internal/tui/tab_sites.go +++ b/internal/tui/tab_sites.go @@ -78,13 +78,13 @@ func (m Model) computeLayout() tableLayout { if nameW < 13 { nameW = 13 } - if nameW > 40 { - nameW = 40 + if nameW > 35 { + nameW = 35 } sparkW := avail - nameW - if sparkW < 10 { - sparkW = 10 + if sparkW < 15 { + sparkW = 15 } widths[1] = nameW diff --git a/internal/tui/table_helpers.go b/internal/tui/table_helpers.go index 8b9f2d4..30fa32c 100644 --- a/internal/tui/table_helpers.go +++ b/internal/tui/table_helpers.go @@ -66,6 +66,9 @@ func (m Model) renderTable(headers []string, items int, buildRows func(start, en if styleOverride != nil { if s := styleOverride(row, col); s != nil { style := *s + if row%2 == 1 { + style = style.Background(tableZebraStyle.GetBackground()) + } if isSelected { style = tableSelectedStyle.Foreground(s.GetForeground()) } diff --git a/internal/tui/tui.go b/internal/tui/tui.go index b5e4729..d08a945 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -138,9 +138,10 @@ type Model struct { // demoMode renders a stable status dot instead of the animated pulse so // screenshots/recordings don't capture the spinner mid-frame. Set via UPTOP_DEMO=1. demoMode bool + version string } -func InitialModel(isAdmin bool, s store.Store, eng *monitor.Engine) Model { +func InitialModel(isAdmin bool, s store.Store, eng *monitor.Engine, version string) Model { vpLogs := viewport.New(100, 20) vpLogs.SetContent("Waiting for logs...") z := zone.New() @@ -172,6 +173,7 @@ func InitialModel(isAdmin bool, s store.Store, eng *monitor.Engine) Model { theme: theme, themeIndex: themeIdx, demoMode: os.Getenv("UPTOP_DEMO") == "1", + version: version, } } diff --git a/internal/tui/view_dashboard.go b/internal/tui/view_dashboard.go index 3507079..504a7fa 100644 --- a/internal/tui/view_dashboard.go +++ b/internal/tui/view_dashboard.go @@ -275,9 +275,10 @@ func (m Model) renderFooter(stats dashboardStats) string { keys = "[T]Theme [Tab]Switch [q]Quit" } - footer := "\n" + statusLine + " " + subtleStyle.Render(keys) + ver := subtleStyle.Render("v" + m.version) + footer := "\n" + statusLine + " " + subtleStyle.Render(keys) + " " + ver if m.filterText != "" && m.currentTab == 0 { - footer = "\n" + subtleStyle.Render(fmt.Sprintf("filter: %s", m.filterText)) + " " + statusLine + " " + subtleStyle.Render(keys) + footer = "\n" + subtleStyle.Render(fmt.Sprintf("filter: %s", m.filterText)) + " " + statusLine + " " + subtleStyle.Render(keys) + " " + ver } return footer }