1package tui
2
3import (
4 "strings"
5
6 "charm.land/bubbles/v2/textinput"
7 tea "charm.land/bubbletea/v2"
8 "charm.land/lipgloss/v2"
9)
10
11// MailingListEditor displays the screen to add a new mailing list.
12type MailingListEditor struct {
13 nameInput textinput.Model
14 addrInput textinput.Model
15 focus int // 0 = name, 1 = addresses
16 width int
17 height int
18}
19
20// NewMailingListEditor creates a new mailing list editor model.
21func NewMailingListEditor() *MailingListEditor {
22 name := textinput.New()
23 name.Placeholder = "e.g., Team"
24 name.Focus()
25
26 addr := textinput.New()
27 addr.Placeholder = "e.g., alice@example.com, bob@example.com"
28
29 return &MailingListEditor{
30 nameInput: name,
31 addrInput: addr,
32 focus: 0,
33 }
34}
35
36// Init initializes the mailing list editor model.
37func (m *MailingListEditor) Init() tea.Cmd {
38 return textinput.Blink
39}
40
41// Update handles messages for the mailing list editor model.
42func (m *MailingListEditor) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
43 var cmd tea.Cmd
44
45 switch msg := msg.(type) {
46 case tea.WindowSizeMsg:
47 m.width = msg.Width
48 m.height = msg.Height
49 m.nameInput.SetWidth(msg.Width - 4)
50 m.addrInput.SetWidth(msg.Width - 4)
51 return m, nil
52
53 case tea.KeyPressMsg:
54 switch msg.String() {
55 case "ctrl+c":
56 return m, tea.Quit
57 case "esc":
58 return m, func() tea.Msg { return GoToSettingsMsg{} }
59 case "tab", "shift+tab", "up", "down":
60 if m.focus == 0 {
61 m.focus = 1
62 m.nameInput.Blur()
63 m.addrInput.Focus()
64 } else {
65 m.focus = 0
66 m.addrInput.Blur()
67 m.nameInput.Focus()
68 }
69 return m, nil
70 case "enter":
71 if m.focus == 0 {
72 m.focus = 1
73 m.nameInput.Blur()
74 m.addrInput.Focus()
75 return m, nil
76 } else {
77 // Submit on second field
78 name := strings.TrimSpace(m.nameInput.Value())
79 addrs := strings.TrimSpace(m.addrInput.Value())
80 if name != "" && addrs != "" {
81 return m, func() tea.Msg {
82 return SaveMailingListMsg{
83 Name: name,
84 Addresses: addrs,
85 }
86 }
87 }
88 }
89 }
90 }
91
92 if m.focus == 0 {
93 m.nameInput, cmd = m.nameInput.Update(msg)
94 } else {
95 m.addrInput, cmd = m.addrInput.Update(msg)
96 }
97
98 return m, cmd
99}
100
101// View renders the mailing list editor screen.
102func (m *MailingListEditor) View() tea.View {
103 title := titleStyle.Render("Add Mailing List")
104
105 var nameView, addrView string
106 if m.focus == 0 {
107 nameView = focusedStyle.Render("Name:") + "\n" + m.nameInput.View()
108 addrView = blurredStyle.Render("Addresses (comma-separated):") + "\n" + m.addrInput.View()
109 } else {
110 nameView = blurredStyle.Render("Name:") + "\n" + m.nameInput.View()
111 addrView = focusedStyle.Render("Addresses (comma-separated):") + "\n" + m.addrInput.View()
112 }
113
114 return tea.NewView(lipgloss.JoinVertical(lipgloss.Left,
115 title,
116 "",
117 nameView,
118 "",
119 addrView,
120 "",
121 helpStyle.Render("tab/↑/↓: switch fields • enter: submit • esc: back"),
122 ))
123}