fix: ensure header visibility with explicit newline and nil checks
This commit is contained in:
parent
8619a7f35c
commit
9fec5df6f7
@ -212,17 +212,18 @@ func (m *Model) updateLayout() {
|
||||
|
||||
rightWidth := 42
|
||||
leftWidth := m.width - rightWidth - 3
|
||||
headerHeight := 3
|
||||
mainHeight := m.height - headerHeight - 1
|
||||
inputHeight := 5
|
||||
chatHeight := mainHeight - inputHeight
|
||||
if chatHeight < 10 {
|
||||
chatHeight = 10
|
||||
|
||||
headerHeight := 2
|
||||
mainHeight := m.height - headerHeight
|
||||
if mainHeight < 10 {
|
||||
mainHeight = 10
|
||||
}
|
||||
chatHeight := mainHeight - 9
|
||||
if chatHeight < 5 {
|
||||
chatHeight = 5
|
||||
}
|
||||
|
||||
m.textarea.SetWidth(leftWidth)
|
||||
m.viewport.Width = leftWidth
|
||||
m.viewport.Height = chatHeight
|
||||
|
||||
if !m.ready {
|
||||
m.viewport = viewport.New(leftWidth, chatHeight)
|
||||
@ -265,33 +266,18 @@ func (m Model) View() string {
|
||||
return "Initializing..."
|
||||
}
|
||||
|
||||
rightWidth := 42
|
||||
leftWidth := m.width - rightWidth - 3
|
||||
rightWidth := 40
|
||||
leftWidth := m.width - rightWidth - 2
|
||||
|
||||
header := m.renderHeader()
|
||||
headerHeight := lipgloss.Height(header)
|
||||
mainHeight := m.height - headerHeight
|
||||
inputHeight := 5
|
||||
chatHeight := mainHeight - inputHeight
|
||||
if chatHeight < 10 {
|
||||
chatHeight = 10
|
||||
}
|
||||
|
||||
chatBox := boxStyle.Width(leftWidth).Height(chatHeight).Render(m.viewport.View())
|
||||
chatBox := boxStyle.Width(leftWidth).Height(m.height - 8).Render(m.viewport.View())
|
||||
inputBox := boxStyle.Width(leftWidth).Render(m.textarea.View())
|
||||
leftPanel := lipgloss.JoinVertical(lipgloss.Left, chatBox, inputBox)
|
||||
|
||||
stats := m.renderStats()
|
||||
agents := m.renderAgents()
|
||||
|
||||
statsHeight := lipgloss.Height(stats)
|
||||
agentsHeight := lipgloss.Height(agents)
|
||||
remainingHeight := mainHeight - statsHeight - agentsHeight - 2
|
||||
if remainingHeight < 3 {
|
||||
remainingHeight = 3
|
||||
}
|
||||
|
||||
empty := boxStyle.Width(rightWidth - 4).Height(remainingHeight).Render("")
|
||||
empty := boxStyle.Width(rightWidth - 2).Height(m.height - lipgloss.Height(stats) - lipgloss.Height(agents) - 5).Render("")
|
||||
rightPanel := lipgloss.JoinVertical(lipgloss.Left, stats, agents, empty)
|
||||
|
||||
if m.loading {
|
||||
@ -299,19 +285,21 @@ func (m Model) View() string {
|
||||
}
|
||||
|
||||
body := lipgloss.JoinHorizontal(lipgloss.Top, leftPanel, rightPanel)
|
||||
return lipgloss.JoinVertical(lipgloss.Left, header, body)
|
||||
return header + "\n" + body
|
||||
}
|
||||
|
||||
func (m Model) renderHeader() string {
|
||||
version := "v0.1.0"
|
||||
title := titleStyle.Render("orca.agent ") + mutedStyle.Render(version)
|
||||
title := "orca.agent " + version
|
||||
line := strings.Repeat("─", m.width-2)
|
||||
return lipgloss.NewStyle().
|
||||
Width(m.width).
|
||||
Padding(0, 1).
|
||||
BorderBottom(true).
|
||||
BorderStyle(lipgloss.NormalBorder()).
|
||||
BorderForeground(lipgloss.Color(colors.border)).
|
||||
Render(title)
|
||||
Bold(true).
|
||||
Foreground(lipgloss.Color(colors.primary)).
|
||||
Render(title) + "\n" + lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color(colors.border)).
|
||||
Render(line)
|
||||
}
|
||||
|
||||
func (m Model) renderStats() string {
|
||||
@ -319,16 +307,22 @@ func (m Model) renderStats() string {
|
||||
b.WriteString(titleStyle.Render("Statistics") + "\n\n")
|
||||
|
||||
tools := 0
|
||||
if tm := m.kernel.ToolManager(); tm != nil {
|
||||
tools = tm.Count()
|
||||
if m.kernel != nil {
|
||||
if tm := m.kernel.ToolManager(); tm != nil {
|
||||
tools = tm.Count()
|
||||
}
|
||||
}
|
||||
skills := 0
|
||||
if sm := m.kernel.SkillManager(); sm != nil {
|
||||
skills = len(sm.ListSkills())
|
||||
if m.kernel != nil {
|
||||
if sm := m.kernel.SkillManager(); sm != nil {
|
||||
skills = len(sm.ListSkills())
|
||||
}
|
||||
}
|
||||
agents := 0
|
||||
if as := m.kernel.ActorSystem(); as != nil {
|
||||
agents = as.AgentCount()
|
||||
if m.kernel != nil {
|
||||
if as := m.kernel.ActorSystem(); as != nil {
|
||||
agents = as.AgentCount()
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteString(statLabelStyle.Render("Tools: "))
|
||||
@ -345,15 +339,17 @@ func (m Model) renderAgents() string {
|
||||
var b strings.Builder
|
||||
b.WriteString(titleStyle.Render("Active Agents") + "\n\n")
|
||||
|
||||
if as := m.kernel.ActorSystem(); as != nil {
|
||||
for _, info := range as.AgentInfos() {
|
||||
status := "idle"
|
||||
style := idleAgentStyle
|
||||
if info.Status == actor.StatusProcessing || m.agentRuns[info.ID] {
|
||||
status = "running"
|
||||
style = activeAgentStyle
|
||||
if m.kernel != nil {
|
||||
if as := m.kernel.ActorSystem(); as != nil {
|
||||
for _, info := range as.AgentInfos() {
|
||||
status := "idle"
|
||||
style := idleAgentStyle
|
||||
if info.Status == actor.StatusProcessing || m.agentRuns[info.ID] {
|
||||
status = "running"
|
||||
style = activeAgentStyle
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("• %s: %s\n", info.ID, style.Render(status)))
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("• %s: %s\n", info.ID, style.Render(status)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/bubbles/textarea"
|
||||
)
|
||||
|
||||
func TestEventWriter(t *testing.T) {
|
||||
@ -74,3 +77,26 @@ func TestModelFormatMessage(t *testing.T) {
|
||||
t.Error("system message should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestViewContainsHeader(t *testing.T) {
|
||||
ta := textarea.New()
|
||||
ta.ShowLineNumbers = false
|
||||
ta.KeyMap.InsertNewline.SetEnabled(false)
|
||||
|
||||
m := Model{
|
||||
width: 120,
|
||||
height: 40,
|
||||
textarea: ta,
|
||||
messages: []ChatMessage{},
|
||||
events: make(chan Event, 10),
|
||||
agentRuns: make(map[string]bool),
|
||||
}
|
||||
m.updateLayout()
|
||||
view := m.View()
|
||||
if view == "Initializing..." {
|
||||
t.Fatal("view should not be initializing")
|
||||
}
|
||||
if !strings.Contains(view, "orca.agent") {
|
||||
t.Errorf("view should contain 'orca.agent', got:\n%s", view[:min(200, len(view))])
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user