Ship a working `gitflow tui` command: static scan result rendered as a lipgloss-styled table, with keyboard navigation and a detail pane. TUI package (internal/tui): - Model struct: holds scan result, cursor, detail/help toggles, loading state, error display, and injected app/AI/config dependencies - Update: handles WindowSizeMsg (resize), KeyMsg for navigation (j/↑/k/↓, Home/End, Enter/Space for detail, ? for help, q/Ctrl-C for quit), and async scanResultMsg/scanErrorMsg for the M3 periodic scan loop - View: repo list table (STATUS/REPOSITORY/BRANCH/AHEAD-BEHIND/CHGS/STASH) with cursor highlighting and dimmed error rows, expandable detail pane showing files, and a status bar (scan summary + keybinding hints) - styles.go: lipgloss Styles (Header/Row/CursorRow/StatusBar) with dark/light theme palettes that mirror the CLI's ThemeMode - Loading and empty states; help overlay with keybinding reference Presenter API surface (needed by the TUI): - ShortPath exported (home → ~ collapsing, reused by TUI and CLI) - StatusSymbolFor exported (✓ ✗ ↑ ↓ ⇄ ◉ ▢ ! symbols, reused) - ShortPath is kept as a wrapper so internal formatter callers are unaffected CLI (cmd/gitflow): - newTUICmd: resolves config, builds AI provider, calls tui.New() for the initial scan, and runs the bubbletea Program - Wired into root command under `gitflow tui` with full flag set (--dir, --interval, --exclude, etc.) Dependencies: bubbletea v1.3.10, lipgloss v1.1.0, a stable x/term tree Testing: - Model logic tests: cursor navigation (arrow + j/k), bottom/top clamping, detail toggle (Enter/Space), ? help, q/Ctrl-C quit, view renders repo names/branch/status columns, detail pane shows file lists, help overlay shows keybindings, loading/empty states Verified: go build, go vet, go test -race (12 packages), gofmt clean, `gitflow tui --help` prints command usage.
51 lines
1.4 KiB
Go
51 lines
1.4 KiB
Go
package tui
|
|
|
|
import (
|
|
"github.com/charmbracelet/lipgloss"
|
|
|
|
"gitea.oblak.solutions/dimitar/gitFlow/internal/presenter"
|
|
)
|
|
|
|
// Styles groups the lipgloss styles used across TUI views.
|
|
type Styles struct {
|
|
Header lipgloss.Style
|
|
Row lipgloss.Style
|
|
CursorRow lipgloss.Style
|
|
StatusBar lipgloss.Style
|
|
}
|
|
|
|
// Dim applies a dimmed, lower-contrast style (shared helper).
|
|
func (s Styles) Dim(text string) string {
|
|
return lipgloss.NewStyle().Faint(true).Render(text)
|
|
}
|
|
|
|
// Err applies an error-highlight style.
|
|
func (s Styles) Err(text string) string {
|
|
return lipgloss.NewStyle().Foreground(lipgloss.Color("1")).Render(text)
|
|
}
|
|
|
|
// NewStyles builds a Styles palette from the presenter options so the TUI
|
|
// theme matches the CLI.
|
|
func NewStyles(opts presenter.Options) Styles {
|
|
headerFg, rowFg, cursorFg, barFg := darkColors()
|
|
if opts.Theme == presenter.ThemeLight {
|
|
headerFg, rowFg, cursorFg, barFg = lightColors()
|
|
}
|
|
return Styles{
|
|
Header: lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color(headerFg)).
|
|
Bold(true),
|
|
Row: lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color(rowFg)),
|
|
CursorRow: lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color(cursorFg)).
|
|
Background(lipgloss.Color("235")),
|
|
StatusBar: lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color(barFg)).
|
|
Background(lipgloss.Color("236")),
|
|
}
|
|
}
|
|
|
|
func darkColors() (h, r, c, b string) { return "14", "7", "15", "8" }
|
|
func lightColors() (h, r, c, b string) { return "6", "0", "0", "7" }
|