From 7d2817812c848000a6059392fb51cbeae4b16d38 Mon Sep 17 00:00:00 2001 From: Leon Mika Date: Tue, 1 Nov 2022 21:59:46 +1100 Subject: [PATCH] Fixed various bugs and papercuts (#37) - Enabled CGO for release builds so that copy to clipboard does not panic. - Added a prompt to confirm quitting when pressing Esc or Ctrl+C - Fixed the table prompt to not quit app on Esc when invoked with the table command. --- .goreleaser.yml | 2 ++ .../dynamo-browse/controllers/tableread.go | 7 +++++-- .../controllers/tableread_test.go | 2 +- internal/dynamo-browse/ui/model.go | 19 +++++++++++------ .../ui/teamodels/tableselect/events.go | 13 ------------ .../ui/teamodels/tableselect/list.go | 1 + .../ui/teamodels/tableselect/model.go | 21 ++++++++++++++----- 7 files changed, 38 insertions(+), 27 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 656b588..5698d53 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -5,6 +5,8 @@ builds: - linux_amd64 - darwin_amd64 - darwin_arm64 + env: + - CGO_ENABLED=1 main: ./cmd/dynamo-browse/. binary: dynamo-browse archives: diff --git a/internal/dynamo-browse/controllers/tableread.go b/internal/dynamo-browse/controllers/tableread.go index 25889ed..e73d6cf 100644 --- a/internal/dynamo-browse/controllers/tableread.go +++ b/internal/dynamo-browse/controllers/tableread.go @@ -83,13 +83,13 @@ func (c *TableReadController) Init() tea.Msg { } if c.tableName == "" { - return c.ListTables() + return c.ListTables(true) } else { return c.ScanTable(c.tableName) } } -func (c *TableReadController) ListTables() tea.Msg { +func (c *TableReadController) ListTables(quitIfNoTable bool) tea.Msg { return NewJob(c.jobController, "Listing tables…", func(ctx context.Context) (any, error) { tables, err := c.tableService.ListTables(context.Background()) if err != nil { @@ -101,6 +101,9 @@ func (c *TableReadController) ListTables() tea.Msg { Tables: res.([]string), OnSelected: func(tableName string) tea.Msg { if tableName == "" { + if quitIfNoTable { + return tea.Quit() + } return events.StatusMsg("No table selected") } diff --git a/internal/dynamo-browse/controllers/tableread_test.go b/internal/dynamo-browse/controllers/tableread_test.go index ecbc1e9..268ce48 100644 --- a/internal/dynamo-browse/controllers/tableread_test.go +++ b/internal/dynamo-browse/controllers/tableread_test.go @@ -34,7 +34,7 @@ func TestTableReadController_ListTables(t *testing.T) { t.Run("returns a list of tables", func(t *testing.T) { srv := newService(t, serviceConfig{}) - event := srv.readController.ListTables().(controllers.PromptForTableMsg) + event := srv.readController.ListTables(false).(controllers.PromptForTableMsg) assert.Equal(t, []string{"alpha-table", "bravo-table"}, event.Tables) diff --git a/internal/dynamo-browse/ui/model.go b/internal/dynamo-browse/ui/model.go index bee7ce1..a1bd48a 100644 --- a/internal/dynamo-browse/ui/model.go +++ b/internal/dynamo-browse/ui/model.go @@ -87,7 +87,7 @@ func NewModel( "quit": commandctrl.NoArgCommand(tea.Quit), "table": func(ctx commandctrl.ExecContext, args []string) tea.Msg { if len(args) == 0 { - return rc.ListTables() + return rc.ListTables(false) } else { return rc.ScanTable(args[0]) } @@ -255,13 +255,11 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case key.Matches(msg, m.keyMap.PromptForCommand): return m, m.commandController.Prompt case key.Matches(msg, m.keyMap.PromptForTable): - return m, events.SetTeaMessage(m.tableReadController.ListTables()) + return m, events.SetTeaMessage(m.tableReadController.ListTables(false)) case key.Matches(msg, m.keyMap.CancelRunningJob): - return m, events.SetTeaMessage(m.jobController.CancelRunningJob(func() tea.Msg { - return tea.Quit() - })) + return m, events.SetTeaMessage(m.jobController.CancelRunningJob(m.promptToQuit)) case key.Matches(msg, m.keyMap.Quit): - return m, tea.Quit + return m, m.promptToQuit } } } @@ -312,3 +310,12 @@ func (m *Model) setMainViewIndex(viewIndex int) tea.Cmd { m.itemEdit.SetSubmodel(m.mainView) return m.tableView.Refresh() } + +func (m *Model) promptToQuit() tea.Msg { + return events.Confirm("Quit dynamo-browse? ", func(yes bool) tea.Msg { + if yes { + return tea.Quit() + } + return nil + }) +} diff --git a/internal/dynamo-browse/ui/teamodels/tableselect/events.go b/internal/dynamo-browse/ui/teamodels/tableselect/events.go index a51d187..a97005e 100644 --- a/internal/dynamo-browse/ui/teamodels/tableselect/events.go +++ b/internal/dynamo-browse/ui/teamodels/tableselect/events.go @@ -2,19 +2,6 @@ package tableselect import tea "github.com/charmbracelet/bubbletea" -func IndicateLoadingTables() tea.Cmd { - return func() tea.Msg { - return indicateLoadingTablesMsg{} - } -} -func ShowTableSelect(onSelected func(n string) tea.Cmd) tea.Cmd { - return func() tea.Msg { - return showTableSelectMsg{ - onSelected: onSelected, - } - } -} - type indicateLoadingTablesMsg struct{} type showTableSelectMsg struct { diff --git a/internal/dynamo-browse/ui/teamodels/tableselect/list.go b/internal/dynamo-browse/ui/teamodels/tableselect/list.go index 0629ce2..629a178 100644 --- a/internal/dynamo-browse/ui/teamodels/tableselect/list.go +++ b/internal/dynamo-browse/ui/teamodels/tableselect/list.go @@ -50,6 +50,7 @@ func newListController(tableNames []string, w, h int) listController { key.WithHelp("→/l/pgdn", "next page"), ) list.SetShowTitle(false) + list.DisableQuitKeybindings() return listController{list: list} } diff --git a/internal/dynamo-browse/ui/teamodels/tableselect/model.go b/internal/dynamo-browse/ui/teamodels/tableselect/model.go index afdae01..95c03a1 100644 --- a/internal/dynamo-browse/ui/teamodels/tableselect/model.go +++ b/internal/dynamo-browse/ui/teamodels/tableselect/model.go @@ -1,6 +1,7 @@ package tableselect import ( + "github.com/charmbracelet/bubbles/key" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" @@ -14,9 +15,12 @@ import ( var ( activeHeaderStyle = lipgloss.NewStyle(). - Bold(true). - Foreground(lipgloss.Color("#ffffff")). - Background(lipgloss.Color("#4479ff")) + Bold(true). + Foreground(lipgloss.Color("#ffffff")). + Background(lipgloss.Color("#4479ff")) + + chooseSelectedTableBinding = key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "select table")) + exitTableSelectionBinding = key.NewBinding(key.WithKeys("ctrl+c", "esc"), key.WithHelp("esc", "close selection")) ) type Model struct { @@ -50,8 +54,8 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil case tea.KeyMsg: if m.pendingSelection != nil { - switch msg.String() { - case "enter": + switch { + case key.Matches(msg, chooseSelectedTableBinding): if m.listController.list.FilterState() != list.Filtering { var sel controllers.PromptForTableMsg sel, m.pendingSelection = *m.pendingSelection, nil @@ -59,6 +63,13 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if selTableItem, isTableItem := m.listController.list.SelectedItem().(tableItem); isTableItem { return m, events.SetTeaMessage(sel.OnSelected(selTableItem.name)) } + return m, events.SetTeaMessage(sel.OnSelected("")) + } + case key.Matches(msg, exitTableSelectionBinding): + if m.listController.list.FilterState() != list.Filtering && m.listController.list.FilterState() != list.FilterApplied { + var sel controllers.PromptForTableMsg + sel, m.pendingSelection = *m.pendingSelection, nil + return m, events.SetTeaMessage(sel.OnSelected("")) } }