diff options
| author | adamdottv <[email protected]> | 2025-06-12 05:35:40 -0500 |
|---|---|---|
| committer | adamdottv <[email protected]> | 2025-06-12 16:00:24 -0500 |
| commit | cce2e4ad754479917fc8f6f24c1421cf19c04573 (patch) | |
| tree | 62c0ec32358932a468af73b44fd28e7de7859bbe /packages/tui/internal/components/dialog | |
| parent | a1ce35c208bf9ebca37f722e845035bd7fd5e801 (diff) | |
| download | opencode-cce2e4ad754479917fc8f6f24c1421cf19c04573.tar.gz opencode-cce2e4ad754479917fc8f6f24c1421cf19c04573.zip | |
wip: refactoring tui
Diffstat (limited to 'packages/tui/internal/components/dialog')
| -rw-r--r-- | packages/tui/internal/components/dialog/arguments.go | 41 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/commands.go | 22 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/complete.go | 12 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/custom_commands.go | 2 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/filepicker.go | 49 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/help.go | 31 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/init.go | 6 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/models.go | 34 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/permission.go | 60 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/quit.go | 20 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/session.go | 24 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/theme.go | 20 | ||||
| -rw-r--r-- | packages/tui/internal/components/dialog/tools.go | 40 |
13 files changed, 185 insertions, 176 deletions
diff --git a/packages/tui/internal/components/dialog/arguments.go b/packages/tui/internal/components/dialog/arguments.go index 2faa36070..4ef21fcf4 100644 --- a/packages/tui/internal/components/dialog/arguments.go +++ b/packages/tui/internal/components/dialog/arguments.go @@ -2,10 +2,10 @@ package dialog import ( "fmt" - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + "github.com/charmbracelet/bubbles/v2/textinput" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" @@ -70,17 +70,24 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu for i, name := range argNames { ti := textinput.New() ti.Placeholder = fmt.Sprintf("Enter value for %s...", name) - ti.Width = 40 + ti.SetWidth(40) ti.Prompt = "" - ti.PlaceholderStyle = ti.PlaceholderStyle.Background(t.Background()) - ti.PromptStyle = ti.PromptStyle.Background(t.Background()) - ti.TextStyle = ti.TextStyle.Background(t.Background()) + ti.Styles.Blurred.Placeholder = ti.Styles.Blurred.Placeholder.Background(t.Background()) + ti.Styles.Blurred.Text = ti.Styles.Blurred.Text.Background(t.Background()) + ti.Styles.Blurred.Prompt = ti.Styles.Blurred.Prompt.Foreground(t.Primary()) + + ti.Styles.Focused.Placeholder = ti.Styles.Focused.Placeholder.Background(t.Background()) + ti.Styles.Focused.Text = ti.Styles.Focused.Text.Background(t.Background()) + ti.Styles.Focused.Prompt = ti.Styles.Focused.Prompt.Foreground(t.Primary()) + + // ti.PromptStyle = ti.PromptStyle.Background(t.Background()) + // ti.TextStyle = ti.TextStyle.Background(t.Background()) // Only focus the first input initially if i == 0 { ti.Focus() - ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary()) - ti.TextStyle = ti.TextStyle.Foreground(t.Primary()) + // ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary()) + // ti.TextStyle = ti.TextStyle.Foreground(t.Primary()) } else { ti.Blur() } @@ -115,7 +122,7 @@ func (m MultiArgumentsDialogCmp) Init() tea.Cmd { // Update implements tea.Model. func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmds []tea.Cmd - t := theme.CurrentTheme() + // t := theme.CurrentTheme() switch msg := msg.(type) { case tea.KeyMsg: @@ -145,22 +152,22 @@ func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.inputs[m.focusIndex].Blur() m.focusIndex++ m.inputs[m.focusIndex].Focus() - m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary()) - m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary()) + // m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary()) + // m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary()) case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))): // Move to the next input m.inputs[m.focusIndex].Blur() m.focusIndex = (m.focusIndex + 1) % len(m.inputs) m.inputs[m.focusIndex].Focus() - m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary()) - m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary()) + // m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary()) + // m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary()) case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))): // Move to the previous input m.inputs[m.focusIndex].Blur() m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs) m.inputs[m.focusIndex].Focus() - m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary()) - m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary()) + // m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary()) + // m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary()) } case tea.WindowSizeMsg: m.width = msg.Width diff --git a/packages/tui/internal/components/dialog/commands.go b/packages/tui/internal/components/dialog/commands.go index 1e99c09e0..39fe793d7 100644 --- a/packages/tui/internal/components/dialog/commands.go +++ b/packages/tui/internal/components/dialog/commands.go @@ -1,9 +1,9 @@ package dialog import ( - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" utilComponents "github.com/sst/opencode/internal/components/util" "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/styles" @@ -56,12 +56,12 @@ type CloseCommandDialogMsg struct{} // CommandDialog interface for the command selection dialog type CommandDialog interface { - tea.Model + layout.ModelWithView layout.Bindings SetCommands(commands []Command) } -type commandDialogCmp struct { +type commandDialogComponent struct { listView utilComponents.SimpleList[Command] width int height int @@ -83,11 +83,11 @@ var commandKeys = commandKeyMap{ ), } -func (c *commandDialogCmp) Init() tea.Cmd { +func (c *commandDialogComponent) Init() tea.Cmd { return c.listView.Init() } -func (c *commandDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (c *commandDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmds []tea.Cmd switch msg := msg.(type) { case tea.KeyMsg: @@ -114,7 +114,7 @@ func (c *commandDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return c, tea.Batch(cmds...) } -func (c *commandDialogCmp) View() string { +func (c *commandDialogComponent) View() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -158,11 +158,11 @@ func (c *commandDialogCmp) View() string { Render(content) } -func (c *commandDialogCmp) BindingKeys() []key.Binding { +func (c *commandDialogComponent) BindingKeys() []key.Binding { return layout.KeyMapToSlice(commandKeys) } -func (c *commandDialogCmp) SetCommands(commands []Command) { +func (c *commandDialogComponent) SetCommands(commands []Command) { c.listView.SetItems(commands) } @@ -174,7 +174,7 @@ func NewCommandDialogCmp() CommandDialog { "No commands available", true, ) - return &commandDialogCmp{ + return &commandDialogComponent{ listView: listView, } } diff --git a/packages/tui/internal/components/dialog/complete.go b/packages/tui/internal/components/dialog/complete.go index ca209014e..91ac8f7b8 100644 --- a/packages/tui/internal/components/dialog/complete.go +++ b/packages/tui/internal/components/dialog/complete.go @@ -1,13 +1,13 @@ package dialog import ( - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/textarea" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/sst/opencode/internal/status" + "github.com/charmbracelet/bubbles/v2/key" + "github.com/charmbracelet/bubbles/v2/textarea" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" utilComponents "github.com/sst/opencode/internal/components/util" "github.com/sst/opencode/internal/layout" + "github.com/sst/opencode/internal/status" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" "github.com/sst/opencode/internal/util" @@ -77,7 +77,7 @@ type CompletionDialogCompleteItemMsg struct { type CompletionDialogCloseMsg struct{} type CompletionDialog interface { - tea.Model + layout.ModelWithView layout.Bindings SetWidth(width int) } diff --git a/packages/tui/internal/components/dialog/custom_commands.go b/packages/tui/internal/components/dialog/custom_commands.go index c0115ad7a..5e0671b80 100644 --- a/packages/tui/internal/components/dialog/custom_commands.go +++ b/packages/tui/internal/components/dialog/custom_commands.go @@ -7,7 +7,7 @@ import ( "regexp" "strings" - tea "github.com/charmbracelet/bubbletea" + tea "github.com/charmbracelet/bubbletea/v2" "github.com/sst/opencode/internal/app" "github.com/sst/opencode/internal/util" ) diff --git a/packages/tui/internal/components/dialog/filepicker.go b/packages/tui/internal/components/dialog/filepicker.go index 3fad90e3f..408b9cc00 100644 --- a/packages/tui/internal/components/dialog/filepicker.go +++ b/packages/tui/internal/components/dialog/filepicker.go @@ -12,13 +12,14 @@ import ( "log/slog" "github.com/atotto/clipboard" - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/textinput" - "github.com/charmbracelet/bubbles/viewport" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + "github.com/charmbracelet/bubbles/v2/textinput" + "github.com/charmbracelet/bubbles/v2/viewport" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/app" "github.com/sst/opencode/internal/image" + "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/status" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" @@ -82,7 +83,7 @@ var filePickerKeyMap = FilePrickerKeyMap{ ), } -type filepickerCmp struct { +type filepickerComponent struct { basePath string width int height int @@ -118,18 +119,18 @@ type AttachmentAddedMsg struct { Attachment app.Attachment } -func (f *filepickerCmp) Init() tea.Cmd { +func (f *filepickerComponent) Init() tea.Cmd { return nil } -func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (f *filepickerComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { case tea.WindowSizeMsg: f.width = 60 f.height = 20 - f.viewport.Width = 80 - f.viewport.Height = 22 + f.viewport.SetWidth(80) + f.viewport.SetHeight(22) f.cursor = 0 f.getCurrentFileBelowCursor() case tea.KeyMsg: @@ -236,7 +237,7 @@ func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return f, cmd } -func (f *filepickerCmp) addAttachmentToMessage() (tea.Model, tea.Cmd) { +func (f *filepickerComponent) addAttachmentToMessage() (tea.Model, tea.Cmd) { // modeInfo := GetSelectedModel(config.Get()) // if !modeInfo.SupportsAttachments { // status.Error(fmt.Sprintf("Model %s doesn't support attachments", modeInfo.Name)) @@ -273,7 +274,7 @@ func (f *filepickerCmp) addAttachmentToMessage() (tea.Model, tea.Cmd) { return f, util.CmdHandler(AttachmentAddedMsg{attachment}) } -func (f *filepickerCmp) View() string { +func (f *filepickerComponent) View() string { t := theme.CurrentTheme() const maxVisibleDirs = 20 const maxWidth = 80 @@ -333,7 +334,7 @@ func (f *filepickerCmp) View() string { Render(f.cwd.View()) viewportstyle := lipgloss.NewStyle(). - Width(f.viewport.Width). + Width(f.viewport.Width()). Background(t.Background()). Border(lipgloss.RoundedBorder()). BorderForeground(t.TextMuted()). @@ -366,21 +367,21 @@ func (f *filepickerCmp) View() string { return lipgloss.JoinHorizontal(lipgloss.Center, contentStyle.Render(content), viewportstyle) } -type FilepickerCmp interface { - tea.Model +type FilepickerComponent interface { + layout.ModelWithView ToggleFilepicker(showFilepicker bool) IsCWDFocused() bool } -func (f *filepickerCmp) ToggleFilepicker(showFilepicker bool) { +func (f *filepickerComponent) ToggleFilepicker(showFilepicker bool) { f.ShowFilePicker = showFilepicker } -func (f *filepickerCmp) IsCWDFocused() bool { +func (f *filepickerComponent) IsCWDFocused() bool { return f.cwd.Focused() } -func NewFilepickerCmp(app *app.App) FilepickerCmp { +func NewFilepickerCmp(app *app.App) FilepickerComponent { homepath, err := os.UserHomeDir() if err != nil { slog.Error("error loading user files") @@ -388,16 +389,16 @@ func NewFilepickerCmp(app *app.App) FilepickerCmp { } baseDir := DirNode{parent: nil, directory: homepath} dirs := readDir(homepath, false) - viewport := viewport.New(0, 0) + viewport := viewport.New() // viewport.New(0, 0) currentDirectory := textinput.New() currentDirectory.CharLimit = 200 - currentDirectory.Width = 44 - currentDirectory.Cursor.Blink = true + currentDirectory.SetWidth(44) + // currentDirectory.Cursor.Blink = true currentDirectory.SetValue(baseDir.directory) - return &filepickerCmp{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app} + return &filepickerComponent{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app} } -func (f *filepickerCmp) getCurrentFileBelowCursor() { +func (f *filepickerComponent) getCurrentFileBelowCursor() { if len(f.dirs) == 0 || f.cursor < 0 || f.cursor >= len(f.dirs) { slog.Error(fmt.Sprintf("Invalid cursor position. Dirs length: %d, Cursor: %d", len(f.dirs), f.cursor)) f.viewport.SetContent("Preview unavailable") @@ -410,7 +411,7 @@ func (f *filepickerCmp) getCurrentFileBelowCursor() { fullPath := f.cwdDetails.directory + "/" + dir.Name() go func() { - imageString, err := image.ImagePreview(f.viewport.Width-4, fullPath) + imageString, err := image.ImagePreview(f.viewport.Width()-4, fullPath) if err != nil { slog.Error(err.Error()) f.viewport.SetContent("Preview unavailable") diff --git a/packages/tui/internal/components/dialog/help.go b/packages/tui/internal/components/dialog/help.go index a55e39e72..6ceeb40b2 100644 --- a/packages/tui/internal/components/dialog/help.go +++ b/packages/tui/internal/components/dialog/help.go @@ -3,28 +3,29 @@ package dialog import ( "strings" - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" + "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" ) -type helpCmp struct { +type helpComponent struct { width int height int keys []key.Binding } -func (h *helpCmp) Init() tea.Cmd { +func (h *helpComponent) Init() tea.Cmd { return nil } -func (h *helpCmp) SetBindings(k []key.Binding) { +func (h *helpComponent) SetBindings(k []key.Binding) { h.keys = k } -func (h *helpCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (h *helpComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: h.width = 90 @@ -53,7 +54,7 @@ func removeDuplicateBindings(bindings []key.Binding) []key.Binding { return result } -func (h *helpCmp) render() string { +func (h *helpComponent) render() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -134,7 +135,7 @@ func (h *helpCmp) render() string { pairs = append(pairs, pair) } - // https://github.com/charmbracelet/lipgloss/issues/209 + // https://github.com/charmbracelet/lipgloss/v2/issues/209 if len(pairs) > 1 { prefix := pairs[:len(pairs)-1] lastPair := pairs[len(pairs)-1] @@ -144,7 +145,7 @@ func (h *helpCmp) render() string { lipgloss.Left, // x lipgloss.Top, // y lastPair, // content - lipgloss.WithWhitespaceBackground(t.Background()), + // lipgloss.WithWhitespaceBackground(t.Background()), )) content := baseStyle.Width(h.width).Render( lipgloss.JoinHorizontal( @@ -165,7 +166,7 @@ func (h *helpCmp) render() string { return content } -func (h *helpCmp) View() string { +func (h *helpComponent) View() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -190,11 +191,11 @@ func (h *helpCmp) View() string { ) } -type HelpCmp interface { - tea.Model +type HelpComponent interface { + layout.ModelWithView SetBindings([]key.Binding) } -func NewHelpCmp() HelpCmp { - return &helpCmp{} +func NewHelpCmp() HelpComponent { + return &helpComponent{} } diff --git a/packages/tui/internal/components/dialog/init.go b/packages/tui/internal/components/dialog/init.go index 01bdbe577..d939427c1 100644 --- a/packages/tui/internal/components/dialog/init.go +++ b/packages/tui/internal/components/dialog/init.go @@ -1,9 +1,9 @@ package dialog import ( - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" diff --git a/packages/tui/internal/components/dialog/models.go b/packages/tui/internal/components/dialog/models.go index 5d0ee772b..50d1791cd 100644 --- a/packages/tui/internal/components/dialog/models.go +++ b/packages/tui/internal/components/dialog/models.go @@ -7,9 +7,9 @@ import ( "slices" "strings" - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/app" "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/styles" @@ -31,13 +31,13 @@ type CloseModelDialogMsg struct { // ModelDialog interface for the model selection dialog type ModelDialog interface { - tea.Model + layout.ModelWithView layout.Bindings SetProviders(providers []client.ProviderInfo) } -type modelDialogCmp struct { +type modelDialogComponent struct { app *app.App availableProviders []client.ProviderInfo provider client.ProviderInfo @@ -106,7 +106,7 @@ var modelKeys = modelKeyMap{ ), } -func (m *modelDialogCmp) Init() tea.Cmd { +func (m *modelDialogComponent) Init() tea.Cmd { // cfg := config.Get() // modelInfo := GetSelectedModel(cfg) // m.availableProviders = getEnabledProviders(cfg) @@ -125,11 +125,11 @@ func (m *modelDialogCmp) Init() tea.Cmd { return nil } -func (m *modelDialogCmp) SetProviders(providers []client.ProviderInfo) { +func (m *modelDialogComponent) SetProviders(providers []client.ProviderInfo) { m.availableProviders = providers } -func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m *modelDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch { @@ -159,7 +159,7 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } -func (m *modelDialogCmp) models() []client.ProviderModel { +func (m *modelDialogComponent) models() []client.ProviderModel { models := slices.SortedFunc(maps.Values(m.provider.Models), func(a, b client.ProviderModel) int { return strings.Compare(*a.Name, *b.Name) }) @@ -167,7 +167,7 @@ func (m *modelDialogCmp) models() []client.ProviderModel { } // moveSelectionUp moves the selection up or wraps to bottom -func (m *modelDialogCmp) moveSelectionUp() { +func (m *modelDialogComponent) moveSelectionUp() { if m.selectedIdx > 0 { m.selectedIdx-- } else { @@ -182,7 +182,7 @@ func (m *modelDialogCmp) moveSelectionUp() { } // moveSelectionDown moves the selection down or wraps to top -func (m *modelDialogCmp) moveSelectionDown() { +func (m *modelDialogComponent) moveSelectionDown() { if m.selectedIdx < len(m.provider.Models)-1 { m.selectedIdx++ } else { @@ -196,7 +196,7 @@ func (m *modelDialogCmp) moveSelectionDown() { } } -func (m *modelDialogCmp) switchProvider(offset int) { +func (m *modelDialogComponent) switchProvider(offset int) { newOffset := m.hScrollOffset + offset // Ensure we stay within bounds @@ -212,7 +212,7 @@ func (m *modelDialogCmp) switchProvider(offset int) { m.setupModelsForProvider(m.provider.Id) } -func (m *modelDialogCmp) View() string { +func (m *modelDialogComponent) View() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -255,7 +255,7 @@ func (m *modelDialogCmp) View() string { Render(content) } -func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string { +func (m *modelDialogComponent) getScrollIndicators(maxWidth int) string { var indicator string if len(m.provider.Models) > numVisibleModels { @@ -291,7 +291,7 @@ func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string { Render(indicator) } -func (m *modelDialogCmp) BindingKeys() []key.Binding { +func (m *modelDialogComponent) BindingKeys() []key.Binding { return layout.KeyMapToSlice(modelKeys) } @@ -305,7 +305,7 @@ func (m *modelDialogCmp) BindingKeys() []key.Binding { // return -1 // } -func (m *modelDialogCmp) setupModelsForProvider(_ string) { +func (m *modelDialogComponent) setupModelsForProvider(_ string) { m.selectedIdx = 0 m.scrollOffset = 0 @@ -332,7 +332,7 @@ func (m *modelDialogCmp) setupModelsForProvider(_ string) { } func NewModelDialogCmp(app *app.App) ModelDialog { - return &modelDialogCmp{ + return &modelDialogComponent{ app: app, } } diff --git a/packages/tui/internal/components/dialog/permission.go b/packages/tui/internal/components/dialog/permission.go index bb71fc35d..526e03483 100644 --- a/packages/tui/internal/components/dialog/permission.go +++ b/packages/tui/internal/components/dialog/permission.go @@ -2,10 +2,10 @@ package dialog import ( "fmt" - "github.com/charmbracelet/bubbles/key" - "github.com/charmbracelet/bubbles/viewport" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + "github.com/charmbracelet/bubbles/v2/viewport" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" @@ -28,9 +28,9 @@ type PermissionResponseMsg struct { Action PermissionAction } -// PermissionDialogCmp interface for permission dialog component -type PermissionDialogCmp interface { - tea.Model +// PermissionDialogComponent interface for permission dialog component +type PermissionDialogComponent interface { + layout.ModelWithView layout.Bindings // SetPermissions(permission permission.PermissionRequest) tea.Cmd } @@ -76,8 +76,8 @@ var permissionsKeys = permissionsMapping{ ), } -// permissionDialogCmp is the implementation of PermissionDialog -type permissionDialogCmp struct { +// permissionDialogComponent is the implementation of PermissionDialog +type permissionDialogComponent struct { width int height int // permission permission.PermissionRequest @@ -89,11 +89,11 @@ type permissionDialogCmp struct { markdownCache map[string]string } -func (p *permissionDialogCmp) Init() tea.Cmd { +func (p *permissionDialogComponent) Init() tea.Cmd { return p.contentViewPort.Init() } -func (p *permissionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (p *permissionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmds []tea.Cmd switch msg := msg.(type) { @@ -129,7 +129,7 @@ func (p *permissionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return p, tea.Batch(cmds...) } -func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd { +func (p *permissionDialogComponent) selectCurrentOption() tea.Cmd { var action PermissionAction switch p.selectedOption { @@ -144,7 +144,7 @@ func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd { return util.CmdHandler(PermissionResponseMsg{Action: action}) // , Permission: p.permission}) } -func (p *permissionDialogCmp) renderButtons() string { +func (p *permissionDialogComponent) renderButtons() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -190,7 +190,7 @@ func (p *permissionDialogCmp) renderButtons() string { return content } -func (p *permissionDialogCmp) renderHeader() string { +func (p *permissionDialogComponent) renderHeader() string { return "NOT IMPLEMENTED" // t := theme.CurrentTheme() // baseStyle := styles.BaseStyle() @@ -246,7 +246,7 @@ func (p *permissionDialogCmp) renderHeader() string { // return lipgloss.NewStyle().Background(t.Background()).Render(lipgloss.JoinVertical(lipgloss.Left, headerParts...)) } -func (p *permissionDialogCmp) renderBashContent() string { +func (p *permissionDialogComponent) renderBashContent() string { // t := theme.CurrentTheme() // baseStyle := styles.BaseStyle() // @@ -269,7 +269,7 @@ func (p *permissionDialogCmp) renderBashContent() string { return "" } -func (p *permissionDialogCmp) renderEditContent() string { +func (p *permissionDialogComponent) renderEditContent() string { // if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok { // diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) { // return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width)) @@ -281,7 +281,7 @@ func (p *permissionDialogCmp) renderEditContent() string { return "" } -func (p *permissionDialogCmp) renderPatchContent() string { +func (p *permissionDialogComponent) renderPatchContent() string { // if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok { // diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) { // return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width)) @@ -293,7 +293,7 @@ func (p *permissionDialogCmp) renderPatchContent() string { return "" } -func (p *permissionDialogCmp) renderWriteContent() string { +func (p *permissionDialogComponent) renderWriteContent() string { // if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok { // // Use the cache for diff rendering // diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) { @@ -306,7 +306,7 @@ func (p *permissionDialogCmp) renderWriteContent() string { return "" } -func (p *permissionDialogCmp) renderFetchContent() string { +func (p *permissionDialogComponent) renderFetchContent() string { // t := theme.CurrentTheme() // baseStyle := styles.BaseStyle() // @@ -329,7 +329,7 @@ func (p *permissionDialogCmp) renderFetchContent() string { return "" } -func (p *permissionDialogCmp) renderDefaultContent() string { +func (p *permissionDialogComponent) renderDefaultContent() string { // t := theme.CurrentTheme() // baseStyle := styles.BaseStyle() // @@ -354,7 +354,7 @@ func (p *permissionDialogCmp) renderDefaultContent() string { return p.styleViewport() } -func (p *permissionDialogCmp) styleViewport() string { +func (p *permissionDialogComponent) styleViewport() string { t := theme.CurrentTheme() contentStyle := lipgloss.NewStyle(). Background(t.Background()) @@ -362,7 +362,7 @@ func (p *permissionDialogCmp) styleViewport() string { return contentStyle.Render(p.contentViewPort.View()) } -func (p *permissionDialogCmp) render() string { +func (p *permissionDialogComponent) render() string { return "NOT IMPLEMENTED" // t := theme.CurrentTheme() // baseStyle := styles.BaseStyle() @@ -420,15 +420,15 @@ func (p *permissionDialogCmp) render() string { // ) } -func (p *permissionDialogCmp) View() string { +func (p *permissionDialogComponent) View() string { return p.render() } -func (p *permissionDialogCmp) BindingKeys() []key.Binding { +func (p *permissionDialogComponent) BindingKeys() []key.Binding { return layout.KeyMapToSlice(permissionsKeys) } -func (p *permissionDialogCmp) SetSize() tea.Cmd { +func (p *permissionDialogComponent) SetSize() tea.Cmd { // if p.permission.ID == "" { // return nil // } @@ -458,7 +458,7 @@ func (p *permissionDialogCmp) SetSize() tea.Cmd { // } // Helper to get or set cached diff content -func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func() (string, error)) string { +func (c *permissionDialogComponent) GetOrSetDiff(key string, generator func() (string, error)) string { if cached, ok := c.diffCache[key]; ok { return cached } @@ -474,7 +474,7 @@ func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func() (string, } // Helper to get or set cached markdown content -func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (string, error)) string { +func (c *permissionDialogComponent) GetOrSetMarkdown(key string, generator func() (string, error)) string { if cached, ok := c.markdownCache[key]; ok { return cached } @@ -489,11 +489,11 @@ func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (str return content } -func NewPermissionDialogCmp() PermissionDialogCmp { +func NewPermissionDialogCmp() PermissionDialogComponent { // Create viewport for content - contentViewport := viewport.New(0, 0) + contentViewport := viewport.New() // (0, 0) - return &permissionDialogCmp{ + return &permissionDialogComponent{ contentViewPort: contentViewport, selectedOption: 0, // Default to "Allow" diffCache: make(map[string]string), diff --git a/packages/tui/internal/components/dialog/quit.go b/packages/tui/internal/components/dialog/quit.go index 78034c714..8362e7672 100644 --- a/packages/tui/internal/components/dialog/quit.go +++ b/packages/tui/internal/components/dialog/quit.go @@ -3,9 +3,9 @@ package dialog import ( "strings" - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" @@ -17,11 +17,11 @@ const question = "Are you sure you want to quit?" type CloseQuitMsg struct{} type QuitDialog interface { - tea.Model + layout.ModelWithView layout.Bindings } -type quitDialogCmp struct { +type quitDialogComponent struct { selectedNo bool } @@ -56,11 +56,11 @@ var helpKeys = helpMapping{ ), } -func (q *quitDialogCmp) Init() tea.Cmd { +func (q *quitDialogComponent) Init() tea.Cmd { return nil } -func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (q *quitDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch { @@ -81,7 +81,7 @@ func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return q, nil } -func (q *quitDialogCmp) View() string { +func (q *quitDialogComponent) View() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -125,12 +125,12 @@ func (q *quitDialogCmp) View() string { Render(content) } -func (q *quitDialogCmp) BindingKeys() []key.Binding { +func (q *quitDialogComponent) BindingKeys() []key.Binding { return layout.KeyMapToSlice(helpKeys) } func NewQuitCmp() QuitDialog { - return &quitDialogCmp{ + return &quitDialogComponent{ selectedNo: true, } } diff --git a/packages/tui/internal/components/dialog/session.go b/packages/tui/internal/components/dialog/session.go index 2d234529e..8ef9a701f 100644 --- a/packages/tui/internal/components/dialog/session.go +++ b/packages/tui/internal/components/dialog/session.go @@ -1,9 +1,9 @@ package dialog import ( - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" @@ -18,13 +18,13 @@ type CloseSessionDialogMsg struct { // SessionDialog interface for the session switching dialog type SessionDialog interface { - tea.Model + layout.ModelWithView layout.Bindings SetSessions(sessions []client.SessionInfo) SetSelectedSession(sessionID string) } -type sessionDialogCmp struct { +type sessionDialogComponent struct { sessions []client.SessionInfo selectedIdx int width int @@ -68,11 +68,11 @@ var sessionKeys = sessionKeyMap{ ), } -func (s *sessionDialogCmp) Init() tea.Cmd { +func (s *sessionDialogComponent) Init() tea.Cmd { return nil } -func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (s *sessionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: s.width = msg.Width @@ -105,7 +105,7 @@ func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return s, nil } -func (s *sessionDialogCmp) View() string { +func (s *sessionDialogComponent) View() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -185,11 +185,11 @@ func (s *sessionDialogCmp) View() string { Render(content) } -func (s *sessionDialogCmp) BindingKeys() []key.Binding { +func (s *sessionDialogComponent) BindingKeys() []key.Binding { return layout.KeyMapToSlice(sessionKeys) } -func (s *sessionDialogCmp) SetSessions(sessions []client.SessionInfo) { +func (s *sessionDialogComponent) SetSessions(sessions []client.SessionInfo) { s.sessions = sessions // If we have a selected session ID, find its index @@ -206,7 +206,7 @@ func (s *sessionDialogCmp) SetSessions(sessions []client.SessionInfo) { s.selectedIdx = 0 } -func (s *sessionDialogCmp) SetSelectedSession(sessionID string) { +func (s *sessionDialogComponent) SetSelectedSession(sessionID string) { s.selectedSessionID = sessionID // Update the selected index if sessions are already loaded @@ -222,7 +222,7 @@ func (s *sessionDialogCmp) SetSelectedSession(sessionID string) { // NewSessionDialogCmp creates a new session switching dialog func NewSessionDialogCmp() SessionDialog { - return &sessionDialogCmp{ + return &sessionDialogComponent{ sessions: []client.SessionInfo{}, selectedIdx: 0, selectedSessionID: "", diff --git a/packages/tui/internal/components/dialog/theme.go b/packages/tui/internal/components/dialog/theme.go index 42c777c41..4704cb42e 100644 --- a/packages/tui/internal/components/dialog/theme.go +++ b/packages/tui/internal/components/dialog/theme.go @@ -1,9 +1,9 @@ package dialog import ( - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/status" "github.com/sst/opencode/internal/styles" @@ -21,11 +21,11 @@ type CloseThemeDialogMsg struct{} // ThemeDialog interface for the theme switching dialog type ThemeDialog interface { - tea.Model + layout.ModelWithView layout.Bindings } -type themeDialogCmp struct { +type themeDialogComponent struct { themes []string selectedIdx int width int @@ -69,7 +69,7 @@ var themeKeys = themeKeyMap{ ), } -func (t *themeDialogCmp) Init() tea.Cmd { +func (t *themeDialogComponent) Init() tea.Cmd { // Load available themes and update selectedIdx based on current theme t.themes = theme.AvailableThemes() t.currentTheme = theme.CurrentThemeName() @@ -85,7 +85,7 @@ func (t *themeDialogCmp) Init() tea.Cmd { return nil } -func (t *themeDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (t *themeDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch { @@ -124,7 +124,7 @@ func (t *themeDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return t, nil } -func (t *themeDialogCmp) View() string { +func (t *themeDialogComponent) View() string { currentTheme := theme.CurrentTheme() baseStyle := styles.BaseStyle() @@ -185,13 +185,13 @@ func (t *themeDialogCmp) View() string { Render(content) } -func (t *themeDialogCmp) BindingKeys() []key.Binding { +func (t *themeDialogComponent) BindingKeys() []key.Binding { return layout.KeyMapToSlice(themeKeys) } // NewThemeDialogCmp creates a new theme switching dialog func NewThemeDialogCmp() ThemeDialog { - return &themeDialogCmp{ + return &themeDialogComponent{ themes: []string{}, selectedIdx: 0, currentTheme: "", diff --git a/packages/tui/internal/components/dialog/tools.go b/packages/tui/internal/components/dialog/tools.go index a01d1911b..c91dfef9a 100644 --- a/packages/tui/internal/components/dialog/tools.go +++ b/packages/tui/internal/components/dialog/tools.go @@ -1,9 +1,9 @@ package dialog import ( - "github.com/charmbracelet/bubbles/key" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/bubbles/v2/key" + tea "github.com/charmbracelet/bubbletea/v2" + "github.com/charmbracelet/lipgloss/v2" utilComponents "github.com/sst/opencode/internal/components/util" "github.com/sst/opencode/internal/layout" "github.com/sst/opencode/internal/styles" @@ -17,7 +17,7 @@ const ( // ToolsDialog interface for the tools list dialog type ToolsDialog interface { - tea.Model + layout.ModelWithView layout.Bindings SetTools(tools []string) } @@ -39,7 +39,7 @@ func (t toolItem) Render(selected bool, width int) string { baseStyle := styles.BaseStyle(). Width(width). Background(th.Background()) - + if selected { baseStyle = baseStyle. Background(th.Primary()). @@ -49,15 +49,15 @@ func (t toolItem) Render(selected bool, width int) string { baseStyle = baseStyle. Foreground(th.Text()) } - + return baseStyle.Render(t.name) } -type toolsDialogCmp struct { - tools []toolItem - width int - height int - list utilComponents.SimpleList[toolItem] +type toolsDialogComponent struct { + tools []toolItem + width int + height int + list utilComponents.SimpleList[toolItem] } type toolsKeyMap struct { @@ -91,21 +91,21 @@ var toolsKeys = toolsKeyMap{ ), } -func (m *toolsDialogCmp) Init() tea.Cmd { +func (m *toolsDialogComponent) Init() tea.Cmd { return nil } -func (m *toolsDialogCmp) SetTools(tools []string) { +func (m *toolsDialogComponent) SetTools(tools []string) { var toolItems []toolItem for _, name := range tools { toolItems = append(toolItems, toolItem{name: name}) } - + m.tools = toolItems m.list.SetItems(toolItems) } -func (m *toolsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m *toolsDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch { @@ -130,7 +130,7 @@ func (m *toolsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, cmd } -func (m *toolsDialogCmp) View() string { +func (m *toolsDialogComponent) View() string { t := theme.CurrentTheme() baseStyle := styles.BaseStyle().Background(t.Background()) @@ -144,7 +144,7 @@ func (m *toolsDialogCmp) View() string { // Calculate dialog width based on content dialogWidth := min(maxToolsDialogWidth, m.width/2) m.list.SetMaxWidth(dialogWidth) - + content := lipgloss.JoinVertical( lipgloss.Left, title, @@ -160,7 +160,7 @@ func (m *toolsDialogCmp) View() string { Render(content) } -func (m *toolsDialogCmp) BindingKeys() []key.Binding { +func (m *toolsDialogComponent) BindingKeys() []key.Binding { return layout.KeyMapToSlice(toolsKeys) } @@ -171,8 +171,8 @@ func NewToolsDialogCmp() ToolsDialog { "No tools available", true, ) - - return &toolsDialogCmp{ + + return &toolsDialogComponent{ list: list, } } |
