Skip to content

Commit 3751c01

Browse files
scttfrdmnclaude
andcommitted
Fix dependency conflicts and API compatibility
- Fix FileSystemID vs FileSystemId inconsistencies in TUI - Implement missing UI components (StatusBar and Spinner) - Fix mock client API implementation for context support - Add context-aware API wrappers for backward compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent ef633fa commit 3751c01

File tree

5 files changed

+1557
-0
lines changed

5 files changed

+1557
-0
lines changed

internal/tui/components/spinner.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package components
2+
3+
import (
4+
"time"
5+
6+
"github.com/charmbracelet/lipgloss"
7+
)
8+
9+
// Spinner represents a loading spinner component
10+
type Spinner struct {
11+
message string
12+
frames []string
13+
current int
14+
lastTick time.Time
15+
interval time.Duration
16+
active bool
17+
}
18+
19+
// NewSpinner creates a new spinner with the given message
20+
func NewSpinner(message string) *Spinner {
21+
return &Spinner{
22+
message: message,
23+
frames: []string{"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"},
24+
current: 0,
25+
lastTick: time.Now(),
26+
interval: 80 * time.Millisecond,
27+
active: true,
28+
}
29+
}
30+
31+
// Start activates the spinner
32+
func (s *Spinner) Start() {
33+
s.active = true
34+
}
35+
36+
// Stop deactivates the spinner
37+
func (s *Spinner) Stop() {
38+
s.active = false
39+
}
40+
41+
// SetMessage updates the spinner message
42+
func (s *Spinner) SetMessage(message string) {
43+
s.message = message
44+
}
45+
46+
// GetMessage returns the current spinner message
47+
func (s *Spinner) GetMessage() string {
48+
return s.message
49+
}
50+
51+
// IsActive returns whether the spinner is currently active
52+
func (s *Spinner) IsActive() bool {
53+
return s.active
54+
}
55+
56+
// Update advances the spinner animation if enough time has passed
57+
func (s *Spinner) Update() {
58+
if !s.active {
59+
return
60+
}
61+
62+
now := time.Now()
63+
if now.Sub(s.lastTick) >= s.interval {
64+
s.current = (s.current + 1) % len(s.frames)
65+
s.lastTick = now
66+
}
67+
}
68+
69+
// View renders the spinner
70+
func (s *Spinner) View() string {
71+
if !s.active {
72+
return ""
73+
}
74+
75+
spinnerStyle := lipgloss.NewStyle().
76+
Foreground(lipgloss.Color("6")).
77+
Bold(true)
78+
79+
messageStyle := lipgloss.NewStyle().
80+
Foreground(lipgloss.Color("15"))
81+
82+
spinnerText := spinnerStyle.Render(s.frames[s.current])
83+
messageText := messageStyle.Render(s.message)
84+
85+
return lipgloss.JoinHorizontal(
86+
lipgloss.Center,
87+
spinnerText,
88+
" ",
89+
messageText,
90+
)
91+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package components
2+
3+
import (
4+
"github.com/charmbracelet/lipgloss"
5+
)
6+
7+
// Status constants
8+
const (
9+
StatusNone = iota
10+
StatusSuccess
11+
StatusWarning
12+
StatusError
13+
)
14+
15+
// StatusBar represents a status bar component
16+
type StatusBar struct {
17+
version string
18+
region string
19+
status string
20+
style int
21+
}
22+
23+
// NewStatusBar creates a new status bar
24+
func NewStatusBar(version, region string) *StatusBar {
25+
return &StatusBar{
26+
version: version,
27+
region: region,
28+
status: "Ready",
29+
style: StatusNone,
30+
}
31+
}
32+
33+
// SetStatus updates the status message and style
34+
func (s *StatusBar) SetStatus(message string, style int) {
35+
s.status = message
36+
s.style = style
37+
}
38+
39+
// GetStatus returns the current status message
40+
func (s *StatusBar) GetStatus() string {
41+
return s.status
42+
}
43+
44+
// GetStatusStyle returns the current status style
45+
func (s *StatusBar) GetStatusStyle() int {
46+
return s.style
47+
}
48+
49+
// GetVersion returns the application version
50+
func (s *StatusBar) GetVersion() string {
51+
return s.version
52+
}
53+
54+
// GetRegion returns the current AWS region
55+
func (s *StatusBar) GetRegion() string {
56+
return s.region
57+
}
58+
59+
// SetRegion updates the current AWS region
60+
func (s *StatusBar) SetRegion(region string) {
61+
s.region = region
62+
}
63+
64+
// View renders the status bar
65+
func (s *StatusBar) View() string {
66+
// Define styles
67+
baseStyle := lipgloss.NewStyle().
68+
Width(100).
69+
Padding(0, 1).
70+
Bold(true)
71+
72+
versionStyle := baseStyle.Copy().
73+
Foreground(lipgloss.Color("#AAAAAA")).
74+
Align(lipgloss.Left)
75+
76+
statusStyle := baseStyle.Copy().Align(lipgloss.Center)
77+
78+
// Apply color based on style
79+
switch s.style {
80+
case StatusSuccess:
81+
statusStyle = statusStyle.Foreground(lipgloss.Color("10"))
82+
case StatusWarning:
83+
statusStyle = statusStyle.Foreground(lipgloss.Color("3"))
84+
case StatusError:
85+
statusStyle = statusStyle.Foreground(lipgloss.Color("9"))
86+
}
87+
88+
regionStyle := baseStyle.Copy().
89+
Foreground(lipgloss.Color("#AAAAAA")).
90+
Align(lipgloss.Right)
91+
92+
// Render components
93+
versionText := versionStyle.Render("v" + s.version)
94+
statusText := statusStyle.Render(s.status)
95+
regionText := regionStyle.Render(s.region)
96+
97+
// Combine and return
98+
return lipgloss.JoinHorizontal(
99+
lipgloss.Center,
100+
versionText,
101+
statusText,
102+
regionText,
103+
)
104+
}

0 commit comments

Comments
 (0)