From 19de412fc57c1461b4e10f8cd9c4d76e7b9d6ad0 Mon Sep 17 00:00:00 2001 From: Sam Fredrickson Date: Thu, 21 Mar 2024 00:08:58 -0700 Subject: [PATCH] Add spinner that indicates an ongoing refresh. --- tui/tui.go | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/tui/tui.go b/tui/tui.go index 50b78e7..042bac1 100644 --- a/tui/tui.go +++ b/tui/tui.go @@ -7,6 +7,7 @@ import ( "code.humancabbage.net/sam/moonmath/config" "code.humancabbage.net/sam/moonmath/moon" + "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" @@ -19,6 +20,9 @@ var baseStyle = lipgloss.NewStyle(). type Model struct { math moon.Math + reloading bool + indicator spinner.Model + prices table.Model projections table.Model } @@ -55,29 +59,46 @@ func New(cfg config.Data) Model { table.WithStyles(tableStyle), ) + indicator := spinner.New() + indicator.Spinner = spinner.Points + indicator.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("69")) + return Model{ math: math, + indicator: indicator, prices: prices, projections: projections, } } func (m Model) Init() tea.Cmd { - return func() tea.Msg { - _ = m.math.Refresh(context.TODO()) - return m.math - } + return tea.Batch( + m.indicator.Tick, + func() tea.Msg { + return refresh{} + }, + ) } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { + case refresh: + m.reloading = true + return m, func() tea.Msg { + _ = m.math.Refresh(context.TODO()) + return m.math + } + case spinner.TickMsg: + var cmd tea.Cmd + m.indicator, cmd = m.indicator.Update(msg) + return m, cmd case moon.Math: m.math = msg + m.reloading = false refillPrice(&m) refillProjections(&m) return m, tea.Tick(time.Second*30, func(t time.Time) tea.Msg { - _ = m.math.Refresh(context.TODO()) - return m.math + return refresh{} }) case tea.KeyMsg: switch msg.String() { @@ -88,6 +109,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } +type refresh struct{} + func refillPrice(m *Model) { rows := []table.Row{ []string{string(m.math.Asset), fmt.Sprintf("$%0.2f", m.math.CurrentPrice)}, @@ -121,9 +144,18 @@ func transpose(slice []table.Row) []table.Row { func (m Model) View() string { var s string + indicator := "" + if m.reloading { + indicator = m.indicator.View() + } + right := lipgloss.JoinVertical( + lipgloss.Center, + baseStyle.Render(m.prices.View()), + indicator, + ) s += lipgloss.JoinHorizontal( lipgloss.Top, - baseStyle.Render(m.prices.View()), + right, baseStyle.Render(m.projections.View()), ) return s + "\n"