Rework Spinner so that default spinners have FPS built-in

This commit is contained in:
Christian Rocha 2020-11-11 11:48:47 -05:00 committed by Christian Rocha
parent 9c38e101d2
commit 3d7cd43046

View File

@ -10,33 +10,58 @@ import (
const defaultFPS = time.Second / 10 const defaultFPS = time.Second / 10
// Spinner is a set of frames used in animating the spinner. // Spinner is a set of frames used in animating the spinner.
type Spinner = []string type Spinner struct {
Frames []string
FPS time.Duration
}
var ( var (
// Some spinners to choose from. You could also make your own. // Some spinners to choose from. You could also make your own.
Line = Spinner{"|", "/", "-", "\\"} Line = Spinner{
Dot = Spinner{"⣾ ", "⣽ ", "⣻ ", "⢿ ", "⡿ ", "⣟ ", "⣯ ", "⣷ "} Frames: []string{"|", "/", "-", "\\"},
Globe = Spinner{"🌍 ", "🌎 ", "🌏 "} FPS: time.Second / 10,
Moon = Spinner{"🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "} }
Monkey = Spinner{"🙈 ", "🙈 ", "🙉 ", "🙊 "} Dot = Spinner{
Jump = Spinner{"⢄", "⢂", "⢁", "⡁", "⡈", "⡐", "⡠"} Frames: []string{"⣾ ", "⣽ ", "⣻ ", "⢿ ", "⡿ ", "⣟ ", "⣯ ", "⣷ "},
Bit8 = Spinner{ FPS: time.Second / 10,
"", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⡀", "⡁", "⡂", "⡃", "⡄", "⡅", "⡆", "⡇", }
"⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎", "⠏", "⡈", "⡉", "⡊", "⡋", "⡌", "⡍", "⡎", "⡏", Jump = Spinner{
"⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⡐", "⡑", "⡒", "⡓", "⡔", "⡕", "⡖", "⡗", Frames: []string{"⢄", "⢂", "⢁", "⡁", "⡈", "⡐", "⡠"},
"⠘", "⠙", "⠚", "⠛", "⠜", "⠝", "⠞", "⠟", "⡘", "⡙", "⡚", "⡛", "⡜", "⡝", "⡞", "⡟", FPS: time.Second / 10,
"⠠", "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⡠", "⡡", "⡢", "⡣", "⡤", "⡥", "⡦", "⡧", }
"⠨", "⠩", "⠪", "⠫", "⠬", "⠭", "⠮", "⠯", "⡨", "⡩", "⡪", "⡫", "⡬", "⡭", "⡮", "⡯", Bit8 = Spinner{
"⠰", "⠱", "⠲", "⠳", "⠴", "⠵", "⠶", "⠷", "⡰", "⡱", "⡲", "⡳", "⡴", "⡵", "⡶", "⡷", Frames: []string{
"⠸", "⠹", "⠺", "⠻", "⠼", "⠽", "⠾", "⠿", "⡸", "⡹", "⡺", "⡻", "⡼", "⡽", "⡾", "⡿", "", "⠁", "⠂", "⠃", "⠄", "⠅", "⠆", "⠇", "⡀", "⡁", "⡂", "⡃", "⡄", "⡅", "⡆", "⡇",
"⢀", "⢁", "⢂", "⢃", "⢄", "⢅", "⢆", "⢇", "⣀", "⣁", "⣂", "⣃", "⣄", "⣅", "⣆", "⣇", "⠈", "⠉", "⠊", "⠋", "⠌", "⠍", "⠎", "⠏", "⡈", "⡉", "⡊", "⡋", "⡌", "⡍", "⡎", "⡏",
"⢈", "⢉", "⢊", "⢋", "⢌", "⢍", "⢎", "⢏", "⣈", "⣉", "⣊", "⣋", "⣌", "⣍", "⣎", "⣏", "⠐", "⠑", "⠒", "⠓", "⠔", "⠕", "⠖", "⠗", "⡐", "⡑", "⡒", "⡓", "⡔", "⡕", "⡖", "⡗",
"⢐", "⢑", "⢒", "⢓", "⢔", "⢕", "⢖", "⢗", "⣐", "⣑", "⣒", "⣓", "⣔", "⣕", "⣖", "⣗", "⠘", "⠙", "⠚", "⠛", "⠜", "⠝", "⠞", "⠟", "⡘", "⡙", "⡚", "⡛", "⡜", "⡝", "⡞", "⡟",
"⢘", "⢙", "⢚", "⢛", "⢜", "⢝", "⢞", "⢟", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟", "⠠", "⠡", "⠢", "⠣", "⠤", "⠥", "⠦", "⠧", "⡠", "⡡", "⡢", "⡣", "⡤", "⡥", "⡦", "⡧",
"⢠", "⢡", "⢢", "⢣", "⢤", "⢥", "⢦", "⢧", "⣠", "⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧", "⠨", "⠩", "⠪", "⠫", "⠬", "⠭", "⠮", "⠯", "⡨", "⡩", "⡪", "⡫", "⡬", "⡭", "⡮", "⡯",
"⢨", "⢩", "⢪", "⢫", "⢬", "⢭", "⢮", "⢯", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯", "⠰", "⠱", "⠲", "⠳", "⠴", "⠵", "⠶", "⠷", "⡰", "⡱", "⡲", "⡳", "⡴", "⡵", "⡶", "⡷",
"⢰", "⢱", "⢲", "⢳", "⢴", "⢵", "⢶", "⢷", "⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷", "⠸", "⠹", "⠺", "⠻", "⠼", "⠽", "⠾", "⠿", "⡸", "⡹", "⡺", "⡻", "⡼", "⡽", "⡾", "⡿",
"⢸", "⢹", "⢺", "⢻", "⢼", "⢽", "⢾", "⢿", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾", "⣿"} "⢀", "⢁", "⢂", "⢃", "⢄", "⢅", "⢆", "⢇", "⣀", "⣁", "⣂", "⣃", "⣄", "⣅", "⣆", "⣇",
"⢈", "⢉", "⢊", "⢋", "⢌", "⢍", "⢎", "⢏", "⣈", "⣉", "⣊", "⣋", "⣌", "⣍", "⣎", "⣏",
"⢐", "⢑", "⢒", "⢓", "⢔", "⢕", "⢖", "⢗", "⣐", "⣑", "⣒", "⣓", "⣔", "⣕", "⣖", "⣗",
"⢘", "⢙", "⢚", "⢛", "⢜", "⢝", "⢞", "⢟", "⣘", "⣙", "⣚", "⣛", "⣜", "⣝", "⣞", "⣟",
"⢠", "⢡", "⢢", "⢣", "⢤", "⢥", "⢦", "⢧", "⣠", "⣡", "⣢", "⣣", "⣤", "⣥", "⣦", "⣧",
"⢨", "⢩", "⢪", "⢫", "⢬", "⢭", "⢮", "⢯", "⣨", "⣩", "⣪", "⣫", "⣬", "⣭", "⣮", "⣯",
"⢰", "⢱", "⢲", "⢳", "⢴", "⢵", "⢶", "⢷", "⣰", "⣱", "⣲", "⣳", "⣴", "⣵", "⣶", "⣷",
"⢸", "⢹", "⢺", "⢻", "⢼", "⢽", "⢾", "⢿", "⣸", "⣹", "⣺", "⣻", "⣼", "⣽", "⣾", "⣿",
},
FPS: time.Second / 16,
}
Globe = Spinner{
Frames: []string{"🌍 ", "🌎 ", "🌏 "},
FPS: time.Second / 4,
}
Moon = Spinner{
Frames: []string{"🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "},
FPS: time.Second / 8,
}
Monkey = Spinner{
Frames: []string{"🙈 ", "🙉 ", "🙊 "},
FPS: time.Second / 3,
}
color = termenv.ColorProfile().Color color = termenv.ColorProfile().Color
) )
@ -45,22 +70,19 @@ var (
// rather than using Model as a struct literal. // rather than using Model as a struct literal.
type Model struct { type Model struct {
// Type is the set of frames to use. See Spinner. // Spinner settings to use. See type Spinner.
Frames Spinner Spinner Spinner
// FPS is the speed at which the ticker should tick. // ForegroundColor sets the background color of the spinner. It can be
FPS time.Duration // a hex code or one of the 256 ANSI colors. If the terminal emulator can't
// support the color specified it will automatically degrade (per
// ForegroundColor sets the background color of the spinner. It can be a // github.com/muesli/termenv).
// hex code or one of the 256 ANSI colors. If the terminal emulator can't
// doesn't support the color specified it will automatically degrade
// (per github.com/muesli/termenv).
ForegroundColor string ForegroundColor string
// BackgroundColor sets the background color of the spinner. It can be a // BackgroundColor sets the background color of the spinner. It can be
// hex code or one of the 256 ANSI colors. If the terminal emulator can't // a hex code or one of the 256 ANSI colors. If the terminal emulator can't
// doesn't support the color specified it will automatically degrade // support the color specified it will automatically degrade (per
// (per github.com/muesli/termenv). // github.com/muesli/termenv).
BackgroundColor string BackgroundColor string
// MinimumLifetime is the minimum amount of time the spinner can run. Any // MinimumLifetime is the minimum amount of time the spinner can run. Any
@ -137,10 +159,7 @@ func (m Model) Visible() bool {
// NewModel returns a model with default values. // NewModel returns a model with default values.
func NewModel() Model { func NewModel() Model {
return Model{ return Model{Spinner: Line}
Frames: Line,
FPS: defaultFPS,
}
} }
// TickMsg indicates that the timer has ticked and we should render a frame. // TickMsg indicates that the timer has ticked and we should render a frame.
@ -155,7 +174,7 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
switch msg.(type) { switch msg.(type) {
case TickMsg: case TickMsg:
m.frame++ m.frame++
if m.frame >= len(m.Frames) { if m.frame >= len(m.Spinner.Frames) {
m.frame = 0 m.frame = 0
} }
return m, m.tick() return m, m.tick()
@ -166,11 +185,11 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
// View renders the model's view. // View renders the model's view.
func (m Model) View() string { func (m Model) View() string {
if m.frame >= len(m.Frames) { if m.frame >= len(m.Spinner.Frames) {
return "error" return "(error)"
} }
frame := m.Frames[m.frame] frame := m.Spinner.Frames[m.frame]
if m.ForegroundColor != "" || m.BackgroundColor != "" { if m.ForegroundColor != "" || m.BackgroundColor != "" {
return termenv. return termenv.
@ -189,7 +208,7 @@ func Tick() tea.Msg {
} }
func (m Model) tick() tea.Cmd { func (m Model) tick() tea.Cmd {
return tea.Tick(m.FPS, func(t time.Time) tea.Msg { return tea.Tick(m.Spinner.FPS, func(t time.Time) tea.Msg {
return TickMsg{ return TickMsg{
Time: t, Time: t,
} }