progress.go RawHistoryFolder
1package models
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/bnema/archup/internal/application/dto"
8 tea "github.com/charmbracelet/bubbletea"
9 "github.com/charmbracelet/lipgloss"
10)
11
12// ProgressModelImpl implements ProgressModel interface
13type ProgressModelImpl struct {
14 BaseModel
15
16 currentPhase string
17 phaseNumber int
18 totalPhases int
19 progressPercent int
20 message string
21 isError bool
22 lastMessage string
23 messageHistory []string
24 maxHistoryLength int
25}
26
27// NewProgressModel creates a new progress model
28func NewProgressModel() *ProgressModelImpl {
29 return &ProgressModelImpl{
30 maxHistoryLength: 10,
31 messageHistory: []string{},
32 }
33}
34
35// Init initializes the model
36func (pm *ProgressModelImpl) Init() tea.Cmd {
37 return nil
38}
39
40// UpdateProgress handles progress updates (called from app when progress updates arrive)
41func (pm *ProgressModelImpl) UpdateProgress(update *dto.ProgressUpdate) {
42 if update == nil {
43 return
44 }
45
46 pm.currentPhase = update.Phase
47 pm.phaseNumber = update.PhaseNumber
48 pm.totalPhases = update.TotalPhases
49 pm.progressPercent = update.ProgressPercent
50 pm.message = update.Message
51 pm.isError = update.IsError
52
53 // Add to history
54 if pm.message != "" && pm.message != pm.lastMessage {
55 pm.addToHistory(pm.message)
56 pm.lastMessage = pm.message
57 }
58}
59
60// Update handles tea.Msg (for tea.Model interface compatibility)
61func (pm *ProgressModelImpl) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
62 return pm, nil
63}
64
65// View renders the progress display
66// Deprecated: Use views.RenderProgress instead
67func (pm *ProgressModelImpl) View() string {
68 var b strings.Builder
69
70 b.WriteString("\n")
71 b.WriteString(lipgloss.NewStyle().
72 Bold(true).
73 Foreground(lipgloss.Color("12")).
74 Render("Installation Progress"))
75 b.WriteString("\n\n")
76
77 // Phase indicator
78 if pm.totalPhases > 0 {
79 phasePercent := int((float64(pm.phaseNumber) / float64(pm.totalPhases)) * 100)
80 b.WriteString(fmt.Sprintf("Phase %d/%d: %s [%d%%]\n", pm.phaseNumber, pm.totalPhases, pm.currentPhase, phasePercent))
81 }
82
83 // Progress bar
84 b.WriteString("\n")
85 b.WriteString(pm.renderProgressBar())
86 b.WriteString("\n\n")
87
88 // Current message
89 if pm.message != "" {
90 color := lipgloss.Color("11")
91 if pm.isError {
92 color = lipgloss.Color("1")
93 }
94 b.WriteString("Current: ")
95 b.WriteString(lipgloss.NewStyle().
96 Foreground(color).
97 Render(pm.message))
98 b.WriteString("\n\n")
99 }
100
101 // Message history
102 if len(pm.messageHistory) > 0 {
103 b.WriteString(lipgloss.NewStyle().
104 Faint(true).
105 Render("Recent activities:"))
106 b.WriteString("\n")
107
108 start := 0
109 if len(pm.messageHistory) > 5 {
110 start = len(pm.messageHistory) - 5
111 }
112 for _, msg := range pm.messageHistory[start:] {
113 b.WriteString(lipgloss.NewStyle().
114 Faint(true).
115 Render(" • " + msg))
116 b.WriteString("\n")
117 }
118 }
119
120 b.WriteString("\n")
121 b.WriteString(lipgloss.NewStyle().
122 Faint(true).
123 Render("Installation running... Press Ctrl+C to cancel"))
124
125 return b.String()
126}
127
128// GetPhaseProgress returns current and total phases
129func (pm *ProgressModelImpl) GetPhaseProgress() (int, int) {
130 return pm.phaseNumber, pm.totalPhases
131}
132
133// GetProgressPercent returns the overall progress percentage
134func (pm *ProgressModelImpl) GetProgressPercent() int {
135 return pm.progressPercent
136}
137
138// GetCurrentPhase returns the current phase name
139func (pm *ProgressModelImpl) GetCurrentPhase() string {
140 return pm.currentPhase
141}
142
143// GetMessage returns the current message
144func (pm *ProgressModelImpl) GetMessage() string {
145 return pm.message
146}
147
148// IsError returns whether the current message is an error
149func (pm *ProgressModelImpl) IsError() bool {
150 return pm.isError
151}
152
153// GetMessageHistory returns the message history
154func (pm *ProgressModelImpl) GetMessageHistory() []string {
155 return pm.messageHistory
156}
157
158// Helper methods
159
160func (pm *ProgressModelImpl) renderProgressBar() string {
161 width := 40
162 filled := (pm.progressPercent * width) / 100
163
164 bar := strings.Repeat("█", filled) + strings.Repeat("░", width-filled)
165
166 return fmt.Sprintf("[%s] %d%%", bar, pm.progressPercent)
167}
168
169func (pm *ProgressModelImpl) addToHistory(msg string) {
170 pm.messageHistory = append(pm.messageHistory, msg)
171 if len(pm.messageHistory) > pm.maxHistoryLength {
172 pm.messageHistory = pm.messageHistory[1:]
173 }
174}