Files
cocommit/src/cmd/tui/tui_github.go
T
2025-04-10 22:31:16 +02:00

223 lines
5.0 KiB
Go

package tui
import (
"fmt"
"strings"
"github.com/Slug-Boi/cocommit/src/cmd/utils"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
// Styles
var (
errorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("9"))
toggleStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("99"))
activeToggleStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
)
type GitHubUserModel struct {
inputs []textinput.Model
focusIndex int
submitted bool
showError bool
errorMsg string
tempAuthShow bool
tempAuth bool
}
func NewGitHubUserForm(old_m *model) GitHubUserModel {
parent_m = old_m
m := GitHubUserModel{
inputs: make([]textinput.Model, 2),
tempAuthShow: func() bool {
return old_m != nil
}(),
}
// GitHub Username (required)
username := textinput.New()
username.Placeholder = "GitHub username *"
username.PromptStyle = focusedStyle
username.TextStyle = focusedStyle
username.Focus()
username.CharLimit = 39 // GitHub username max length
m.inputs[0] = username
// Email (optional)
email := textinput.New()
email.Placeholder = "Email"
email.PromptStyle = blurredStyle
email.TextStyle = blurredStyle
m.inputs[1] = email
return m
}
func (m GitHubUserModel) Init() tea.Cmd {
return textinput.Blink
}
func (m GitHubUserModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "esc":
return m, tea.Quit
case "ctrl+t": // Toggle temp mode
if m.tempAuthShow {
m.tempAuth = !m.tempAuth
return m, nil
}
case "tab", "shift+tab", "enter", "up", "down":
s := msg.String()
// Submit on enter when button is focused
if s == "enter" && m.focusIndex == len(m.inputs)+1 && m.tempAuthShow || s == "enter" && m.focusIndex == len(m.inputs) && !m.tempAuthShow {
if m.inputs[0].Value() == "" {
m.showError = true
m.errorMsg = "GitHub username is required"
return m, nil
}
m.submitted = true
user := utils.FetchGithubProfile(m.inputs[0].Value())
if m.inputs[1].Value() != "" {
user.Email = m.inputs[1].Value()
}
if m.tempAuth {
return createGHTempAuthorModel(parent_m,user), nil
}
return createGHAuthorModel(parent_m,user), nil
} else if s == "enter" && m.focusIndex == len(m.inputs) && m.tempAuthShow {
//toggle temp mode
m.tempAuth = !m.tempAuth
return m, nil
}
// Cycle through inputs
if s == "up" || s == "shift+tab" {
m.focusIndex--
} else {
m.focusIndex++
}
inpNum := len(m.inputs)
if m.tempAuthShow {
inpNum++
}
if m.focusIndex > inpNum {
m.focusIndex = 0
} else if m.focusIndex < 0 {
m.focusIndex = inpNum
}
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()
m.inputs[i].PromptStyle = focusedStyle
m.inputs[i].TextStyle = focusedStyle
continue
}
m.inputs[i].Blur()
m.inputs[i].PromptStyle = blurredStyle
if m.inputs[i].Value() == "" {
m.inputs[i].TextStyle = blurredStyle
} else {
m.inputs[i].TextStyle = noStyle
}
}
m.showError = false // Clear error when navigating
return m, tea.Batch(cmds...)
}
}
// Handle text input
cmd := m.updateInputs(msg)
return m, cmd
}
func (m *GitHubUserModel) 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 GitHubUserModel) View() string {
if m.submitted {
return ""
}
var b strings.Builder
// Title
b.WriteString("Enter GitHub User Details\n\n")
// Input fields
for i := range m.inputs {
b.WriteString(m.inputs[i].View())
if i < len(m.inputs)-1 {
b.WriteRune('\n')
}
}
if m.tempAuthShow {
toggleText := "[ ]"
if m.tempAuth {
toggleText = "[X]"
}
toggleBtn := fmt.Sprintf("[ TempAuthor ] %s ", toggleText)
if m.focusIndex == len(m.inputs) { // When toggle is focused
b.WriteString("\n" + focusedStyle.Render(toggleBtn))
} else {
b.WriteString("\n" + blurredStyle.Render(toggleBtn))
}
}
// Submit button
button := blurredButton
if m.focusIndex == len(m.inputs)+1 && m.tempAuthShow || m.focusIndex == len(m.inputs) && !m.tempAuthShow {
button = focusedButton
}
b.WriteString("\n\n" + button + "\n")
// Error message
if m.showError {
b.WriteString("\n" + errorStyle.Render(m.errorMsg) + "\n")
}
// Help text
b.WriteString("\n" + blurredStyle.Render("tab to navigate • enter to submit"))
return b.String()
}
// RunForm starts the TUI and returns the entered values
func RunForm() (string, string, error) {
model := NewGitHubUserForm(nil)
p := tea.NewProgram(model)
m, err := p.Run()
if err != nil {
return "", "", err
}
if fm, ok := m.(GitHubUserModel); ok {
if fm.submitted {
return fm.inputs[0].Value(), fm.inputs[1].Value(), nil
}
}
return "", "", nil
}