diff --git a/internal/ui/app.go b/internal/ui/app.go index ccedb07..b8e3880 100644 --- a/internal/ui/app.go +++ b/internal/ui/app.go @@ -11,6 +11,7 @@ import ( "github.com/akyriako/o7k/internal/plugins" "github.com/akyriako/o7k/internal/resource" "github.com/akyriako/o7k/internal/resources/contexts" + "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/table" "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/viewport" @@ -39,6 +40,7 @@ type Model struct { showLoading bool loaded bool loadID uint64 + spinner spinner.Model autoRefreshTimestamp *time.Time autoRefreshPaused bool @@ -106,6 +108,9 @@ func New(registry *resource.Registry, openstackContext *openstack.Context, plugi detail := viewport.New(1, 1) detail.SetHorizontalStep(4) + s := spinner.New() + s.Spinner = spinner.Points + m := Model{ version: version, @@ -121,9 +126,11 @@ func New(registry *resource.Registry, openstackContext *openstack.Context, plugi loading: true, showLoading: true, - loadingLabel: "Loading...", + loadingLabel: "Loading", loaded: false, loadID: 1, + + spinner: s, } m.command.SetSuggestions(m.suggestions()) @@ -134,6 +141,7 @@ func (m Model) Init() tea.Cmd { return tea.Batch( m.loadResource(), autoRefresh(), + m.spinner.Tick, ) } @@ -319,6 +327,15 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, cmd } + case spinner.TickMsg: + if !m.showLoading { + return m, nil + } + + var cmd tea.Cmd + m.spinner, cmd = m.spinner.Update(msg) + return m, cmd + case resourcesLoadedMsg: if msg.loadID != m.loadID { return m, nil @@ -429,7 +446,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.pluginHost.ContextChanged(m.context) m.status = fmt.Sprintf("connected to %s", m.context.Cloud) - m.loadingLabel = "Loading..." + m.loadingLabel = "Loading" cmd := m.refreshResource() return m, tea.Batch( @@ -537,8 +554,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil case resource.CommandCompletedMsg: - m.showLoading = false - m.loadingLabel = "" + //m.showLoading = false + //m.loadingLabel = "" return m, nil } @@ -599,7 +616,9 @@ func (m Model) View() string { rightTag = lipgloss.JoinHorizontal(lipgloss.Left, rightTag, autoRefreshMsgState, timeTag) if m.showLoading { - loadingTag := loadingStyle.Render(fmt.Sprintf(" %s ", m.loadingLabel)) + loadingLabelTag := infoStyle.Render(fmt.Sprintf(" %s ", m.loadingLabel)) + spinnerTag := loadingStyle.Render(fmt.Sprintf(" %s ", m.spinner.View())) + loadingTag := lipgloss.JoinHorizontal(lipgloss.Left, loadingLabelTag, spinnerTag) rightTag = lipgloss.JoinHorizontal(lipgloss.Left, loadingTag, rightTag) } diff --git a/internal/ui/commands.go b/internal/ui/commands.go index 8e80444..6ed5e76 100644 --- a/internal/ui/commands.go +++ b/internal/ui/commands.go @@ -107,22 +107,25 @@ func (m *Model) executeResourceCommand(key string) tea.Cmd { m.showLoading = true m.loadingLabel = command.StatusLabel if m.loadingLabel == "" { - m.loadingLabel = "Loading..." + m.loadingLabel = "Loading" } if m.resource.Kind() == "contexts" && key == "a" { m.activatingContext = true m.showLoading = true - m.loadingLabel = "Connecting to " + row.ID + "..." + m.loadingLabel = "Connecting to " + row.ID } cmd := m.resource.Execute(command, row) - return tea.Sequence( - cmd, - func() tea.Msg { - return resource.CommandCompletedMsg{} - }, + return tea.Batch( + m.spinner.Tick, + tea.Sequence( + cmd, + func() tea.Msg { + return resource.CommandCompletedMsg{} + }, + ), ) } } @@ -153,7 +156,7 @@ func (m *Model) switchResource(name string, scope resourceScope) tea.Cmd { m.loading = true m.showLoading = true - m.loadingLabel = "Loading..." + m.loadingLabel = "Loading" m.loaded = false m.itemCount = 0 m.loadID++ @@ -165,7 +168,10 @@ func (m *Model) switchResource(name string, scope resourceScope) tea.Cmd { m.Resize() - return m.loadResource() + return tea.Batch( + m.loadResource(), + m.spinner.Tick, + ) } func (m *Model) navigateResource(name string) tea.Cmd { @@ -268,10 +274,14 @@ func (m *Model) refreshResource() tea.Cmd { m.loading = true m.showLoading = true - m.loadingLabel = "Loading..." + m.spinner.Tick() + m.loadingLabel = "Loading" m.loadID++ - return m.loadResource() + return tea.Batch( + m.loadResource(), + m.spinner.Tick, + ) } func (m *Model) autoRefreshResource() tea.Cmd { @@ -284,10 +294,14 @@ func (m *Model) autoRefreshResource() tea.Cmd { m.loading = true m.showLoading = true - m.loadingLabel = "Refreshing..." + m.spinner.Tick() + m.loadingLabel = "Refreshing" m.loadID++ - return m.loadResource() + return tea.Batch( + m.loadResource(), + m.spinner.Tick, + ) } func (m Model) loadResource() tea.Cmd { diff --git a/internal/ui/styles.go b/internal/ui/styles.go index 857c7d5..b02e19f 100644 --- a/internal/ui/styles.go +++ b/internal/ui/styles.go @@ -49,7 +49,7 @@ var ( loadingStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#000000")). - Background(lipgloss.Color("#FFA500")). + Background(lipgloss.Color("#ff8c00")). Bold(true) infoStyle = lipgloss.NewStyle().