1package claude
2
3import (
4 tea "charm.land/bubbletea/v2"
5 "charm.land/lipgloss/v2"
6 "github.com/charmbracelet/crush/internal/tui/styles"
7 "github.com/charmbracelet/crush/internal/tui/util"
8)
9
10type AuthMethod int
11
12const (
13 AuthMethodAPIKey AuthMethod = iota
14 AuthMethodOAuth2
15)
16
17type AuthMethodChooser struct {
18 State AuthMethod
19 width int
20 isOnboarding bool
21}
22
23func NewAuthMethodChooser() *AuthMethodChooser {
24 return &AuthMethodChooser{
25 State: AuthMethodOAuth2,
26 }
27}
28
29func (a *AuthMethodChooser) Init() tea.Cmd {
30 return nil
31}
32
33func (a *AuthMethodChooser) Update(msg tea.Msg) (util.Model, tea.Cmd) {
34 return a, nil
35}
36
37func (a *AuthMethodChooser) View() string {
38 t := styles.CurrentTheme()
39
40 white := lipgloss.NewStyle().Foreground(t.White)
41 primary := lipgloss.NewStyle().Foreground(t.Primary)
42 success := lipgloss.NewStyle().Foreground(t.Success)
43
44 titleStyle := white
45 if a.isOnboarding {
46 titleStyle = primary
47 }
48
49 question := lipgloss.
50 NewStyle().
51 Margin(0, 1).
52 Render(titleStyle.Render("How would you like to authenticate with ") + success.Render("Anthropic") + titleStyle.Render("?"))
53
54 squareWidth := (a.width - 2) / 2
55 squareHeight := squareWidth / 3
56 if isOdd(squareHeight) {
57 squareHeight++
58 }
59
60 square := lipgloss.NewStyle().
61 Width(squareWidth).
62 Height(squareHeight).
63 Margin(0, 0).
64 Border(lipgloss.RoundedBorder())
65
66 squareText := lipgloss.NewStyle().
67 Width(squareWidth - 2).
68 Height(squareHeight).
69 Align(lipgloss.Center).
70 AlignVertical(lipgloss.Center)
71
72 oauthBorder := t.AuthBorderSelected
73 oauthText := t.AuthTextSelected
74 apiKeyBorder := t.AuthBorderUnselected
75 apiKeyText := t.AuthTextUnselected
76
77 if a.State == AuthMethodAPIKey {
78 oauthBorder, apiKeyBorder = apiKeyBorder, oauthBorder
79 oauthText, apiKeyText = apiKeyText, oauthText
80 }
81
82 return lipgloss.JoinVertical(
83 lipgloss.Left,
84 question,
85 "",
86 lipgloss.JoinHorizontal(
87 lipgloss.Center,
88 square.MarginLeft(1).
89 Inherit(oauthBorder).Render(squareText.Inherit(oauthText).Render("Claude Account\nwith Subscription")),
90 square.MarginRight(1).
91 Inherit(apiKeyBorder).Render(squareText.Inherit(apiKeyText).Render("API Key")),
92 ),
93 )
94}
95
96func (a *AuthMethodChooser) SetDefaults() {
97 a.State = AuthMethodOAuth2
98}
99
100func (a *AuthMethodChooser) SetWidth(w int) {
101 a.width = w
102}
103
104func (a *AuthMethodChooser) ToggleChoice() {
105 switch a.State {
106 case AuthMethodAPIKey:
107 a.State = AuthMethodOAuth2
108 case AuthMethodOAuth2:
109 a.State = AuthMethodAPIKey
110 }
111}
112
113func isOdd(n int) bool {
114 return n%2 != 0
115}