frostfs-node/cmd/frostfs-lens/internal/tui/loading.go
Aleksey Savchuk ed396448ac [#1223] lens/tui: Add TUI app to explore metabase
Signed-off-by: Aleksey Savchuk <a.savchuk@yadro.com>
2024-09-05 08:03:52 +00:00

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)
}