diff --git a/src/cmd/tui/tui_author.go b/src/cmd/tui/tui_author.go index 7ec54d3..ff84351 100644 --- a/src/cmd/tui/tui_author.go +++ b/src/cmd/tui/tui_author.go @@ -4,7 +4,6 @@ package tui // from the Bubbles component library. import ( - "encoding/json" "fmt" "os" "strings" @@ -14,7 +13,6 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - //"github.com/inancgumus/screen" ) var ( @@ -36,6 +34,63 @@ type model_ca struct { inputs []textinput.Model quitting bool exclude bool + errorModel *errorModel +} + +// Error popup model +type errorModel struct { + missing []string + visible bool +} + +func errorGetMissingFields(m model_ca) { + inpLen := len(m.inputs) + if !tempAuthorToggle { + inpLen -= 1 + } + + if len(m.inputs) > 0 { + for i := 0; i < inpLen; i++ { + if m.inputs[i].Value() == "" { + m.errorModel.missing = append(m.errorModel.missing, "- "+strings.Split(m.inputs[i].Placeholder,"(")[0]) + } + } + } else { + m.errorModel.missing = append(m.errorModel.missing, "GIGA ERROR NO INPUTS") + } + +} + +func (e errorModel) View() string { + var sb strings.Builder + sb.WriteString("Error") + if len(e.missing) > 0 { + sb.WriteString("\nMissing fields: \n") + sb.WriteString(strings.Join(e.missing, "\n")) + } + + // Create centered content + content := lipgloss.JoinVertical( + lipgloss.Left, // Changed from Center to Left for better alignment + sb.String(), + "\n\n[enter/esc]", + + ) + + // Create the error box + errorBox := lipgloss.NewStyle(). + Border(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("9")). + Padding(1, 2). + Width(40). + Foreground(lipgloss.Color("9")). + Background(lipgloss.Color("0")). + Align(lipgloss.Center). + Render(content) + + return lipgloss.NewStyle(). + Padding(1, 0). + Render(errorBox) } var parent_m *model @@ -45,13 +100,13 @@ func createAuthorModel(old_m *model) model_ca { m := model_ca{ inputs: make([]textinput.Model, 5), + errorModel: intitialErrorModel(), } var t textinput.Model for i := range m.inputs { t = textinput.New() t.Cursor.Style = cursorStyle - //t.CharLimit = 32 switch i { case 0: @@ -75,11 +130,71 @@ func createAuthorModel(old_m *model) model_ca { return m } +func intitialErrorModel() *errorModel { + return &errorModel{ + missing: []string{}, + visible: false, + } +} + +func createGHAuthorModel(old_m *model, user utils.User) model_ca { + parent_m = old_m + + m := model_ca{ + inputs: make([]textinput.Model, 5), + errorModel: intitialErrorModel(), + } + + var t textinput.Model + for i := range m.inputs { + t = textinput.New() + t.Cursor.Style = cursorStyle + + switch i { + case 0: + t.Placeholder = "Shortname (e.g. jo)" + t.SetValue(user.Shortname) + t.Focus() + t.PromptStyle = focusedStyle + t.TextStyle = focusedStyle + case 1: + t.Placeholder = "Long name (e.g. JohnDoe)" + t.SetValue(user.Longname) + case 2: + t.Placeholder = "Username (e.g. JohnDoe-gh)" + t.SetValue(user.Username) + case 3: + t.Placeholder = "Email (e.g. JohnDoe@domain.do" + t.SetValue("") + case 4: + t.Placeholder = "Group tags (e.g. gr1|gr2)" + t.SetValue(strings.Join(user.Groups, "|")) + } + + m.inputs[i] = t + } + + return m +} + +func EntryGHAuthorModel(user utils.User) { + model := createGHAuthorModel(&model{}, user) + + print(model.inputs[0].Value()) + + if _, err := tea.NewProgram(model).Run(); err != nil { + fmt.Println("Error running program:", err) + os.Exit(1) + } +} + + func tempAuthorModel(old_m *model) model_ca { parent_m = old_m m := model_ca{ inputs: make([]textinput.Model, 2), + errorModel: intitialErrorModel(), } var t textinput.Model @@ -110,13 +225,35 @@ func (m model_ca) Init() tea.Cmd { return textinput.Blink } +func updateErrorPopup(m model_ca, msg tea.Msg) (tea.Model, tea.Cmd) { + + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "enter", "esc", "ctrl+c": + m.errorModel.missing = []string{} + m.errorModel.visible = false + return m, nil + } + } + + return m, nil +} + func (m model_ca) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + if m.errorModel.visible { + return updateErrorPopup(m, msg) + } + switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { case "ctrl+c", "esc": m.inputs = nil - return nil, nil + if parent_m.keys != nil { + return nil, nil + } + return m, tea.Quit // Set focus to next input case "tab", "shift+tab", "enter", "up", "down": @@ -126,8 +263,17 @@ func (m model_ca) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if !tempAuthorToggle { if s == "enter" && m.focusIndex == len(m.inputs)+1 { m.quitting = true - m.AddAuthor() - return model{list: parent_m.list}, tea.ClearScreen + m.errorModel.visible = m.AddAuthor() + if m.errorModel.visible { + m.quitting = false + return m, nil + } + if parent_m.keys != nil { + return model{list: parent_m.list}, tea.ClearScreen + } else { + m.quitting = true + return m, tea.Quit + } } else if s == "enter" && m.focusIndex == len(m.inputs) { // toggle exclude m.exclude = !m.exclude @@ -136,8 +282,17 @@ func (m model_ca) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } else { if s == "enter" && m.focusIndex == len(m.inputs) { m.quitting = true - m.TempAddAuthor() - return model{list: parent_m.list}, tea.ClearScreen + m.errorModel.visible = m.TempAddAuthor() + if m.errorModel.visible { + m.quitting = false + return m, nil + } + if parent_m.keys != nil { + return model{list: parent_m.list}, tea.ClearScreen + } else { + m.quitting = true + return m, tea.Quit + } } } @@ -192,6 +347,13 @@ func (m *model_ca) updateInputs(msg tea.Msg) tea.Cmd { } func (m model_ca) View() string { + if m.errorModel.visible { + if len(m.errorModel.missing) == 0 { + errorGetMissingFields(m) + } + return m.errorModel.View() + } + if m.quitting { return "" } @@ -237,19 +399,13 @@ func (m model_ca) View() string { return b.String() } -func (m *model_ca) AddAuthor() { +func (m *model_ca) AddAuthor() bool { if len(m.inputs) > 0 && m.inputs[0].Value() != "" && m.inputs[1].Value() != "" && m.inputs[2].Value() != "" && m.inputs[3].Value() != "" { - author_file := utils.Find_authorfile() - f, err := os.OpenFile(author_file, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) - if err != nil { - panic(err) - } - - defer f.Close() + var groups []string if m.inputs[4].Value() == "" { groups = []string{} @@ -257,9 +413,6 @@ func (m *model_ca) AddAuthor() { groups = strings.Split(m.inputs[4].Value(), "|") } - - - // create and add the user to the users map usr := utils.User{ Shortname: m.inputs[0].Value(), @@ -270,42 +423,29 @@ func (m *model_ca) AddAuthor() { Groups: groups, } - utils.Users[m.inputs[0].Value()] = usr - utils.Users[m.inputs[1].Value()] = usr - - - utils.Authors.Authors[m.inputs[1].Value()] = usr - - data, err := json.MarshalIndent(utils.Authors, "", " ") - if err != nil { - panic(fmt.Sprintf("Error marshalling json: %v", err)) - - } - - // write the data to the file - f.Truncate(0) - f.Seek(0, 0) - f.Write(data) - f.Close() - - // redefine the users map for the tui to use - utils.Define_users(utils.Find_authorfile()) + utils.CreateAuthor(usr) author := m.inputs[0].Value() - item_str := utils.Users[author].Username + " - " + utils.Users[author].Email - dupProtect[item_str] = author - parent_m.list.InsertItem(len(parent_m.list.Items())+1, item(item_str)) - - } + if parent_m.keys != nil { + item_str := utils.Users[author].Username + " - " + utils.Users[author].Email + dupProtect[item_str] = author + parent_m.list.InsertItem(len(parent_m.list.Items())+1, item(item_str)) + } + return false + } + return true } -func (m *model_ca) TempAddAuthor() { +func (m *model_ca) TempAddAuthor() bool { if len(m.inputs) > 1 && m.inputs[0].Value() != "" && m.inputs[1].Value() != "" { item_str := m.inputs[0].Value() + " - " + m.inputs[1].Value() dupProtect[item_str] = m.inputs[0].Value() + ":" + m.inputs[1].Value() i := item(item_str) parent_m.list.InsertItem(len(parent_m.list.Items())+1, item(item_str)) selectToggle(i) + + return false } + return true }