Skip to content

Commit

Permalink
Merge pull request #4 from chelnak/enhanced_configuration
Browse files Browse the repository at this point in the history
Enhanced configuration
  • Loading branch information
chelnak authored Jul 17, 2022
2 parents 0868c71 + 7e55a80 commit 4b84d98
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 33 deletions.
7 changes: 6 additions & 1 deletion examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import (
"time"

"github.com/chelnak/ysmrr"
"github.com/chelnak/ysmrr/pkg/charmap"
"github.com/chelnak/ysmrr/pkg/colors"
)

func main() {
// Create a new spinner manager
sm := ysmrr.NewSpinnerManager()
sm := ysmrr.NewSpinnerManager(
ysmrr.WithCharMap(charmap.Arrows),
ysmrr.WithSpinnerColor(colors.FgHiBlue),
)

// Set up our spinners
downloading := sm.AddSpinner("Downloading...")
Expand Down
79 changes: 55 additions & 24 deletions manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,11 @@ import (
"os"
"time"

"github.com/chelnak/ysmrr/pkg/charmap"
"github.com/chelnak/ysmrr/pkg/colors"
"github.com/chelnak/ysmrr/pkg/tput"
"github.com/fatih/color"
)

var Dots = []string{
"⠋",
"⠙",
"⠹",
"⠸",
"⠼",
"⠴",
"⠦",
"⠧",
"⠇",
"⠏",
}

// SpinnerManager manages spinners
type SpinnerManager interface {
AddSpinner(msg string) *spinner
Expand All @@ -36,6 +24,9 @@ type spinnerManager struct {
Spinners []*spinner
chars []string
frameDuration time.Duration
spinnerColor colors.Color
completeColor colors.Color
errorColor colors.Color
writer io.Writer
done chan bool
ticks *time.Ticker
Expand All @@ -44,9 +35,7 @@ type spinnerManager struct {

// AddSpinner adds a new spinner to the manager
func (sm *spinnerManager) AddSpinner(msg string) *spinner {
c := color.New(color.FgHiGreen)
spinner := NewSpinner(msg, c)

spinner := NewSpinner(msg, sm.spinnerColor, sm.completeColor, sm.errorColor)
sm.Spinners = append(sm.Spinners, spinner)
return spinner
}
Expand Down Expand Up @@ -75,11 +64,13 @@ func (sm *spinnerManager) setNextPos() {
func (sm *spinnerManager) renderFrame() {
for _, s := range sm.Spinners {
if s.complete {
fmt.Fprintf(sm.writer, "\r✓ %s\n", s.msg)
s.completeColor.Fprint(sm.writer, "\r✓")
fmt.Fprintf(sm.writer, " %s\n", s.msg)
} else if s.err {
fmt.Fprintf(sm.writer, "\r✗ %s\n", s.msg)
s.errorColor.Fprint(sm.writer, "\r✗")
fmt.Fprintf(sm.writer, " %s\n", s.msg)
} else {
s.c.Fprintf(sm.writer, "%s", sm.chars[sm.pos])
s.spinnerColor.Fprintf(sm.writer, "%s", sm.chars[sm.pos])
fmt.Fprintf(sm.writer, " %s\r", s.msg)
fmt.Fprint(sm.writer, "\n")
}
Expand All @@ -103,12 +94,52 @@ func (sm *spinnerManager) render() {
}
}

// NewSpinnerManager creates a new spinner manager
func NewSpinnerManager() SpinnerManager {
return &spinnerManager{
chars: Dots,
// Option represents a spinner manager option.
type Option func(*spinnerManager)

// NewSpinnerManager creates a new spinner manager.
func NewSpinnerManager(options ...Option) SpinnerManager {
sm := &spinnerManager{
chars: charmap.Dots,
frameDuration: 250 * time.Millisecond,
spinnerColor: colors.FgHiGreen,
errorColor: colors.FgHiRed,
completeColor: colors.FgHiGreen,
writer: os.Stdout,
done: make(chan bool),
}

for _, option := range options {
option(sm)
}

return sm
}

// WithChars sets the characters used for the spinners.
func WithCharMap(chars []string) Option {
return func(sm *spinnerManager) {
sm.chars = chars
}
}

// WithFrameDuration sets the duration of each frame.
func WithFrameDuration(d time.Duration) Option {
return func(sm *spinnerManager) {
sm.frameDuration = d
}
}

// WithSpinnerColor sets the color of the spinners.
func WithSpinnerColor(c colors.Color) Option {
return func(sm *spinnerManager) {
sm.spinnerColor = c
}
}

// WithWriter sets the writer used for the spinners.
func WithWriter(w io.Writer) Option {
return func(sm *spinnerManager) {
sm.writer = w
}
}
25 changes: 25 additions & 0 deletions pkg/charmap/charmap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package charmap

var Dots = []string{
"⠋",
"⠙",
"⠹",
"⠸",
"⠼",
"⠴",
"⠦",
"⠧",
"⠇",
"⠏",
}

var Arrows = []string{
"←",
"↖",
"↑",
"↗",
"→",
"↘",
"↓",
"↙",
}
32 changes: 32 additions & 0 deletions pkg/colors/colors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package colors

import "github.com/fatih/color"

// Color represents an item in the color map.
type Color int

const (
// FgHiGreen is a foreground high intensity green color.
FgHiGreen Color = iota

// FgHiYellow is a foreground high intensity yellow color.
FgHiYellow

// FgHiBlue is a foreground high intensity blue color.
FgHiBlue

// FgHiRed is a foreground high intensity red color.
FgHiRed
)

var lookup = map[Color]color.Attribute{
FgHiGreen: color.FgHiGreen,
FgHiYellow: color.FgHiYellow,
FgHiBlue: color.FgHiBlue,
FgHiRed: color.FgHiRed,
}

// Get returns a color.Color for the given color.
func GetColor(c Color) *color.Color {
return color.New(lookup[c])
}
35 changes: 27 additions & 8 deletions spinner.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,52 @@
package ysmrr

import "github.com/fatih/color"
import (
"sync"

"github.com/chelnak/ysmrr/pkg/colors"
"github.com/fatih/color"
)

// Spinner manages a single spinner
type spinner struct {
c *color.Color
msg string
complete bool
err bool
mutex sync.Mutex
spinnerColor *color.Color
completeColor *color.Color
errorColor *color.Color
msg string
complete bool
err bool
}

// Update updates the spinner message
func (s *spinner) Update(msg string) {
s.mutex.Lock()
defer s.mutex.Unlock()

s.msg = msg
}

// Complete marks the spinner as complete
func (s *spinner) Complete() {
s.mutex.Lock()
defer s.mutex.Unlock()

s.complete = true
}

// Error marks the spinner as error
func (s *spinner) Error() {
s.mutex.Lock()
defer s.mutex.Unlock()

s.err = true
}

func NewSpinner(msg string, c *color.Color) *spinner {
func NewSpinner(msg string, spinnerColor, completeColor, errorColor colors.Color) *spinner {
return &spinner{
c: c,
msg: msg,
spinnerColor: colors.GetColor(spinnerColor),
completeColor: colors.GetColor(completeColor),
errorColor: colors.GetColor(errorColor),
msg: msg,
}
}

0 comments on commit 4b84d98

Please sign in to comment.