Render renders the spinner overlay.
()
| 160 | |
| 161 | // Render renders the spinner overlay. |
| 162 | func (w *WorktreeSpinner) Render() string { |
| 163 | modalWidth := min(65, w.width-10) |
| 164 | if modalWidth < 40 { |
| 165 | modalWidth = 40 |
| 166 | } |
| 167 | |
| 168 | var content strings.Builder |
| 169 | |
| 170 | // Title |
| 171 | titleStyle := lipgloss.NewStyle().Bold(true).Foreground(PrimaryColor) |
| 172 | content.WriteString(titleStyle.Render("Setting up worktree")) |
| 173 | content.WriteString("\n") |
| 174 | content.WriteString(DividerStyle.Render(strings.Repeat("─", modalWidth-4))) |
| 175 | content.WriteString("\n\n") |
| 176 | |
| 177 | spinnerFrames := []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} |
| 178 | spinnerStyle := lipgloss.NewStyle().Foreground(PrimaryColor) |
| 179 | checkStyle := lipgloss.NewStyle().Foreground(SuccessColor) |
| 180 | errorStyle := lipgloss.NewStyle().Foreground(ErrorColor) |
| 181 | textStyle := lipgloss.NewStyle().Foreground(TextColor) |
| 182 | mutedStyle := lipgloss.NewStyle().Foreground(MutedColor) |
| 183 | |
| 184 | // Render steps |
| 185 | for _, step := range w.steps { |
| 186 | if step.complete { |
| 187 | content.WriteString(checkStyle.Render("✓")) |
| 188 | content.WriteString(" ") |
| 189 | // Show completed label |
| 190 | completedLabel := strings.Replace(step.label, "Creating branch", "Created branch", 1) |
| 191 | completedLabel = strings.Replace(completedLabel, "Creating worktree", "Created worktree", 1) |
| 192 | completedLabel = strings.Replace(completedLabel, "Running setup", "Ran setup", 1) |
| 193 | content.WriteString(textStyle.Render(completedLabel)) |
| 194 | } else if step.errMsg != "" { |
| 195 | content.WriteString(errorStyle.Render("✗")) |
| 196 | content.WriteString(" ") |
| 197 | content.WriteString(errorStyle.Render(step.label)) |
| 198 | content.WriteString("\n") |
| 199 | content.WriteString(" ") |
| 200 | content.WriteString(errorStyle.Render(step.errMsg)) |
| 201 | } else if step.active { |
| 202 | frame := spinnerFrames[w.spinnerFrame%len(spinnerFrames)] |
| 203 | content.WriteString(spinnerStyle.Render(frame)) |
| 204 | content.WriteString(" ") |
| 205 | content.WriteString(textStyle.Render(step.label)) |
| 206 | } else { |
| 207 | content.WriteString(mutedStyle.Render("○")) |
| 208 | content.WriteString(" ") |
| 209 | content.WriteString(mutedStyle.Render(step.label)) |
| 210 | } |
| 211 | content.WriteString("\n") |
| 212 | } |
| 213 | |
| 214 | // Done state - show "Starting loop..." |
| 215 | if w.IsDone() { |
| 216 | content.WriteString("\n") |
| 217 | content.WriteString(checkStyle.Render("Starting loop...")) |
| 218 | } |
| 219 |