diff --git a/cli/spin/spin.go b/cli/spin/spin.go index dd584d8..2896335 100644 --- a/cli/spin/spin.go +++ b/cli/spin/spin.go @@ -58,28 +58,47 @@ func (m model) View() string { return str } -func Spin(ctx context.Context, message string) (chan string, chan error) { - p := tea.NewProgram(newModel(message), tea.WithContext(ctx)) - - msgChan := make(chan string, 10) - errChan := make(chan error) - - go func() { - for { - m := <-msgChan - p.Send(textMessage(m)) - } - }() - go func() { - _, err := p.Run() - if errors.Is(err, context.Canceled) { - err = nil - } else if errors.Is(err, context.DeadlineExceeded) { - err = nil - } else if errors.Is(err, tea.ErrProgramKilled) { - err = nil - } - errChan <- err - }() - return msgChan, errChan +type Spinner interface { + Wait() error + SetMessage(string) + Err() error +} + +var _ Spinner = new(spin) + +type spin struct { + p *tea.Program + err error + finished chan struct{} +} + +func (s *spin) Wait() error { + <-s.finished + return s.Err() +} + +func (s *spin) SetMessage(msg string) { + s.p.Send(textMessage(msg)) +} + +func (s *spin) Err() error { + if errors.Is(s.err, context.Canceled) { + return nil + } else if errors.Is(s.err, context.DeadlineExceeded) { + return nil + } else if errors.Is(s.err, tea.ErrProgramKilled) { + return nil + } + return s.err +} + +func Spin(ctx context.Context, message string) Spinner { + p := tea.NewProgram(newModel(message), tea.WithContext(ctx)) + s := &spin{p: p, finished: make(chan struct{}, 1)} + go func() { + _, err := s.p.Run() + s.err = err + s.finished <- struct{}{} + }() + return s }