Skip to content

Commit ab671db

Browse files
committed
fix: stabilize progress bar display to prevent flickering
1 parent b61029b commit ab671db

1 file changed

Lines changed: 30 additions & 19 deletions

File tree

internal/ui/progress.go

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ var (
2727
)
2828

2929
type ProgressTracker struct {
30-
total int
31-
completed int
32-
active map[string]bool
33-
width int
34-
startTime time.Time
35-
mu sync.Mutex
36-
spinnerIdx int
37-
spinnerStop chan bool
30+
total int
31+
completed int
32+
active map[string]bool
33+
width int
34+
startTime time.Time
35+
mu sync.Mutex
36+
spinnerIdx int
37+
spinnerStop chan bool
38+
lastDisplayed string
3839
}
3940

4041
var spinnerFrames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
@@ -80,6 +81,9 @@ func (p *ProgressTracker) Complete(pkgName string) {
8081
p.mu.Lock()
8182
defer p.mu.Unlock()
8283
delete(p.active, pkgName)
84+
if p.lastDisplayed == pkgName {
85+
p.lastDisplayed = ""
86+
}
8387
p.completed++
8488
p.render()
8589
}
@@ -92,32 +96,39 @@ func (p *ProgressTracker) render() {
9296
bar := progressBarStyle.Render(strings.Repeat("█", filled)) +
9397
progressBgStyle.Render(strings.Repeat("░", empty))
9498

95-
status := fmt.Sprintf(" %d/%d (%.0f%%)", p.completed, p.total, percent*100)
99+
status := fmt.Sprintf(" %d/%d (%3.0f%%)", p.completed, p.total, percent*100)
96100

97101
eta := p.estimateRemaining()
102+
if eta != "" {
103+
eta = fmt.Sprintf("%-6s", eta)
104+
}
98105

99-
spinner := ""
100106
activeDisplay := ""
101107
activeCount := len(p.active)
102108
if activeCount > 0 {
103-
spinner = currentPkgStyle.Render(spinnerFrames[p.spinnerIdx]) + " "
104-
for pkg := range p.active {
105-
if len(pkg) > 15 {
106-
pkg = pkg[:12] + "..."
109+
if p.lastDisplayed != "" && p.active[p.lastDisplayed] {
110+
activeDisplay = p.lastDisplayed
111+
} else {
112+
for pkg := range p.active {
113+
p.lastDisplayed = pkg
114+
activeDisplay = pkg
115+
break
107116
}
108-
activeDisplay = pkg
109-
break
117+
}
118+
if len(activeDisplay) > 12 {
119+
activeDisplay = activeDisplay[:12] + "..."
110120
}
111121
if activeCount > 1 {
112-
activeDisplay = fmt.Sprintf("%s +%d", activeDisplay, activeCount-1)
122+
activeDisplay = fmt.Sprintf("%-15s +%d", activeDisplay, activeCount-1)
123+
} else {
124+
activeDisplay = fmt.Sprintf("%-15s", activeDisplay)
113125
}
114126
}
115127

116-
fmt.Printf("\r\033[K%s%s %s %s%s",
128+
fmt.Printf("\r\033[K%s%s %s %s",
117129
bar,
118130
progressTextStyle.Render(status),
119131
etaStyle.Render(eta),
120-
spinner,
121132
currentPkgStyle.Render(activeDisplay))
122133
}
123134

0 commit comments

Comments
 (0)