package main import ( "fmt" "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "strings" "time" ) type Indicator struct { text string spinner spinner.Model quitting bool err error info IndicatorInfo } type IndicatorInfo struct { duration time.Duration quitting bool info string } func (i IndicatorInfo) String() string { if i.duration == 0 { return textStyle.Render(strings.Repeat(".", 30)) } return fmt.Sprintf("%s %s", textStyle.Render(i.duration.String()), i.info) } func initialIndicator(text string) Indicator { s := spinner.New() s.Spinner = spinner.Dot s.Style = lipgloss.NewStyle().Foreground(colors.green) return Indicator{spinner: s, text: text} } func (m Indicator) Init() tea.Cmd { return m.spinner.Tick } func (m Indicator) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case error: m.err = msg return m, nil case IndicatorInfo: m.info = msg m.quitting = msg.quitting return m, nil default: var cmd tea.Cmd m.spinner, cmd = m.spinner.Update(msg) return m, cmd } } func (m Indicator) View() string { if m.err != nil { return m.err.Error() } str := "" if !m.quitting { str += fmt.Sprintf("\n %s %s\n %s\n", m.spinner.View(), m.text, m.info.String()) } return str }