Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 6 additions & 17 deletions internal/ui/tui/wizard/boot.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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, "")

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions internal/ui/tui/wizard/wizard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand All @@ -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.
Expand Down
Loading