package plays import ( "fmt" "net/http" "strings" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" ) type Login struct { *Base focusIndex int inputs []textinput.Model } func NewLogin(base *Base) *Login { m := Login{ Base: base, focusIndex: 0, inputs: make([]textinput.Model, 2), } for i := range m.inputs { t := textinput.New() t.CharLimit = 32 t.Width = 20 switch i { case 0: t.Placeholder = "Username" t.Focus() case 1: t.Placeholder = "Password" t.EchoMode = textinput.EchoPassword t.EchoCharacter = '•' } m.inputs[i] = t } return &m } func (m *Login) Init() tea.Cmd { return tea.Batch(tea.ClearScreen, textinput.Blink) } func (m *Login) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if _, cmd := m.Base.Update(msg); cmd != nil { return m, cmd } switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { case "tab", "shift+tab", "enter", "up", "down": s := msg.String() if s == "enter" && m.focusIndex == len(m.inputs)-1 { return m, tea.Quit } if s == "up" || s == "shift+tab" { m.focusIndex-- } else { m.focusIndex++ } if m.focusIndex >= len(m.inputs) { m.focusIndex = 0 } else if m.focusIndex < 0 { m.focusIndex = len(m.inputs) - 1 } cmds := make([]tea.Cmd, len(m.inputs)) for i := 0; i < len(m.inputs); i++ { if i == m.focusIndex { cmds[i] = m.inputs[i].Focus() continue } m.inputs[i].Blur() } return m, tea.Batch(cmds...) } } cmd := m.updateInputs(msg) return m, cmd } func (m *Login) updateInputs(msg tea.Msg) tea.Cmd { cmds := make([]tea.Cmd, len(m.inputs)) for i := range m.inputs { m.inputs[i], cmds[i] = m.inputs[i].Update(msg) } return tea.Batch(cmds...) } func (m *Login) View() string { var b strings.Builder fmt.Fprintf(&b, "User login:\n") for i := range m.inputs { b.WriteString(m.inputs[i].View()) if i < len(m.inputs) { b.WriteRune('\n') } } return b.String() } func (m *Login) Next(queue *[]*tea.Program) error { username := m.inputs[0].Value() password := m.inputs[1].Value() resp, _ := m.Base.client.R(). SetBasicAuth(username, password). Get("/auth/login") if resp.StatusCode() == http.StatusOK { m.Base.client. SetBasicAuth(username, password) m.Base.username = username *queue = append(*queue, tea.NewProgram(NewLobby(m.Base))) } else { *queue = append(*queue, tea.NewProgram(NewRedirect("Login failed"))) *queue = append(*queue, tea.NewProgram(NewLanding(m.Base))) } return nil }