Skip to content

Commit 7d1e78c

Browse files
refactor: extract shared column slice, named constant, and package-level styles
- Extract toggleableColumns var to replace 3 duplicate column order slices - Replace -1 magic number with colOptionBorders named constant - Remove redundant colOptionsFrom field (always viewQueue) - Hoist errorStyle/flashStyle/updateStyle to package-level vars, eliminating per-render allocations across queue, review, and tasks views Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c5a097c commit 7d1e78c

File tree

6 files changed

+25
-18
lines changed

6 files changed

+25
-18
lines changed

cmd/roborev/tui/handlers_queue.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func (m model) handleColumnOptionsKey() (tea.Model, tea.Cmd) {
161161
}
162162
// Build option list from toggleable columns
163163
var opts []columnOption
164-
for _, col := range []int{colRef, colBranch, colRepo, colAgent, colStatus, colQueued, colElapsed, colPF, colHandled} {
164+
for _, col := range toggleableColumns {
165165
opts = append(opts, columnOption{
166166
id: col,
167167
name: columnDisplayName(col),
@@ -170,21 +170,20 @@ func (m model) handleColumnOptionsKey() (tea.Model, tea.Cmd) {
170170
}
171171
// Add borders toggle
172172
opts = append(opts, columnOption{
173-
id: -1,
173+
id: colOptionBorders,
174174
name: "Column borders",
175175
enabled: m.colBordersOn,
176176
})
177177
m.colOptionsList = opts
178178
m.colOptionsIdx = 0
179-
m.colOptionsFrom = m.currentView
180179
m.currentView = viewColumnOptions
181180
return m, nil
182181
}
183182

184183
func (m model) handleColumnOptionsInput(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
185184
switch msg.String() {
186185
case "esc":
187-
m.currentView = m.colOptionsFrom
186+
m.currentView = viewQueue
188187
return m, nil
189188
case "ctrl+c":
190189
return m, tea.Quit
@@ -202,7 +201,7 @@ func (m model) handleColumnOptionsInput(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
202201
if m.colOptionsIdx >= 0 && m.colOptionsIdx < len(m.colOptionsList) {
203202
opt := &m.colOptionsList[m.colOptionsIdx]
204203
opt.enabled = !opt.enabled
205-
if opt.id == -1 {
204+
if opt.id == colOptionBorders {
206205
// Borders toggle
207206
m.colBordersOn = opt.enabled
208207
} else {

cmd/roborev/tui/render_queue.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ func (m model) renderQueueView() string {
127127
b.WriteString(titleStyle.Render(title.String()))
128128
// In compact mode, show version mismatch inline since the status area is hidden
129129
if compact && m.versionMismatch {
130-
errorStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "124", Dark: "196"}).Bold(true)
131130
b.WriteString(" ")
132131
b.WriteString(errorStyle.Render(fmt.Sprintf("MISMATCH: TUI %s != Daemon %s", version.Version, m.daemonVersion)))
133132
}
@@ -177,7 +176,6 @@ func (m model) renderQueueView() string {
177176

178177
// Update notification on line 3 (above the table)
179178
if m.updateAvailable != "" {
180-
updateStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "136", Dark: "226"}).Bold(true)
181179
var updateMsg string
182180
if m.updateIsDevBuild {
183181
updateMsg = fmt.Sprintf("Dev build - latest release: %s - run 'roborev update --force'", m.updateAvailable)
@@ -533,10 +531,8 @@ func (m model) renderQueueView() string {
533531
// Status line: flash message (temporary)
534532
// Version mismatch takes priority over flash messages (it's persistent and important)
535533
if m.versionMismatch {
536-
errorStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "124", Dark: "196"}).Bold(true) // Red
537534
b.WriteString(errorStyle.Render(fmt.Sprintf("VERSION MISMATCH: TUI %s != Daemon %s - restart TUI or daemon", version.Version, m.daemonVersion)))
538535
} else if m.flashMessage != "" && time.Now().Before(m.flashExpiresAt) && m.flashView == viewQueue {
539-
flashStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "28", Dark: "46"}) // Green
540536
b.WriteString(flashStyle.Render(m.flashMessage))
541537
}
542538
b.WriteString("\x1b[K\n") // Clear to end of line
@@ -641,6 +637,10 @@ func stripControlChars(s string) string {
641637
return b.String()
642638
}
643639

640+
// toggleableColumns is the ordered list of columns the user can show/hide.
641+
// colSel and colJobID are always visible and not included here.
642+
var toggleableColumns = []int{colRef, colBranch, colRepo, colAgent, colStatus, colQueued, colElapsed, colPF, colHandled}
643+
644644
// columnNames maps column constants to display names.
645645
var columnNames = map[int]string{
646646
colRef: "Ref",
@@ -694,7 +694,7 @@ func parseHiddenColumns(names []string) map[int]bool {
694694
func hiddenColumnsToNames(hidden map[int]bool) []string {
695695
var names []string
696696
// Maintain stable order
697-
for _, col := range []int{colRef, colBranch, colRepo, colAgent, colStatus, colQueued, colElapsed, colPF, colHandled} {
697+
for _, col := range toggleableColumns {
698698
if hidden[col] {
699699
names = append(names, columnConfigNames[col])
700700
}
@@ -706,7 +706,7 @@ func hiddenColumnsToNames(hidden map[int]bool) []string {
706706
// always including colSel and colJobID, plus any non-hidden toggleable columns.
707707
func (m model) visibleColumns() []int {
708708
cols := []int{colSel, colJobID}
709-
for _, c := range []int{colRef, colBranch, colRepo, colAgent, colStatus, colQueued, colElapsed, colPF, colHandled} {
709+
for _, c := range toggleableColumns {
710710
if !m.hiddenColumns[c] {
711711
cols = append(cols, c)
712712
}
@@ -749,7 +749,7 @@ func (m model) renderColumnOptionsView() string {
749749
line = selectedStyle.Render(line)
750750
}
751751
// Separator before "Column borders" item
752-
if opt.id == -1 && i > 0 {
752+
if opt.id == colOptionBorders && i > 0 {
753753
b.WriteString("\n")
754754
}
755755
b.WriteString(prefix)

cmd/roborev/tui/render_review.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,8 @@ func (m model) renderReviewView() string {
236236

237237
// Status line: version mismatch (persistent) takes priority, then flash message, then scroll indicator
238238
if m.versionMismatch {
239-
errorStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "124", Dark: "196"}).Bold(true) // Red
240239
b.WriteString(errorStyle.Render(fmt.Sprintf("VERSION MISMATCH: TUI %s != Daemon %s - restart TUI or daemon", version.Version, m.daemonVersion)))
241240
} else if m.flashMessage != "" && time.Now().Before(m.flashExpiresAt) && m.flashView == viewReview {
242-
flashStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "28", Dark: "46"}) // Green
243241
b.WriteString(flashStyle.Render(m.flashMessage))
244242
} else if len(lines) > visibleLines {
245243
scrollInfo := fmt.Sprintf("[%d-%d of %d lines]", start+1, end, len(lines))

cmd/roborev/tui/render_tasks.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ func (m model) renderTasksView() string {
151151

152152
// Flash message
153153
if m.flashMessage != "" && time.Now().Before(m.flashExpiresAt) && m.flashView == viewTasks {
154-
flashStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "28", Dark: "46"})
155154
b.WriteString(flashStyle.Render(m.flashMessage))
156155
}
157156
b.WriteString("\x1b[K\n")

cmd/roborev/tui/tui.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ var (
5959
Foreground(lipgloss.AdaptiveColor{Light: "242", Dark: "246"}) // Gray (matches status/scroll text)
6060
helpDescStyle = lipgloss.NewStyle().
6161
Foreground(lipgloss.AdaptiveColor{Light: "248", Dark: "240"}) // Dimmer gray for descriptions
62+
63+
errorStyle = lipgloss.NewStyle().
64+
Foreground(lipgloss.AdaptiveColor{Light: "124", Dark: "196"}).Bold(true) // Red
65+
66+
flashStyle = lipgloss.NewStyle().
67+
Foreground(lipgloss.AdaptiveColor{Light: "28", Dark: "46"}) // Green
68+
69+
updateStyle = lipgloss.NewStyle().
70+
Foreground(lipgloss.AdaptiveColor{Light: "136", Dark: "226"}).Bold(true) // Yellow/Gold
6271
)
6372

6473
// reflowHelpRows redistributes items across rows so that when rendered
@@ -379,7 +388,6 @@ type model struct {
379388
// Column options modal
380389
colOptionsIdx int // Cursor in modal
381390
colOptionsList []columnOption // Items in modal (columns + borders toggle)
382-
colOptionsFrom viewKind // Return view
383391
colBordersOn bool // Column borders enabled
384392
hiddenColumns map[int]bool // Set of hidden column IDs
385393
}

cmd/roborev/tui/types.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,13 @@ type logLine struct {
7373
text string
7474
}
7575

76+
// colOptionBorders is the sentinel ID for the borders toggle in the column options modal.
77+
const colOptionBorders = -1
78+
7679
// columnOption represents an item in the column options modal.
77-
// id is the column constant (colRef..colHandled) or -1 for the borders toggle.
80+
// id is a column constant (colRef..colHandled) or colOptionBorders.
7881
type columnOption struct {
79-
id int // column constant or -1 for borders toggle
82+
id int // column constant or colOptionBorders
8083
name string // display label
8184
enabled bool // visible/on
8285
}

0 commit comments

Comments
 (0)