inbox.go

  1package tui
  2
  3import (
  4	"fmt"
  5	"io"
  6
  7	"github.com/andrinoff/email-cli/fetcher"
  8	"github.com/charmbracelet/bubbles/list"
  9	tea "github.com/charmbracelet/bubbletea"
 10	"github.com/charmbracelet/lipgloss"
 11)
 12
 13var (
 14	itemStyle         = lipgloss.NewStyle().PaddingLeft(4)
 15	selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("205"))
 16	paginationStyle   = list.DefaultStyles().PaginationStyle.PaddingLeft(4)
 17	inboxHelpStyle = list.DefaultStyles().HelpStyle.PaddingLeft(4).PaddingBottom(1)
 18)
 19
 20type item struct {
 21	title, desc string
 22}
 23
 24func (i item) Title() string       { return i.title }
 25func (i item) Description() string { return i.desc }
 26func (i item) FilterValue() string { return i.title + " " + i.desc }
 27
 28type itemDelegate struct{}
 29
 30func (d itemDelegate) Height() int                             { return 1 }
 31func (d itemDelegate) Spacing() int                            { return 0 }
 32func (d itemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
 33func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
 34	i, ok := listItem.(item)
 35	if !ok {
 36		return
 37	}
 38
 39	str := fmt.Sprintf("%d. %s", index+1, i.title)
 40
 41	// **FIX**: Corrected the function literal to accept a variadic string
 42	fn := itemStyle.Render
 43	if index == m.Index() {
 44		fn = func(s ...string) string {
 45			return selectedItemStyle.Render("> " + s[0])
 46		}
 47	}
 48
 49	fmt.Fprint(w, fn(str))
 50}
 51
 52type Inbox struct {
 53	list list.Model
 54}
 55
 56func NewInbox(emails []fetcher.Email) Inbox {
 57	items := make([]list.Item, len(emails))
 58	for i, email := range emails {
 59		items[i] = item{
 60			title: email.Subject,
 61			desc:  email.From,
 62		}
 63	}
 64
 65	l := list.New(items, itemDelegate{}, 20, 14)
 66	l.Title = "Inbox"
 67	l.SetShowStatusBar(false)
 68	l.SetFilteringEnabled(false)
 69	l.Styles.Title = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
 70	l.Styles.PaginationStyle = paginationStyle
 71	l.Styles.HelpStyle = inboxHelpStyle
 72
 73	return Inbox{list: l}
 74}
 75
 76func (m Inbox) Init() tea.Cmd {
 77	return nil
 78}
 79
 80func (m Inbox) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 81	switch msg := msg.(type) {
 82	case tea.KeyMsg:
 83		if msg.String() == "enter" {
 84			i, ok := m.list.SelectedItem().(item)
 85			if ok {
 86				_ = i
 87				return m, func() tea.Msg {
 88					return ViewEmailMsg{Index: m.list.Index()}
 89				}
 90			}
 91		}
 92	case tea.WindowSizeMsg:
 93		m.list.SetWidth(msg.Width)
 94		return m, nil
 95	}
 96
 97	var cmd tea.Cmd
 98	m.list, cmd = m.list.Update(msg)
 99	return m, cmd
100}
101
102func (m Inbox) View() string {
103	return "\n" + m.list.View()
104}