If using advanced settings, draw empty spinner when appropriate

When model.HideFor or model.MinimumLifetime is present, we won't draw
the spinner in cases where model.Visibe() returns false.
This commit is contained in:
Christian Rocha 2020-12-11 14:51:26 -05:00 committed by Christian Rocha
parent 3be2d0585b
commit 11f56f9b6b

View File

@ -1,9 +1,11 @@
package spinner package spinner
import ( import (
"strings"
"time" "time"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/muesli/reflow/ansi"
"github.com/muesli/termenv" "github.com/muesli/termenv"
) )
@ -105,12 +107,43 @@ type Model struct {
// Start resets resets the spinner start time. For use with MinimumLifetime and // Start resets resets the spinner start time. For use with MinimumLifetime and
// MinimumStartTime. Optional. // MinimumStartTime. Optional.
// //
// This function is optional and generally considered for advanced use only.
// Most of the time your application logic will obviate the need for this
// method.
//
// This is considered experimental and may not appear in future versions of // This is considered experimental and may not appear in future versions of
// this library. // this library.
func (m *Model) Start() { func (m *Model) Start() {
m.startTime = time.Now() m.startTime = time.Now()
} }
// Finish sets the internal timer to a completed state so long as the spinner
// isn't flagged to be showing. If it is showing, finish has no effect. The
// idea here is that you call Finish if your operation has completed and, if
// the spinner isn't showing yet (by virtue of HideFor) then Visible() doesn't
// show the spinner at all.
//
// This is intended to work in conjunction with MinimumLifetime and
// MinimumStartTime, is completely optional.
//
// This function is optional and generally considered for advanced use only.
// Most of the time your application logic will obviate the need for this
// method.
//
// This is considered experimental and may not appear in future versions of
// this library.
func (m *Model) Finish() {
if m.hidden() {
m.startTime = time.Time{}
}
}
// advancedMode returns whether or not the user is making use of HideFor and
// MinimumLifetime properties.
func (m Model) advancedMode() bool {
return m.HideFor > 0 && m.MinimumLifetime > 0
}
// hidden returns whether or not Model.HideFor is in effect. // hidden returns whether or not Model.HideFor is in effect.
func (m Model) hidden() bool { func (m Model) hidden() bool {
if m.startTime.IsZero() { if m.startTime.IsZero() {
@ -125,10 +158,7 @@ func (m Model) hidden() bool {
// finished returns whether the minimum lifetime of this spinner has been // finished returns whether the minimum lifetime of this spinner has been
// exceeded. // exceeded.
func (m Model) finished() bool { func (m Model) finished() bool {
if m.startTime.IsZero() { if m.startTime.IsZero() || m.MinimumLifetime == 0 {
return true
}
if m.MinimumLifetime == 0 {
return true return true
} }
return m.startTime.Add(m.HideFor).Add(m.MinimumLifetime).Before(time.Now()) return m.startTime.Add(m.HideFor).Add(m.MinimumLifetime).Before(time.Now())
@ -140,9 +170,9 @@ func (m Model) finished() bool {
// the parent view and whether to continue sending spin messaging in the // the parent view and whether to continue sending spin messaging in the
// parent update function. // parent update function.
// //
// Also note that using this function is optional and generally considered for // This function is optional and generally considered for advanced use only.
// advanced use only. Most of the time your application logic will determine // Most of the time your application logic will obviate the need for this
// whether or not this view should be used. // method.
// //
// This is considered experimental and may not appear in future versions of // This is considered experimental and may not appear in future versions of
// this library. // this library.
@ -195,6 +225,13 @@ func (m Model) View() string {
frame := m.Spinner.Frames[m.frame] frame := m.Spinner.Frames[m.frame]
// If we're using the fine-grained hide/show spinner rules and those rules
// deem that the spinner should be hidden, draw an empty space in place of
// the spinner.
if m.advancedMode() && !m.Visible() {
frame = strings.Repeat(" ", ansi.PrintableRuneWidth(frame))
}
if m.ForegroundColor != "" || m.BackgroundColor != "" { if m.ForegroundColor != "" || m.BackgroundColor != "" {
return termenv. return termenv.
String(frame). String(frame).