method.go

  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}