choice.go

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