ollama/progress/spinner.go
2023-11-20 17:27:53 -08:00

73 lines
1.1 KiB
Go

package progress
import (
"fmt"
"strings"
"time"
)
type Spinner struct {
message string
messageWidth int
value int
ticker *time.Ticker
started time.Time
stopped time.Time
}
func NewSpinner(message string) *Spinner {
s := &Spinner{
message: message,
started: time.Now(),
value: 231,
}
go s.start()
return s
}
func (s *Spinner) String() string {
var sb strings.Builder
if len(s.message) > 0 {
message := strings.TrimSpace(s.message)
if s.messageWidth > 0 && len(message) > s.messageWidth {
message = message[:s.messageWidth]
}
fmt.Fprintf(&sb, "%s", message)
if s.messageWidth-sb.Len() >= 0 {
sb.WriteString(strings.Repeat(" ", s.messageWidth-sb.Len()))
}
sb.WriteString(" ")
}
if s.stopped.IsZero() {
sb.WriteString(fmt.Sprintf("\033[48;5;%dm ", s.value))
sb.WriteString("\033[0m")
}
return sb.String()
}
func (s *Spinner) start() {
s.ticker = time.NewTicker(40 * time.Millisecond)
for range s.ticker.C {
if s.value < 255 {
s.value++
} else {
s.value = 231
}
if !s.stopped.IsZero() {
return
}
}
}
func (s *Spinner) Stop() {
if s.stopped.IsZero() {
s.stopped = time.Now()
}
}