190 lines
4.1 KiB
Go
190 lines
4.1 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/charmbracelet/bubbles/textinput"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/lipgloss"
|
|
)
|
|
|
|
type inputScreenState int
|
|
|
|
const (
|
|
urlInput inputScreenState = iota
|
|
usernameInput
|
|
tokenInput
|
|
connNameInput
|
|
)
|
|
|
|
type InputScreen struct {
|
|
urlField textinput.Model
|
|
usernameField textinput.Model
|
|
tokenField textinput.Model
|
|
connNameField textinput.Model
|
|
focusedField inputScreenState
|
|
err error
|
|
url string
|
|
username string
|
|
token string
|
|
connName string
|
|
done bool
|
|
}
|
|
|
|
func NewInputScreen() *InputScreen {
|
|
urlField := textinput.New()
|
|
urlField.Placeholder = "https://gitea.example.com"
|
|
urlField.Focus()
|
|
|
|
usernameField := textinput.New()
|
|
usernameField.Placeholder = "your_username"
|
|
|
|
tokenField := textinput.New()
|
|
tokenField.Placeholder = "your_access_token"
|
|
tokenField.EchoMode = textinput.EchoPassword
|
|
|
|
connNameField := textinput.New()
|
|
connNameField.Placeholder = "(optional) Connection name"
|
|
|
|
return &InputScreen{
|
|
urlField: urlField,
|
|
usernameField: usernameField,
|
|
tokenField: tokenField,
|
|
connNameField: connNameField,
|
|
focusedField: urlInput,
|
|
}
|
|
}
|
|
|
|
func (is *InputScreen) Init() tea.Cmd {
|
|
return textinput.Blink
|
|
}
|
|
|
|
func (is *InputScreen) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
switch msg.Type {
|
|
case tea.KeyCtrlC:
|
|
return is, tea.Quit
|
|
case tea.KeyEnter:
|
|
switch is.focusedField {
|
|
case urlInput:
|
|
is.url = is.urlField.Value()
|
|
is.focusedField = usernameInput
|
|
is.usernameField.Focus()
|
|
return is, nil
|
|
case usernameInput:
|
|
is.username = is.usernameField.Value()
|
|
is.focusedField = tokenInput
|
|
is.tokenField.Focus()
|
|
return is, nil
|
|
case tokenInput:
|
|
is.token = is.tokenField.Value()
|
|
is.focusedField = connNameInput
|
|
is.connNameField.Focus()
|
|
return is, nil
|
|
case connNameInput:
|
|
is.connName = is.connNameField.Value()
|
|
is.done = true
|
|
return is, nil
|
|
}
|
|
case tea.KeyTab, tea.KeyShiftTab:
|
|
switch is.focusedField {
|
|
case urlInput:
|
|
is.url = is.urlField.Value()
|
|
case usernameInput:
|
|
is.username = is.usernameField.Value()
|
|
case tokenInput:
|
|
is.token = is.tokenField.Value()
|
|
case connNameInput:
|
|
is.connName = is.connNameField.Value()
|
|
}
|
|
|
|
if msg.Type == tea.KeyTab {
|
|
is.focusedField = (is.focusedField + 1) % 4
|
|
} else {
|
|
is.focusedField = (is.focusedField - 1 + 4) % 4
|
|
}
|
|
|
|
is.urlField.Blur()
|
|
is.usernameField.Blur()
|
|
is.tokenField.Blur()
|
|
is.connNameField.Blur()
|
|
|
|
switch is.focusedField {
|
|
case urlInput:
|
|
is.urlField.Focus()
|
|
case usernameInput:
|
|
is.usernameField.Focus()
|
|
case tokenInput:
|
|
is.tokenField.Focus()
|
|
case connNameInput:
|
|
is.connNameField.Focus()
|
|
}
|
|
return is, nil
|
|
}
|
|
|
|
case errMsg:
|
|
is.err = msg
|
|
return is, nil
|
|
}
|
|
|
|
var cmd tea.Cmd
|
|
switch is.focusedField {
|
|
case urlInput:
|
|
is.urlField, cmd = is.urlField.Update(msg)
|
|
case usernameInput:
|
|
is.usernameField, cmd = is.usernameField.Update(msg)
|
|
case tokenInput:
|
|
is.tokenField, cmd = is.tokenField.Update(msg)
|
|
case connNameInput:
|
|
is.connNameField, cmd = is.connNameField.Update(msg)
|
|
}
|
|
|
|
return is, cmd
|
|
}
|
|
|
|
func (is *InputScreen) View() string {
|
|
var s string
|
|
|
|
s += lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("212")).
|
|
Bold(true).
|
|
Render("Gitea Wrapped") + "\n\n"
|
|
|
|
s += "Enter your Gitea credentials:\n\n"
|
|
|
|
s += "Gitea URL\n"
|
|
s += is.urlField.View() + "\n\n"
|
|
|
|
s += "Username\n"
|
|
s += is.usernameField.View() + "\n\n"
|
|
|
|
s += "Access Token\n"
|
|
s += is.tokenField.View() + "\n\n"
|
|
|
|
s += "Connection Name (optional - to save for later)\n"
|
|
s += is.connNameField.View() + "\n\n"
|
|
|
|
if is.err != nil {
|
|
s += lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("1")).
|
|
Render(fmt.Sprintf("Error: %v", is.err)) + "\n"
|
|
}
|
|
|
|
s += lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("8")).
|
|
Render("(Tab to navigate, Enter to continue, Ctrl+C to quit)") + "\n"
|
|
|
|
return s
|
|
}
|
|
|
|
func (is *InputScreen) IsDone() bool {
|
|
return is.done
|
|
}
|
|
|
|
func (is *InputScreen) GetCredentials() (url, username, token, connName string) {
|
|
return is.url, is.username, is.token, is.connName
|
|
}
|
|
|
|
type errMsg error
|