Skip to content
Open
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
2 changes: 1 addition & 1 deletion internal/tui/components/empty_screen.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func NewEmptyScreenComponent(title, description string, width, height int) *Empt
Title: title,
Description: description,
Style: lipgloss.NewStyle().Align(lipgloss.Center).Padding(2),
width: width,
width: width - 6,
height: height,
}
}
Expand Down
171 changes: 159 additions & 12 deletions internal/tui/components/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type HelpComponent struct {
help help.Model
keys KeyMap
Style lipgloss.Style
width int
}

// NewHelpComponent creates a new help component
Expand All @@ -30,7 +31,16 @@ func NewHelpComponent(title, description string) *HelpComponent {

// SetWidth sets the width of the help component
func (h *HelpComponent) SetWidth(width int) {
h.help.Width = width
h.width = width
overhead := h.getStyleOverhead()
h.help.Width = width - overhead
}

// getStyleOverhead calculates the total width overhead from padding and borders
func (h *HelpComponent) getStyleOverhead() int {
hPadding := h.Style.GetHorizontalPadding()
hBorder := h.Style.GetHorizontalBorderSize()
return hPadding + hBorder
}

// ShowAll toggles the help view between short and full
Expand All @@ -50,30 +60,167 @@ func (h *HelpComponent) IsShowingAll() bool {

// Render returns the formatted help string
func (h *HelpComponent) Render() string {
h.help.ShowAll = true

var content strings.Builder

// Title
titleStyle := lipgloss.NewStyle().
Bold(true).
Foreground(colors.Blue)
content.WriteString(titleStyle.Render(h.Title))
Foreground(colors.Blue).
Align(lipgloss.Center)

title := titleStyle.Render(h.Title)
content.WriteString(title)
content.WriteString("\n\n")

// Description
if h.Description != "" {
content.WriteString(h.Description)
descStyle := lipgloss.NewStyle().
Foreground(colors.LightGray).
Align(lipgloss.Center)
desc := descStyle.Render(h.Description)
content.WriteString(desc)
content.WriteString("\n\n")
}

// Use bubbles help to render the key bindings
helpView := h.help.View(h.keys)
content.WriteString(helpView)
content.WriteString(h.renderKeyBindings())

return h.Style.Render(content.String())
}

func (h *HelpComponent) renderKeyBindings() string {
fullHelp := h.keys.FullHelp()

if len(fullHelp) == 0 {
return ""
}

// Calculate available content width
availableWidth := h.help.Width
if availableWidth <= 0 {
availableWidth = 80 // default fallback
}

keyStyle := lipgloss.NewStyle().
Foreground(colors.Blue).
Bold(true).
Padding(0, 1)

descStyle := lipgloss.NewStyle().
Foreground(colors.White)

sepStyle := lipgloss.NewStyle().
Foreground(colors.LightGray)

var sections []string

sectionTitles := []string{
"Navigation",
"Pagination",
"View Controls",
"General",
}

for i, column := range fullHelp {
var rows []string

if i < len(sectionTitles) {
titleStyle := lipgloss.NewStyle().
Bold(true).
Foreground(colors.Blue).
Underline(true)
rows = append(rows, titleStyle.Render(sectionTitles[i]))
rows = append(rows, "")
}

for _, binding := range column {
if !binding.Enabled() {
continue
}

keyHelp := binding.Help()
keyStr := keyStyle.Render(keyHelp.Key)
descStr := descStyle.Render(keyHelp.Desc)
sep := sepStyle.Render(" • ")

row := keyStr + sep + descStr
rows = append(rows, row)
}

section := strings.Join(rows, "\n")
sections = append(sections, section)
}

// Calculate the width for each section
maxWidth := 0
for _, section := range sections {
lines := strings.Split(section, "\n")
for _, line := range lines {
width := lipgloss.Width(line)
if width > maxWidth {
maxWidth = width
}
}
}

// Section padding and spacing constants
const sectionHPadding = 4 // horizontal padding per section (left + right)
const sectionSpacing = 2 // spacing between sections
sectionWidth := maxWidth + sectionHPadding

// Calculate total width needed for horizontal layout
numSections := len(sections)
totalWidthNeeded := (sectionWidth * numSections) + (sectionSpacing * (numSections - 1))

// Decide layout based on available width
var helpContent string
if totalWidthNeeded <= availableWidth && numSections > 1 {
// Horizontal layout - sections side by side
sectionStyle := lipgloss.NewStyle().
Width(sectionWidth).
Padding(1, 2)

var styledSections []string
for _, section := range sections {
styledSections = append(styledSections, sectionStyle.Render(section))
}

helpContent = lipgloss.JoinHorizontal(
lipgloss.Top,
styledSections...,
)
} else {
// Vertical layout - sections stacked
// Adjust section width to use more available space
adjustedWidth := availableWidth - sectionHPadding
if adjustedWidth < maxWidth {
adjustedWidth = maxWidth
}

sectionStyle := lipgloss.NewStyle().
Width(adjustedWidth).
Padding(1, 2)

var styledSections []string
for i, section := range sections {
styledSections = append(styledSections, sectionStyle.Render(section))
// Add spacing between sections except for the last one
if i < len(sections)-1 {
styledSections = append(styledSections, "")
}
}

helpContent = lipgloss.JoinVertical(
lipgloss.Left,
styledSections...,
)
}

// Center the entire help content
centeredStyle := lipgloss.NewStyle().
Width(availableWidth).
Align(lipgloss.Center)

view := h.Style.Render(content.String())
h.help.ShowAll = false
return view
return centeredStyle.Render(helpContent)
}

// GetHelpModel returns the underlying help model for direct manipulation
Expand Down
5 changes: 5 additions & 0 deletions internal/tui/views/trafficwatch/left_pane.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ func (l *LeftPane) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}

var cmd tea.Cmd

if val, ok := msg.(tea.KeyMsg); ok && val.String() == "left" {
return l, nil
}

l.paginator, cmd = l.paginator.Update(msg)
return l, cmd
}
Expand Down
15 changes: 6 additions & 9 deletions internal/tui/views/trafficwatch/main_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,22 +335,19 @@ func (m *MainView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}

// Update focused pane
var cmd tea.Cmd
if m.state == StateWithData {
m.rightPane.SetFocused(m.focus == "right")

switch m.focus {
case "left":
_, cmd = m.leftPane.Update(msg)
case "right":
_, cmd = m.rightPane.Update(msg)
}
_, cmd := m.leftPane.Update(msg)
cmds = append(cmds, cmd)
_, cmd = m.rightPane.Update(msg)
cmds = append(cmds, cmd)
}

if m.state == StateLogs {
_, cmd = m.logsView.Update(msg)
_, cmd := m.logsView.Update(msg)
cmds = append(cmds, cmd)
}
cmds = append(cmds, cmd)

return m, tea.Batch(cmds...)
}
Expand Down