Fearure:
- 增加收件箱功能(有BUG) - 增加已发送|草稿箱|发送历史 本地记录
This commit is contained in:
189
inbox/model.go
Normal file
189
inbox/model.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package inbox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
type EmailItem struct {
|
||||
UID uint32
|
||||
From string
|
||||
FromName string
|
||||
Subject string
|
||||
Date time.Time
|
||||
Preview string
|
||||
Account string
|
||||
AccountID string
|
||||
}
|
||||
|
||||
func (e EmailItem) FilterValue() string {
|
||||
return fmt.Sprintf("%s %s %s %s", e.Account, e.FromName, e.From, e.Subject)
|
||||
}
|
||||
|
||||
func (e EmailItem) Title() string {
|
||||
return fmt.Sprintf("%s · %s - %s", e.Account, e.FromName, e.Subject)
|
||||
}
|
||||
|
||||
func (e EmailItem) Description() string {
|
||||
return e.Preview
|
||||
}
|
||||
|
||||
func formatTimeAgo(d time.Duration) string {
|
||||
if d < time.Minute {
|
||||
return "刚刚"
|
||||
}
|
||||
if d < time.Hour {
|
||||
mins := int(d.Minutes())
|
||||
return fmt.Sprintf("%d分钟前", mins)
|
||||
}
|
||||
if d < 24*time.Hour {
|
||||
hours := int(d.Hours())
|
||||
return fmt.Sprintf("%d小时前", hours)
|
||||
}
|
||||
if d < 7*24*time.Hour {
|
||||
days := int(d.Hours() / 24)
|
||||
return fmt.Sprintf("%d天前", days)
|
||||
}
|
||||
return d.Truncate(24 * time.Hour).String()
|
||||
}
|
||||
|
||||
type InboxModel struct {
|
||||
list list.Model
|
||||
emails []EmailItem
|
||||
loading bool
|
||||
err error
|
||||
selectedEmail *EmailItem
|
||||
}
|
||||
|
||||
func NewInboxModel() *InboxModel {
|
||||
l := list.New(nil, emailDelegate{}, 0, 10)
|
||||
l.Title = "收件箱"
|
||||
l.Styles.Title = inboxTitleStyle
|
||||
l.Styles.NoItems = inboxNoItemsStyle
|
||||
l.SetShowHelp(true)
|
||||
l.SetShowPagination(false)
|
||||
|
||||
return &InboxModel{
|
||||
list: l,
|
||||
emails: []EmailItem{},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *InboxModel) SetEmails(emails []EmailItem) {
|
||||
m.emails = emails
|
||||
items := make([]list.Item, len(emails))
|
||||
for i, e := range emails {
|
||||
items[i] = e
|
||||
}
|
||||
m.list.SetItems(items)
|
||||
m.list.Title = fmt.Sprintf("收件箱 (%d 封新邮件)", len(items))
|
||||
}
|
||||
|
||||
func (m InboxModel) Init() tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *InboxModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
if msg.String() == "ctrl+c" {
|
||||
return m, tea.Quit
|
||||
}
|
||||
case tea.WindowSizeMsg:
|
||||
m.list.SetWidth(msg.Width)
|
||||
}
|
||||
var cmd tea.Cmd
|
||||
m.list, cmd = m.list.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
func (m InboxModel) View() string {
|
||||
if m.loading {
|
||||
return loadingStyle.Render("正在加载邮件...")
|
||||
}
|
||||
if m.err != nil {
|
||||
return errorStyle.Render(fmt.Sprintf("错误: %v", m.err))
|
||||
}
|
||||
return m.list.View()
|
||||
}
|
||||
|
||||
func (m *InboxModel) SetLoading(loading bool) {
|
||||
m.loading = loading
|
||||
}
|
||||
|
||||
func (m *InboxModel) SetError(err error) {
|
||||
m.err = err
|
||||
}
|
||||
|
||||
func (m InboxModel) SelectedEmail() *EmailItem {
|
||||
idx := m.list.Index()
|
||||
if idx >= 0 && idx < len(m.emails) {
|
||||
return &m.emails[idx]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
inboxTitleStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("86")).
|
||||
Bold(true)
|
||||
|
||||
inboxNoItemsStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("241")).
|
||||
Padding(1, 2)
|
||||
|
||||
loadingStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("86")).
|
||||
Padding(1, 2)
|
||||
|
||||
errorStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("196")).
|
||||
Padding(1, 2)
|
||||
)
|
||||
|
||||
type emailDelegate struct{}
|
||||
|
||||
func (d emailDelegate) Height() int { return 1 }
|
||||
func (d emailDelegate) Spacing() int { return 0 }
|
||||
func (d emailDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd {
|
||||
return nil
|
||||
}
|
||||
func (d emailDelegate) Render(w io.Writer, m list.Model, index int, item list.Item) {
|
||||
email, ok := item.(EmailItem)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
isSelected := index == m.Index()
|
||||
|
||||
titleStyle := emailTitleStyle
|
||||
descStyle := emailDescStyle
|
||||
|
||||
if isSelected {
|
||||
titleStyle = emailTitleStyleSelected
|
||||
descStyle = emailDescStyleSelected
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s\n%s", titleStyle.Render(email.Title()), descStyle.Render(email.Description()))
|
||||
}
|
||||
|
||||
var (
|
||||
emailTitleStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("255"))
|
||||
|
||||
emailTitleStyleSelected = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("255")).
|
||||
Background(lipgloss.Color("68"))
|
||||
|
||||
emailDescStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("241"))
|
||||
|
||||
emailDescStyleSelected = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("186")).
|
||||
Background(lipgloss.Color("68"))
|
||||
)
|
||||
Reference in New Issue
Block a user