1package models
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/charmbracelet/bubbles/v2/textinput"
8 tea "github.com/charmbracelet/bubbletea/v2"
9 "github.com/charmbracelet/crush/internal/config"
10 "github.com/charmbracelet/crush/internal/tui/styles"
11 "github.com/charmbracelet/lipgloss/v2"
12)
13
14type APIKeyInput struct {
15 input textinput.Model
16 width int
17 height int
18 providerName string
19}
20
21func NewAPIKeyInput() *APIKeyInput {
22 t := styles.CurrentTheme()
23
24 ti := textinput.New()
25 ti.Placeholder = "Enter your API key..."
26 ti.SetWidth(50)
27 ti.SetVirtualCursor(false)
28 ti.Prompt = "> "
29 ti.SetStyles(t.S().TextInput)
30 ti.Focus()
31
32 return &APIKeyInput{
33 input: ti,
34 width: 60,
35 providerName: "Provider",
36 }
37}
38
39func (a *APIKeyInput) SetProviderName(name string) {
40 a.providerName = name
41}
42
43func (a *APIKeyInput) Init() tea.Cmd {
44 return textinput.Blink
45}
46
47func (a *APIKeyInput) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
48 switch msg := msg.(type) {
49 case tea.WindowSizeMsg:
50 a.width = msg.Width
51 a.height = msg.Height
52 }
53
54 var cmd tea.Cmd
55 a.input, cmd = a.input.Update(msg)
56 return a, cmd
57}
58
59func (a *APIKeyInput) View() string {
60 t := styles.CurrentTheme()
61
62 title := t.S().Base.
63 Foreground(t.Primary).
64 Bold(true).
65 Render(fmt.Sprintf("Enter your %s API Key", a.providerName))
66
67 inputView := a.input.View()
68
69 dataPath := config.GlobalConfigData()
70 dataPath = strings.Replace(dataPath, config.HomeDir(), "~", 1)
71 helpText := t.S().Muted.
72 Render(fmt.Sprintf("This will be written to the global configuration: %s", dataPath))
73
74 content := lipgloss.JoinVertical(
75 lipgloss.Left,
76 title,
77 "",
78 inputView,
79 "",
80 helpText,
81 )
82
83 return content
84}
85
86func (a *APIKeyInput) Cursor() *tea.Cursor {
87 cursor := a.input.Cursor()
88 if cursor != nil {
89 cursor.Y += 2 // Adjust for title and spacing
90 }
91 return cursor
92}
93
94func (a *APIKeyInput) Value() string {
95 return a.input.Value()
96}