From 3d416a9ff55c9657854ff16fd069b0d21f40df8b Mon Sep 17 00:00:00 2001 From: fullstackjam Date: Fri, 17 Jul 2026 21:43:44 +0800 Subject: [PATCH] fix(tui): stop saying "openboot" twice on the boot screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The title bar reads "▲ openboot v0.66.2" and the body opened, one row below it, with a wordmark reading "openboot". Same word, twice, three lines apart — and a row spent on it. The frame is what names the product; it's on every screen. The wordmark was a splash element that only repeated what the frame already said, so it goes. The tagline stays: "zero → dev-ready, in one command" is the only part of that block that told you anything. bootHitTest's geometry mirrors the render row-for-row, so it moves with it (4 header rows → 3). The two mouse tests hardcode screen rows and caught the shift on the first run, which is what they're for. --- internal/ui/tui/wizard/boot.go | 23 ++++++----------------- internal/ui/tui/wizard/wizard_test.go | 10 +++++----- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/internal/ui/tui/wizard/boot.go b/internal/ui/tui/wizard/boot.go index cedadd6..8dae8c1 100644 --- a/internal/ui/tui/wizard/boot.go +++ b/internal/ui/tui/wizard/boot.go @@ -7,7 +7,6 @@ import ( "strings" tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" "github.com/openbootdotdev/openboot/internal/brew" "github.com/openbootdotdev/openboot/internal/config" @@ -238,8 +237,11 @@ func (m Model) enterSelect(sel map[string]bool) (tea.Model, tea.Cmd) { func (m Model) bootBody(w, _ int) string { const pad = " " var b []string + // No wordmark here: the title bar one row up already reads + // "▲ openboot vX.Y.Z". Repeating the name immediately below it said the + // same word twice and spent a row doing it. The tagline is the only part + // that adds anything, so the body opens with that. b = append(b, "") - b = append(b, pad+wordmark()+" "+fg(cAccent).Render("▌")) b = append(b, pad+fg(cDim3).Render("zero → dev-ready, in one command")) b = append(b, "") @@ -303,19 +305,6 @@ func (m Model) renderLoadout(i int, l loadout, w int) string { return line } -// wordmark renders "openboot" with the design's green gradient. -func wordmark() string { - letters := []struct{ ch, hex string }{ - {"o", "#166534"}, {"p", "#15803d"}, {"e", "#16a34a"}, {"n", "#22c55e"}, - {"b", "#22c55e"}, {"o", "#4ade80"}, {"o", "#86efac"}, {"t", "#bbf7d0"}, - } - var sb strings.Builder - for _, l := range letters { - sb.WriteString(lipgloss.NewStyle().Foreground(lipgloss.Color(l.hex)).Bold(true).Render(l.ch)) - } - return sb.String() -} - // estMinutes is a rough install-time estimate (~0.4 min/pkg), matching the // design's back-of-envelope figure. func estMinutes(pkgCount int) int { @@ -356,10 +345,10 @@ func (m Model) bootHitTest(x, y int) int { return -1 } bodyRow := y - 1 // title bar is screen row 0 - // Header: blank + wordmark + subtitle + blank = 4 body rows + // Header: blank + tagline + blank = 3 body rows // Probes: len(m.probes) rows // Footer before loadouts: blank + "Choose…" + blank = 3 body rows - loadoutStart := 4 + len(m.probes) + 3 + loadoutStart := 3 + len(m.probes) + 3 idx := bodyRow - loadoutStart if idx >= 0 && idx < len(m.loadouts) { return idx diff --git a/internal/ui/tui/wizard/wizard_test.go b/internal/ui/tui/wizard/wizard_test.go index 070e5dd..e92510f 100644 --- a/internal/ui/tui/wizard/wizard_test.go +++ b/internal/ui/tui/wizard/wizard_test.go @@ -239,9 +239,9 @@ func TestBootMouseClickPicksLoadout(t *testing.T) { require.Equal(t, scrBoot, m.screen) require.GreaterOrEqual(t, len(m.loadouts), 2) - // Click the second loadout row. Geometry: 4 header + 4 probes + 3 footer - // = loadouts start at body row 11 → screen row 12. Loadout 1 at row 13. - m = send(m, tea.MouseMsg{Action: tea.MouseActionPress, Button: tea.MouseButtonLeft, X: 10, Y: 13}) + // Click the second loadout row. Geometry: 3 header + 4 probes + 3 footer + // = loadouts start at body row 10 → screen row 11. Loadout 1 at row 12. + m = send(m, tea.MouseMsg{Action: tea.MouseActionPress, Button: tea.MouseButtonLeft, X: 10, Y: 12}) assert.Equal(t, scrSelect, m.screen, "clicking a loadout enters the select screen") assert.Equal(t, 1, m.loadCur, "click lands on loadout index 1") } @@ -251,8 +251,8 @@ func TestBootMouseHoverHighlightsLoadout(t *testing.T) { require.Equal(t, scrBoot, m.screen) require.Equal(t, -1, m.hoverRow, "starts with no hover") - // Motion over the first loadout row (screen row 12) sets hoverRow. - m = send(m, tea.MouseMsg{Action: tea.MouseActionMotion, X: 10, Y: 12}) + // Motion over the first loadout row (screen row 11) sets hoverRow. + m = send(m, tea.MouseMsg{Action: tea.MouseActionMotion, X: 10, Y: 11}) assert.Equal(t, 0, m.hoverRow, "hover over loadout 0") // Motion off the loadout area clears it.