summaryrefslogtreecommitdiffhomepage
path: root/packages/tui/internal/components/chat
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-06-26 10:16:07 -0500
committerGitHub <[email protected]>2025-06-26 10:16:07 -0500
commit7d13baadc84d7377a352c6d58ed9deeea2c918be (patch)
tree575b6897431e390ae8bf4b9ccde2803446c6c67a /packages/tui/internal/components/chat
parentdb24bf87c01d3fff2a9594e55e9fab0d9ef52cfe (diff)
downloadopencode-7d13baadc84d7377a352c6d58ed9deeea2c918be.tar.gz
opencode-7d13baadc84d7377a352c6d58ed9deeea2c918be.zip
feat: default system theme (#419)
Co-authored-by: adamdottv <[email protected]>
Diffstat (limited to 'packages/tui/internal/components/chat')
-rw-r--r--packages/tui/internal/components/chat/editor.go65
-rw-r--r--packages/tui/internal/components/chat/message.go31
-rw-r--r--packages/tui/internal/components/chat/messages.go26
3 files changed, 70 insertions, 52 deletions
diff --git a/packages/tui/internal/components/chat/editor.go b/packages/tui/internal/components/chat/editor.go
index b5d1cc034..79b80cf69 100644
--- a/packages/tui/internal/components/chat/editor.go
+++ b/packages/tui/internal/components/chat/editor.go
@@ -26,6 +26,9 @@ type EditorComponent interface {
Content() string
Lines() int
Value() string
+ Focused() bool
+ Focus() (tea.Model, tea.Cmd)
+ Blur()
Submit() (tea.Model, tea.Cmd)
Clear() (tea.Model, tea.Cmd)
Paste() (tea.Model, tea.Cmd)
@@ -48,7 +51,7 @@ type editorComponent struct {
}
func (m *editorComponent) Init() tea.Cmd {
- return tea.Batch(textarea.Blink, m.spinner.Tick, tea.EnableReportFocus)
+ return tea.Batch(m.textarea.Focus(), m.spinner.Tick, tea.EnableReportFocus)
}
func (m *editorComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@@ -69,7 +72,7 @@ func (m *editorComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case dialog.ThemeSelectedMsg:
m.textarea = createTextArea(&m.textarea)
m.spinner = createSpinner()
- return m, tea.Batch(m.spinner.Tick, textarea.Blink)
+ return m, tea.Batch(m.spinner.Tick, m.textarea.Focus())
case dialog.CompletionSelectedMsg:
if msg.IsCommand {
commandName := strings.TrimPrefix(msg.CompletionValue, "/")
@@ -104,12 +107,11 @@ func (m *editorComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m *editorComponent) Content() string {
t := theme.CurrentTheme()
- base := styles.BaseStyle().Background(t.Background()).Render
- muted := styles.Muted().Background(t.Background()).Render
- promptStyle := lipgloss.NewStyle().
+ base := styles.NewStyle().Foreground(t.Text()).Background(t.Background()).Render
+ muted := styles.NewStyle().Foreground(t.TextMuted()).Background(t.Background()).Render
+ promptStyle := styles.NewStyle().Foreground(t.Primary()).
Padding(0, 0, 0, 1).
- Bold(true).
- Foreground(t.Primary())
+ Bold(true)
prompt := promptStyle.Render(">")
textarea := lipgloss.JoinHorizontal(
@@ -117,11 +119,11 @@ func (m *editorComponent) Content() string {
prompt,
m.textarea.View(),
)
- textarea = styles.BaseStyle().
+ textarea = styles.NewStyle().
+ Background(t.BackgroundElement()).
Width(m.width).
PaddingTop(1).
PaddingBottom(1).
- Background(t.BackgroundElement()).
Render(textarea)
hint := base(m.getSubmitKeyText()) + muted(" send ")
@@ -140,10 +142,10 @@ func (m *editorComponent) Content() string {
}
space := m.width - 2 - lipgloss.Width(model) - lipgloss.Width(hint)
- spacer := lipgloss.NewStyle().Background(t.Background()).Width(space).Render("")
+ spacer := styles.NewStyle().Background(t.Background()).Width(space).Render("")
info := hint + spacer + model
- info = styles.Padded().Background(t.Background()).Render(info)
+ info = styles.NewStyle().Background(t.Background()).Padding(0, 1).Render(info)
content := strings.Join([]string{"", textarea, info}, "\n")
return content
@@ -156,6 +158,18 @@ func (m *editorComponent) View() string {
return m.Content()
}
+func (m *editorComponent) Focused() bool {
+ return m.textarea.Focused()
+}
+
+func (m *editorComponent) Focus() (tea.Model, tea.Cmd) {
+ return m, m.textarea.Focus()
+}
+
+func (m *editorComponent) Blur() {
+ m.textarea.Blur()
+}
+
func (m *editorComponent) GetSize() (width, height int) {
return m.width, m.height
}
@@ -297,14 +311,14 @@ func createTextArea(existing *textarea.Model) textarea.Model {
ta := textarea.New()
- ta.Styles.Blurred.Base = lipgloss.NewStyle().Background(bgColor).Foreground(textColor)
- ta.Styles.Blurred.CursorLine = lipgloss.NewStyle().Background(bgColor)
- ta.Styles.Blurred.Placeholder = lipgloss.NewStyle().Background(bgColor).Foreground(textMutedColor)
- ta.Styles.Blurred.Text = lipgloss.NewStyle().Background(bgColor).Foreground(textColor)
- ta.Styles.Focused.Base = lipgloss.NewStyle().Background(bgColor).Foreground(textColor)
- ta.Styles.Focused.CursorLine = lipgloss.NewStyle().Background(bgColor)
- ta.Styles.Focused.Placeholder = lipgloss.NewStyle().Background(bgColor).Foreground(textMutedColor)
- ta.Styles.Focused.Text = lipgloss.NewStyle().Background(bgColor).Foreground(textColor)
+ ta.Styles.Blurred.Base = styles.NewStyle().Foreground(textColor).Background(bgColor).Lipgloss()
+ ta.Styles.Blurred.CursorLine = styles.NewStyle().Background(bgColor).Lipgloss()
+ ta.Styles.Blurred.Placeholder = styles.NewStyle().Foreground(textMutedColor).Background(bgColor).Lipgloss()
+ ta.Styles.Blurred.Text = styles.NewStyle().Foreground(textColor).Background(bgColor).Lipgloss()
+ ta.Styles.Focused.Base = styles.NewStyle().Foreground(textColor).Background(bgColor).Lipgloss()
+ ta.Styles.Focused.CursorLine = styles.NewStyle().Background(bgColor).Lipgloss()
+ ta.Styles.Focused.Placeholder = styles.NewStyle().Foreground(textMutedColor).Background(bgColor).Lipgloss()
+ ta.Styles.Focused.Text = styles.NewStyle().Foreground(textColor).Background(bgColor).Lipgloss()
ta.Styles.Cursor.Color = t.Primary()
ta.Prompt = " "
@@ -317,18 +331,21 @@ func createTextArea(existing *textarea.Model) textarea.Model {
ta.SetHeight(existing.Height())
}
- ta.Focus()
+ // ta.Focus()
return ta
}
func createSpinner() spinner.Model {
+ t := theme.CurrentTheme()
return spinner.New(
spinner.WithSpinner(spinner.Ellipsis),
spinner.WithStyle(
- styles.
- Muted().
- Background(theme.CurrentTheme().Background()).
- Width(3)),
+ styles.NewStyle().
+ Foreground(t.Background()).
+ Foreground(t.TextMuted()).
+ Width(3).
+ Lipgloss(),
+ ),
)
}
diff --git a/packages/tui/internal/components/chat/message.go b/packages/tui/internal/components/chat/message.go
index c20bf6447..4f0293de5 100644
--- a/packages/tui/internal/components/chat/message.go
+++ b/packages/tui/internal/components/chat/message.go
@@ -129,15 +129,13 @@ func renderContentBlock(content string, options ...renderingOption) string {
option(renderer)
}
- style := styles.BaseStyle().
+ style := styles.NewStyle().Foreground(t.TextMuted()).Background(t.BackgroundPanel()).
// MarginTop(renderer.marginTop).
// MarginBottom(renderer.marginBottom).
PaddingTop(renderer.paddingTop).
PaddingBottom(renderer.paddingBottom).
PaddingLeft(renderer.paddingLeft).
PaddingRight(renderer.paddingRight).
- Background(t.BackgroundPanel()).
- Foreground(t.TextMuted()).
BorderStyle(lipgloss.ThickBorder())
align := lipgloss.Left
@@ -179,13 +177,13 @@ func renderContentBlock(content string, options ...renderingOption) string {
layout.Current.Container.Width,
align,
content,
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
)
content = lipgloss.PlaceHorizontal(
layout.Current.Viewport.Width,
lipgloss.Center,
content,
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
)
if renderer.marginTop > 0 {
for range renderer.marginTop {
@@ -226,7 +224,7 @@ func renderText(message client.MessageInfo, text string, author string) string {
textWidth := max(lipgloss.Width(text), lipgloss.Width(info))
markdownWidth := min(textWidth, width-padding-4) // -4 for the border and padding
if message.Role == client.Assistant {
- markdownWidth = width - padding - 4 - 2
+ markdownWidth = width - padding - 4 - 3
}
if message.Role == client.User {
text = strings.ReplaceAll(text, "<", "\\<")
@@ -275,9 +273,10 @@ func renderToolInvocation(
}
t := theme.CurrentTheme()
- style := styles.Muted().
- Width(outerWidth).
+ style := styles.NewStyle().
+ Foreground(t.TextMuted()).
Background(t.BackgroundPanel()).
+ Width(outerWidth).
PaddingTop(paddingTop).
PaddingBottom(paddingBottom).
PaddingLeft(2).
@@ -293,7 +292,9 @@ func renderToolInvocation(
if !showDetails {
title = "∟ " + title
padding := calculatePadding()
- style := lipgloss.NewStyle().Width(outerWidth - padding - 4).Background(t.BackgroundPanel())
+ style := styles.NewStyle().
+ Background(t.BackgroundPanel()).
+ Width(outerWidth - padding - 4 - 3)
return renderContentBlock(style.Render(title),
WithAlign(lipgloss.Left),
WithBorderColor(t.Accent()),
@@ -334,9 +335,9 @@ func renderToolInvocation(
if e, ok := metadata.Get("error"); ok && e.(bool) == true {
if m, ok := metadata.Get("message"); ok {
style = style.BorderLeftForeground(t.Error())
- error = styles.BaseStyle().
- Background(t.BackgroundPanel()).
+ error = styles.NewStyle().
Foreground(t.Error()).
+ Background(t.BackgroundPanel()).
Render(m.(string))
error = renderContentBlock(
error,
@@ -374,7 +375,7 @@ func renderToolInvocation(
formattedDiff, _ = diff.FormatDiff(filename, patch, diff.WithTotalWidth(diffWidth))
}
formattedDiff = strings.TrimSpace(formattedDiff)
- formattedDiff = lipgloss.NewStyle().
+ formattedDiff = styles.NewStyle().
BorderStyle(lipgloss.ThickBorder()).
BorderBackground(t.Background()).
BorderForeground(t.BackgroundPanel()).
@@ -394,7 +395,7 @@ func renderToolInvocation(
lipgloss.Center,
lipgloss.Top,
body,
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
)
}
}
@@ -506,7 +507,7 @@ func renderToolInvocation(
if !showDetails {
title = "∟ " + title
padding := calculatePadding()
- style := lipgloss.NewStyle().Width(outerWidth - padding - 4).Background(t.BackgroundPanel())
+ style := styles.NewStyle().Background(t.BackgroundPanel()).Width(outerWidth - padding - 4 - 3)
paddingBottom := 0
if isLast {
paddingBottom = 1
@@ -530,7 +531,7 @@ func renderToolInvocation(
layout.Current.Viewport.Width,
lipgloss.Center,
content,
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
)
if showDetails && body != "" && error == "" {
content += "\n" + body
diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go
index bdb6a6f82..da45545c9 100644
--- a/packages/tui/internal/components/chat/messages.go
+++ b/packages/tui/internal/components/chat/messages.go
@@ -245,7 +245,7 @@ func (m *messagesComponent) renderView() {
m.width,
lipgloss.Center,
block,
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
))
}
@@ -260,8 +260,8 @@ func (m *messagesComponent) header() string {
t := theme.CurrentTheme()
width := layout.Current.Container.Width
- base := styles.BaseStyle().Background(t.Background()).Render
- muted := styles.Muted().Background(t.Background()).Render
+ base := styles.NewStyle().Foreground(t.Text()).Background(t.Background()).Render
+ muted := styles.NewStyle().Foreground(t.TextMuted()).Background(t.Background()).Render
headerLines := []string{}
headerLines = append(headerLines, toMarkdown("# "+m.app.Session.Title, width-6, t.Background()))
if m.app.Session.Share != nil && m.app.Session.Share.Url != "" {
@@ -271,11 +271,11 @@ func (m *messagesComponent) header() string {
}
header := strings.Join(headerLines, "\n")
- header = styles.BaseStyle().
+ header = styles.NewStyle().
+ Background(t.Background()).
Width(width).
PaddingLeft(2).
PaddingRight(2).
- Background(t.Background()).
BorderLeft(true).
BorderRight(true).
BorderBackground(t.Background()).
@@ -306,7 +306,7 @@ func (m *messagesComponent) View() string {
m.width,
lipgloss.Center,
m.header(),
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
),
m.viewport.View(),
)
@@ -314,9 +314,9 @@ func (m *messagesComponent) View() string {
func (m *messagesComponent) home() string {
t := theme.CurrentTheme()
- baseStyle := styles.BaseStyle().Background(t.Background())
+ baseStyle := styles.NewStyle().Background(t.Background())
base := baseStyle.Render
- muted := styles.Muted().Background(t.Background()).Render
+ muted := styles.NewStyle().Foreground(t.TextMuted()).Background(t.Background()).Render
open := `
█▀▀█ █▀▀█ █▀▀ █▀▀▄
@@ -335,9 +335,9 @@ func (m *messagesComponent) home() string {
// cwd := app.Info.Path.Cwd
// config := app.Info.Path.Config
- versionStyle := lipgloss.NewStyle().
- Background(t.Background()).
+ versionStyle := styles.NewStyle().
Foreground(t.TextMuted()).
+ Background(t.Background()).
Width(lipgloss.Width(logo)).
Align(lipgloss.Right)
version := versionStyle.Render(m.app.Version)
@@ -347,14 +347,14 @@ func (m *messagesComponent) home() string {
m.width,
lipgloss.Center,
logoAndVersion,
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
)
m.commands.SetBackgroundColor(t.Background())
commands := lipgloss.PlaceHorizontal(
m.width,
lipgloss.Center,
m.commands.View(),
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
)
lines := []string{}
@@ -372,7 +372,7 @@ func (m *messagesComponent) home() string {
lipgloss.Center,
lipgloss.Center,
baseStyle.Render(strings.Join(lines, "\n")),
- lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
+ styles.WhitespaceStyle(t.Background()),
)
}