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