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}