wip: refactoring tui

This commit is contained in:
adamdottv
2025-06-12 09:35:19 -05:00
parent 98bd5109c2
commit ca0ea3f94d
6 changed files with 275 additions and 71 deletions

View File

@@ -3,7 +3,7 @@ package dialog
import (
"github.com/charmbracelet/bubbles/v2/key"
tea "github.com/charmbracelet/bubbletea/v2"
"github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/components/modal"
utilComponents "github.com/sst/opencode/internal/components/util"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
@@ -19,10 +19,11 @@ type CloseSessionDialogMsg struct {
// SessionDialog interface for the session switching dialog
type SessionDialog interface {
layout.ModelWithView
tea.Model
layout.Bindings
SetSessions(sessions []client.SessionInfo)
SetSelectedSession(sessionID string)
Render(background string) string
}
type sessionItem struct {
@@ -48,7 +49,8 @@ func (s sessionItem) Render(selected bool, width int) string {
return baseStyle.Padding(0, 1).Render(s.session.Title)
}
type sessionDialogComponent struct {
// sessionDialogContent is the inner content of the session dialog
type sessionDialogContent struct {
sessions []client.SessionInfo
width int
height int
@@ -72,11 +74,11 @@ var sessionKeys = sessionKeyMap{
),
}
func (s *sessionDialogComponent) Init() tea.Cmd {
func (s *sessionDialogContent) Init() tea.Cmd {
return nil
}
func (s *sessionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (s *sessionDialogContent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
s.width = msg.Width
@@ -110,17 +112,14 @@ func (s *sessionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return s, cmd
}
func (s *sessionDialogComponent) View() string {
func (s *sessionDialogContent) View() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle().Background(t.BackgroundElement())
outerWidth := layout.Current.Container.Width - 8
width := outerWidth - 4
width := layout.Current.Container.Width - 12
if len(s.sessions) == 0 {
return baseStyle.Padding(1, 2).
Border(lipgloss.RoundedBorder()).
BorderBackground(t.Background()).
BorderForeground(t.TextMuted()).
Foreground(t.TextMuted()).
Width(width).
Render("No sessions available")
}
@@ -128,50 +127,46 @@ func (s *sessionDialogComponent) View() string {
// Set the max width for the list
s.list.SetMaxWidth(width)
title := baseStyle.
Foreground(t.Primary()).
Bold(true).
Width(width).
Padding(0, 1).
Render("Switch Session")
content := lipgloss.JoinVertical(
lipgloss.Left,
title,
s.list.View(),
)
style := styles.BaseStyle().
PaddingTop(1).
PaddingBottom(1).
PaddingLeft(2).
PaddingRight(2).
Background(t.BackgroundElement()).
Foreground(t.TextMuted()).
BorderStyle(lipgloss.ThickBorder())
style = style.
BorderLeft(true).
BorderRight(true).
BorderLeftForeground(t.BackgroundSubtle()).
BorderLeftBackground(t.Background()).
BorderRightForeground(t.BackgroundSubtle()).
BorderRightBackground(t.Background())
return style.
Width(outerWidth).
Render(content)
return s.list.View()
}
func (s *sessionDialogComponent) BindingKeys() []key.Binding {
func (s *sessionDialogContent) BindingKeys() []key.Binding {
// Combine session dialog keys with list keys
dialogKeys := layout.KeyMapToSlice(sessionKeys)
listKeys := s.list.BindingKeys()
return append(dialogKeys, listKeys...)
}
// sessionDialogComponent wraps the content with a modal
type sessionDialogComponent struct {
content *sessionDialogContent
modal *modal.Modal
}
func (s *sessionDialogComponent) Init() tea.Cmd {
return s.modal.Init()
}
func (s *sessionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m, cmd := s.modal.Update(msg)
s.modal = m.(*modal.Modal)
return s, cmd
}
func (s *sessionDialogComponent) View() string {
return s.modal.View()
}
func (s *sessionDialogComponent) Render(background string) string {
return s.modal.Render(background)
}
func (s *sessionDialogComponent) BindingKeys() []key.Binding {
return s.modal.BindingKeys()
}
func (s *sessionDialogComponent) SetSessions(sessions []client.SessionInfo) {
s.sessions = sessions
s.content.sessions = sessions
// Convert sessions to sessionItems
var sessionItems []sessionItem
@@ -180,16 +175,16 @@ func (s *sessionDialogComponent) SetSessions(sessions []client.SessionInfo) {
sessionItems = append(sessionItems, sessionItem{session: sess})
}
s.list.SetItems(sessionItems)
s.content.list.SetItems(sessionItems)
}
func (s *sessionDialogComponent) SetSelectedSession(sessionID string) {
s.selectedSessionID = sessionID
s.content.selectedSessionID = sessionID
// Update the selected index if sessions are already loaded
if len(s.sessions) > 0 {
if len(s.content.sessions) > 0 {
// Re-set the sessions to update the selection
s.SetSessions(s.sessions)
s.SetSessions(s.content.sessions)
}
}
@@ -202,9 +197,15 @@ func NewSessionDialogCmp() SessionDialog {
true, // useAlphaNumericKeys
)
return &sessionDialogComponent{
content := &sessionDialogContent{
sessions: []client.SessionInfo{},
selectedSessionID: "",
list: list,
}
return &sessionDialogComponent{
content: content,
modal: modal.New(content, modal.WithTitle("Switch Session")),
}
}