choice.go

 1package tui
 2
 3import (
 4	"fmt"
 5	"strings"
 6
 7	tea "github.com/charmbracelet/bubbletea"
 8	"github.com/charmbracelet/lipgloss"
 9)
10
11// Styles defined locally to avoid import issues.
12var (
13	docStyle          = lipgloss.NewStyle().Margin(1, 2)
14	titleStyle        = lipgloss.NewStyle().Foreground(lipgloss.Color("#FFFDF5")).Background(lipgloss.Color("#25A065")).Padding(0, 1)
15	listHeader        = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).PaddingBottom(1)
16	itemStyle         = lipgloss.NewStyle().PaddingLeft(2)
17	selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("205"))
18)
19
20type Choice struct {
21	cursor         int
22	choices        []string
23	hasCachedDraft bool
24}
25
26func NewChoice(hasCachedDraft bool) Choice {
27	choices := []string{"View Inbox", "Compose Email", "Settings"}
28	if hasCachedDraft {
29		choices = append(choices, "Restore Draft")
30	}
31	return Choice{
32		choices:        choices,
33		hasCachedDraft: hasCachedDraft,
34	}
35}
36
37func (m Choice) Init() tea.Cmd {
38	return nil
39}
40
41func (m Choice) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
42	switch msg := msg.(type) {
43	case tea.KeyMsg:
44		switch msg.String() {
45		case "up", "k":
46			if m.cursor > 0 {
47				m.cursor--
48			}
49		case "down", "j":
50			if m.cursor < len(m.choices)-1 {
51				m.cursor++
52			}
53		case "enter":
54			selectedChoice := m.choices[m.cursor]
55			switch selectedChoice {
56			case "View Inbox":
57				return m, func() tea.Msg { return GoToInboxMsg{} }
58			case "Compose Email":
59				return m, func() tea.Msg { return GoToSendMsg{} }
60			case "Settings":
61				return m, func() tea.Msg { return GoToSettingsMsg{} }
62			case "Restore Draft":
63				return m, func() tea.Msg { return RestoreDraftMsg{} }
64			}
65		}
66	}
67	return m, nil
68}
69
70func (m Choice) View() string {
71	var b strings.Builder
72
73	b.WriteString(titleStyle.Render("Matcha") + "\n\n")
74	b.WriteString(listHeader.Render("What would you like to do?"))
75	b.WriteString("\n\n")
76
77	for i, choice := range m.choices {
78		if m.cursor == i {
79			b.WriteString(selectedItemStyle.Render(fmt.Sprintf("> %s", choice)))
80		} else {
81			b.WriteString(itemStyle.Render(fmt.Sprintf("  %s", choice)))
82		}
83		b.WriteString("\n")
84	}
85
86	b.WriteString("\n\n")
87	b.WriteString(helpStyle.Render("Use ↑/↓ to navigate, enter to select, and ctrl+c to quit."))
88
89	return docStyle.Render(b.String())
90}