whispervis/widgets/loader.go

88 lines
1.6 KiB
Go

package widgets
import (
"fmt"
"sync"
"github.com/gopherjs/vecty"
"github.com/gopherjs/vecty/elem"
)
// Loader implements prograss-bar style loader widget.
type Loader struct {
vecty.Core
mx sync.RWMutex
steps int
current int
}
// Render implements Component interface for Loader.
func (l *Loader) Render() vecty.ComponentOrHTML {
text := l.text()
return elem.Div(
vecty.Markup(
vecty.Style("text-align", "center"),
vecty.Style("position", "relative"),
vecty.Style("top", "50%"),
),
elem.Heading1(
vecty.Text(text),
),
)
}
// NewLoader creates new Loader.
func NewLoader() *Loader {
return &Loader{}
}
// Inc increases current value of loader by one.
func (l *Loader) Inc() {
l.mx.Lock()
if l.current < l.steps {
l.current++
}
l.mx.Unlock()
}
// Steps returns the total number of steps.
func (l *Loader) Steps() int {
l.mx.RLock()
defer l.mx.RUnlock()
return l.steps
}
// Reset resets the current state of Loader.
func (l *Loader) Reset() {
l.mx.Lock()
l.current = 0
l.mx.Unlock()
}
// SetSteps updates the number of steps for loader.
func (l *Loader) SetSteps(steps int) {
l.mx.Lock()
l.steps = steps
l.mx.Unlock()
}
// Progress reports Loader's progress in percentage.
func (l *Loader) Progress() float64 {
l.mx.RLock()
defer l.mx.RUnlock()
return 100 * float64(l.current) / float64(l.steps)
}
// text returns formatted string to display.
func (l *Loader) text() string {
var text string
progress := l.Progress()
if progress > 99.9 {
text = "Completed"
} else {
text = fmt.Sprintf("Loading %.0f%%...", progress)
}
return text
}