1package tui
2
3import (
4 "fmt"
5
6 "github.com/andrinoff/email-cli/fetcher"
7 "github.com/andrinoff/email-cli/view"
8 "github.com/charmbracelet/bubbles/viewport"
9 tea "github.com/charmbracelet/bubbletea"
10 "github.com/charmbracelet/lipgloss"
11)
12
13var (
14 emailHeaderStyle = lipgloss.NewStyle().
15 BorderStyle(lipgloss.NormalBorder()).
16 BorderBottom(true).
17 Padding(0, 1)
18)
19
20type EmailView struct {
21 viewport viewport.Model
22 email fetcher.Email
23}
24
25func NewEmailView(email fetcher.Email, width, height int) *EmailView {
26 body, err := view.ProcessBody(email.Body)
27 if err != nil {
28 body = fmt.Sprintf("Error rendering body: %v", err)
29 }
30
31 header := fmt.Sprintf("From: %s\nSubject: %s", email.From, email.Subject)
32 headerHeight := lipgloss.Height(header) + 2 // Account for padding and border
33
34 vp := viewport.New(width, height-headerHeight)
35 vp.SetContent(body)
36
37 return &EmailView{
38 viewport: vp,
39 email: email,
40 }
41}
42
43func (m *EmailView) Init() tea.Cmd {
44 return nil
45}
46
47func (m *EmailView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
48 var cmd tea.Cmd
49 switch msg := msg.(type) {
50 case tea.KeyMsg:
51 switch msg.String() {
52 case "r":
53 return m, func() tea.Msg {
54 return ReplyToEmailMsg{Email: m.email}
55 }
56 }
57 case tea.WindowSizeMsg:
58 header := fmt.Sprintf("From: %s\nSubject: %s", m.email.From, m.email.Subject)
59 headerHeight := lipgloss.Height(header) + 2
60 m.viewport.Width = msg.Width
61 m.viewport.Height = msg.Height - headerHeight
62 }
63 m.viewport, cmd = m.viewport.Update(msg)
64 return m, cmd
65}
66
67func (m *EmailView) View() string {
68 header := fmt.Sprintf("From: %s\nSubject: %s", m.email.From, m.email.Subject)
69 styledHeader := emailHeaderStyle.Width(m.viewport.Width).Render(header)
70 help := helpStyle.Render("r: reply • esc: back to inbox")
71 return fmt.Sprintf("%s\n%s\n%s", styledHeader, m.viewport.View(), help)
72}