forked from TrueCloudLab/frostfs-node
72 lines
1.3 KiB
Go
72 lines
1.3 KiB
Go
package tui
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
"github.com/rivo/tview"
|
|
)
|
|
|
|
type LoadingBar struct {
|
|
*tview.Box
|
|
view *tview.TextView
|
|
secondsElapsed atomic.Int64
|
|
needDrawFunc func()
|
|
reset func()
|
|
}
|
|
|
|
func NewLoadingBar(needDrawFunc func()) *LoadingBar {
|
|
b := &LoadingBar{
|
|
Box: tview.NewBox(),
|
|
view: tview.NewTextView(),
|
|
needDrawFunc: needDrawFunc,
|
|
}
|
|
b.view.SetBackgroundColor(tview.Styles.PrimaryTextColor)
|
|
b.view.SetTextColor(b.GetBackgroundColor())
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *LoadingBar) Start(ctx context.Context) {
|
|
ctx, b.reset = context.WithCancel(ctx)
|
|
|
|
go func() {
|
|
ticker := time.NewTicker(1 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
b.secondsElapsed.Store(0)
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
b.secondsElapsed.Add(1)
|
|
b.needDrawFunc()
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (b *LoadingBar) Stop() {
|
|
b.reset()
|
|
}
|
|
|
|
func (b *LoadingBar) Draw(screen tcell.Screen) {
|
|
seconds := b.secondsElapsed.Load()
|
|
|
|
var time string
|
|
switch {
|
|
case seconds < 60:
|
|
time = fmt.Sprintf("%ds", seconds)
|
|
default:
|
|
time = fmt.Sprintf("%dm%ds", seconds/60, seconds%60)
|
|
}
|
|
b.view.SetText(fmt.Sprintf(" Loading... %s (press Escape to cancel) ", time))
|
|
|
|
x, y, width, _ := b.GetInnerRect()
|
|
b.view.SetRect(x, y, width, 1)
|
|
b.view.Draw(screen)
|
|
}
|