♻️ I think I'm finally happy with the Spinner implementation

This commit is contained in:
Dan Jones 2024-10-25 13:17:35 -05:00
commit 2552adbd3e

View file

@ -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
}