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}