summaryrefslogtreecommitdiffhomepage
path: root/internal/tui/components
diff options
context:
space:
mode:
authorKujtim Hoxha <[email protected]>2025-04-11 18:54:13 +0200
committerKujtim Hoxha <[email protected]>2025-04-21 13:38:42 +0200
commit23e7a95083a8d875420c90e0479647f18a278c5f (patch)
tree3f91d3eaad7267030cf079e7f946de480ffb2e54 /internal/tui/components
parent6b1c64bcc75b89c530294b6a2d4404682b435d56 (diff)
downloadopencode-23e7a95083a8d875420c90e0479647f18a278c5f.tar.gz
opencode-23e7a95083a8d875420c90e0479647f18a278c5f.zip
intiial layout
Diffstat (limited to 'internal/tui/components')
-rw-r--r--internal/tui/components/chat/editor.go62
-rw-r--r--internal/tui/components/chat/messages.go21
-rw-r--r--internal/tui/components/chat/sidebar.go21
-rw-r--r--internal/tui/components/dialog/permission.go2
-rw-r--r--internal/tui/components/repl/editor.go48
5 files changed, 132 insertions, 22 deletions
diff --git a/internal/tui/components/chat/editor.go b/internal/tui/components/chat/editor.go
new file mode 100644
index 000000000..0b7617174
--- /dev/null
+++ b/internal/tui/components/chat/editor.go
@@ -0,0 +1,62 @@
+package chat
+
+import (
+ "github.com/charmbracelet/bubbles/key"
+ "github.com/charmbracelet/bubbles/textarea"
+ tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/lipgloss"
+ "github.com/kujtimiihoxha/termai/internal/tui/layout"
+ "github.com/kujtimiihoxha/termai/internal/tui/styles"
+)
+
+type editorCmp struct {
+ textarea textarea.Model
+}
+
+func (m *editorCmp) Init() tea.Cmd {
+ return textarea.Blink
+}
+
+func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ var cmd tea.Cmd
+ m.textarea, cmd = m.textarea.Update(msg)
+ return m, cmd
+}
+
+func (m *editorCmp) View() string {
+ style := lipgloss.NewStyle().Padding(0, 0, 0, 1).Bold(true)
+
+ return lipgloss.JoinHorizontal(lipgloss.Top, style.Render(">"), m.textarea.View())
+}
+
+func (m *editorCmp) SetSize(width, height int) {
+ m.textarea.SetWidth(width - 3) // account for the prompt and padding right
+ m.textarea.SetHeight(height)
+}
+
+func (m *editorCmp) GetSize() (int, int) {
+ return m.textarea.Width(), m.textarea.Height()
+}
+
+func (m *editorCmp) BindingKeys() []key.Binding {
+ return layout.KeyMapToSlice(m.textarea.KeyMap)
+}
+
+func NewEditorCmp() tea.Model {
+ ti := textarea.New()
+ ti.Prompt = " "
+ ti.ShowLineNumbers = false
+ ti.BlurredStyle.Base = ti.BlurredStyle.Base.Background(styles.Background)
+ ti.BlurredStyle.CursorLine = ti.BlurredStyle.CursorLine.Background(styles.Background)
+ ti.BlurredStyle.Placeholder = ti.BlurredStyle.Placeholder.Background(styles.Background)
+ ti.BlurredStyle.Text = ti.BlurredStyle.Text.Background(styles.Background)
+
+ ti.FocusedStyle.Base = ti.FocusedStyle.Base.Background(styles.Background)
+ ti.FocusedStyle.CursorLine = ti.FocusedStyle.CursorLine.Background(styles.Background)
+ ti.FocusedStyle.Placeholder = ti.FocusedStyle.Placeholder.Background(styles.Background)
+ ti.FocusedStyle.Text = ti.BlurredStyle.Text.Background(styles.Background)
+ ti.Focus()
+ return &editorCmp{
+ textarea: ti,
+ }
+}
diff --git a/internal/tui/components/chat/messages.go b/internal/tui/components/chat/messages.go
new file mode 100644
index 000000000..691954767
--- /dev/null
+++ b/internal/tui/components/chat/messages.go
@@ -0,0 +1,21 @@
+package chat
+
+import tea "github.com/charmbracelet/bubbletea"
+
+type messagesCmp struct{}
+
+func (m *messagesCmp) Init() tea.Cmd {
+ return nil
+}
+
+func (m *messagesCmp) Update(tea.Msg) (tea.Model, tea.Cmd) {
+ return m, nil
+}
+
+func (m *messagesCmp) View() string {
+ return "Messages"
+}
+
+func NewMessagesCmp() tea.Model {
+ return &messagesCmp{}
+}
diff --git a/internal/tui/components/chat/sidebar.go b/internal/tui/components/chat/sidebar.go
new file mode 100644
index 000000000..afdd241f4
--- /dev/null
+++ b/internal/tui/components/chat/sidebar.go
@@ -0,0 +1,21 @@
+package chat
+
+import tea "github.com/charmbracelet/bubbletea"
+
+type sidebarCmp struct{}
+
+func (m *sidebarCmp) Init() tea.Cmd {
+ return nil
+}
+
+func (m *sidebarCmp) Update(tea.Msg) (tea.Model, tea.Cmd) {
+ return m, nil
+}
+
+func (m *sidebarCmp) View() string {
+ return "Sidebar"
+}
+
+func NewSidebarCmp() tea.Model {
+ return &sidebarCmp{}
+}
diff --git a/internal/tui/components/dialog/permission.go b/internal/tui/components/dialog/permission.go
index 465f475d5..088697d55 100644
--- a/internal/tui/components/dialog/permission.go
+++ b/internal/tui/components/dialog/permission.go
@@ -441,7 +441,7 @@ func NewPermissionDialogCmd(permission permission.PermissionRequest) tea.Cmd {
layout.WithSinglePaneBordered(true),
layout.WithSinglePaneFocusable(true),
layout.WithSinglePaneActiveColor(styles.Warning),
- layout.WithSignlePaneBorderText(map[layout.BorderPosition]string{
+ layout.WithSinglePaneBorderText(map[layout.BorderPosition]string{
layout.TopMiddleBorder: " Permission Required ",
}),
)
diff --git a/internal/tui/components/repl/editor.go b/internal/tui/components/repl/editor.go
index 37ac275e3..e9493129d 100644
--- a/internal/tui/components/repl/editor.go
+++ b/internal/tui/components/repl/editor.go
@@ -156,30 +156,36 @@ func (m *editorCmp) Cancel() tea.Cmd {
}
func (m *editorCmp) Send() tea.Cmd {
- return func() tea.Msg {
- messages, err := m.app.Messages.List(m.sessionID)
- if err != nil {
- return util.ReportError(err)
- }
- if hasUnfinishedMessages(messages) {
- return util.ReportWarn("Assistant is still working on the previous message")
- }
- a, err := agent.NewCoderAgent(m.app)
- if err != nil {
- return util.ReportError(err)
- }
+ if m.cancelMessage != nil {
+ return util.ReportWarn("Assistant is still working on the previous message")
+ }
- content := strings.Join(m.editor.GetBuffer().Lines(), "\n")
- ctx, cancel := context.WithCancel(m.app.Context)
- m.cancelMessage = cancel
- go func() {
- defer cancel()
- a.Generate(ctx, m.sessionID, content)
- m.cancelMessage = nil
- }()
+ messages, err := m.app.Messages.List(m.sessionID)
+ if err != nil {
+ return util.ReportError(err)
+ }
+ if hasUnfinishedMessages(messages) {
+ return util.ReportWarn("Assistant is still working on the previous message")
+ }
+
+ a, err := agent.NewCoderAgent(m.app)
+ if err != nil {
+ return util.ReportError(err)
+ }
- return m.editor.Reset()
+ content := strings.Join(m.editor.GetBuffer().Lines(), "\n")
+ if len(content) == 0 {
+ return util.ReportWarn("Message is empty")
}
+ ctx, cancel := context.WithCancel(m.app.Context)
+ m.cancelMessage = cancel
+ go func() {
+ defer cancel()
+ a.Generate(ctx, m.sessionID, content)
+ m.cancelMessage = nil
+ }()
+
+ return m.editor.Reset()
}
func (m *editorCmp) View() string {