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	fn := itemStyle.Render
 42	if index == m.Index() {
 43		fn = func(s ...string) string {
 44			return selectedItemStyle.Render("> " + s[0])
 45		}
 46	}
 47
 48	fmt.Fprint(w, fn(str))
 49}
 50
 51type Inbox struct {
 52	list list.Model
 53}
 54
 55func NewInbox(emails []fetcher.Email) Inbox {
 56	items := make([]list.Item, len(emails))
 57	for i, email := range emails {
 58		items[i] = item{
 59			title: email.Subject,
 60			desc:  email.From,
 61		}
 62	}
 63
 64	l := list.New(items, itemDelegate{}, 20, 14)
 65	l.Title = "Inbox"
 66	l.SetShowStatusBar(false)
 67	l.SetFilteringEnabled(true)
 68	l.Styles.Title = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
 69	l.Styles.PaginationStyle = paginationStyle
 70	l.Styles.HelpStyle = inboxHelpStyle
 71
 72	return Inbox{list: l}
 73}
 74
 75func (m Inbox) Init() tea.Cmd {
 76	return nil
 77}
 78
 79func (m Inbox) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 80	switch msg := msg.(type) {
 81	case tea.KeyMsg:
 82		if msg.String() == "enter" {
 83			i, ok := m.list.SelectedItem().(item)
 84			if ok {
 85				_ = i
 86				return m, func() tea.Msg {
 87					return ViewEmailMsg{Index: m.list.Index()}
 88				}
 89			}
 90		}
 91	case tea.WindowSizeMsg:
 92		m.list.SetWidth(msg.Width)
 93		return m, nil
 94	}
 95
 96	var cmd tea.Cmd
 97	m.list, cmd = m.list.Update(msg)
 98	return m, cmd
 99}
100
101func (m Inbox) View() string {
102	return "\n" + m.list.View()
103}