mirror of
https://github.com/Slug-Boi/cocommit.git
synced 2026-05-13 12:45:47 +00:00
feat: add gh add tui component
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user