feat: 收件箱功能新增按回车查看详情面板
- 添加邮件详情面板显示(主题、发件人、收件人、抄送、账户、时间、正文) - 优化邮件列表卡片样式,增加选中高亮效果 - 窗口宽度 >= 80 时启用双面板布局,左侧列表右侧详情 - 简化依赖包,从 charm.land 使用统一导入路径 - 删除未使用的 golangci/goreleaser 配置文件
This commit is contained in:
98
model.go
98
model.go
@@ -5,14 +5,14 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/bubbles/filepicker"
|
||||
"github.com/charmbracelet/bubbles/help"
|
||||
"github.com/charmbracelet/bubbles/key"
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
"github.com/charmbracelet/bubbles/textarea"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"charm.land/bubbles/v2/filepicker"
|
||||
"charm.land/bubbles/v2/help"
|
||||
"charm.land/bubbles/v2/key"
|
||||
"charm.land/bubbles/v2/list"
|
||||
"charm.land/bubbles/v2/spinner"
|
||||
"charm.land/bubbles/v2/textarea"
|
||||
"charm.land/bubbles/v2/textinput"
|
||||
tea "charm.land/bubbletea/v2"
|
||||
"github.com/charmbracelet/x/exp/ordered"
|
||||
"github.com/resendlabs/resend-go"
|
||||
)
|
||||
@@ -89,68 +89,32 @@ func NewModel(defaults resend.SendEmailRequest, deliveryMethod DeliveryMethod) M
|
||||
from := textinput.New()
|
||||
from.Prompt = "From "
|
||||
from.Placeholder = "me@example.com"
|
||||
from.PromptStyle = labelStyle.Copy()
|
||||
from.PromptStyle = labelStyle
|
||||
from.TextStyle = textStyle
|
||||
from.Cursor.Style = cursorStyle
|
||||
from.PlaceholderStyle = placeholderStyle
|
||||
from.SetValue(defaults.From)
|
||||
|
||||
to := textinput.New()
|
||||
to.Prompt = "To "
|
||||
to.PromptStyle = labelStyle.Copy()
|
||||
to.Cursor.Style = cursorStyle
|
||||
to.PlaceholderStyle = placeholderStyle
|
||||
to.TextStyle = textStyle
|
||||
to.Placeholder = "you@example.com"
|
||||
to.SetValue(strings.Join(defaults.To, ToSeparator))
|
||||
|
||||
cc := textinput.New()
|
||||
cc.Prompt = "Cc "
|
||||
cc.PromptStyle = labelStyle.Copy()
|
||||
cc.Cursor.Style = cursorStyle
|
||||
cc.PlaceholderStyle = placeholderStyle
|
||||
cc.TextStyle = textStyle
|
||||
cc.Placeholder = "cc@example.com"
|
||||
cc.SetValue(strings.Join(defaults.Cc, ToSeparator))
|
||||
|
||||
bcc := textinput.New()
|
||||
bcc.Prompt = "Bcc "
|
||||
bcc.PromptStyle = labelStyle.Copy()
|
||||
bcc.Cursor.Style = cursorStyle
|
||||
bcc.PlaceholderStyle = placeholderStyle
|
||||
bcc.TextStyle = textStyle
|
||||
bcc.Placeholder = "bcc@example.com"
|
||||
bcc.SetValue(strings.Join(defaults.Bcc, ToSeparator))
|
||||
|
||||
subject := textinput.New()
|
||||
subject.Prompt = "Subject "
|
||||
subject.PromptStyle = labelStyle.Copy()
|
||||
subject.Cursor.Style = cursorStyle
|
||||
subject.PlaceholderStyle = placeholderStyle
|
||||
subject.TextStyle = textStyle
|
||||
subject.Placeholder = "Hello!"
|
||||
subject.SetValue(defaults.Subject)
|
||||
|
||||
body := textarea.New()
|
||||
body.Placeholder = "# Email"
|
||||
body.ShowLineNumbers = false
|
||||
body.FocusedStyle.CursorLine = activeTextStyle
|
||||
body.FocusedStyle.Prompt = activeLabelStyle
|
||||
body.FocusedStyle.Text = activeTextStyle
|
||||
body.FocusedStyle.Placeholder = placeholderStyle
|
||||
body.BlurredStyle.CursorLine = textStyle
|
||||
body.BlurredStyle.Prompt = labelStyle
|
||||
body.BlurredStyle.Text = textStyle
|
||||
body.BlurredStyle.Placeholder = placeholderStyle
|
||||
body.Cursor.Style = cursorStyle
|
||||
body.CharLimit = 4000
|
||||
body.SetValue(defaults.Text)
|
||||
|
||||
// Adjust for signature (if none, this is a no-op)
|
||||
body.CursorUp()
|
||||
body.CursorUp()
|
||||
|
||||
body.CharLimit = 4000
|
||||
body.Blur()
|
||||
|
||||
// Decide which input to focus.
|
||||
@@ -170,9 +134,6 @@ func NewModel(defaults resend.SendEmailRequest, deliveryMethod DeliveryMethod) M
|
||||
attachments.DisableQuitKeybindings()
|
||||
attachments.SetShowTitle(true)
|
||||
attachments.Title = "Attachments"
|
||||
attachments.Styles.Title = labelStyle
|
||||
attachments.Styles.TitleBar = labelStyle
|
||||
attachments.Styles.NoItems = placeholderStyle
|
||||
attachments.SetShowHelp(false)
|
||||
attachments.SetShowStatusBar(false)
|
||||
attachments.SetStatusBarItemName("attachment", "attachments")
|
||||
@@ -186,7 +147,6 @@ func NewModel(defaults resend.SendEmailRequest, deliveryMethod DeliveryMethod) M
|
||||
picker.CurrentDirectory, _ = os.UserHomeDir()
|
||||
|
||||
loadingSpinner := spinner.New()
|
||||
loadingSpinner.Style = activeLabelStyle
|
||||
loadingSpinner.Spinner = spinner.Dot
|
||||
|
||||
m := Model{
|
||||
@@ -213,9 +173,7 @@ func NewModel(defaults resend.SendEmailRequest, deliveryMethod DeliveryMethod) M
|
||||
|
||||
// Init initializes the model.
|
||||
func (m Model) Init() tea.Cmd {
|
||||
return tea.Batch(
|
||||
m.From.Cursor.BlinkCmd(),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
type clearErrMsg struct{}
|
||||
@@ -370,70 +328,46 @@ func (m *Model) blurInputs() {
|
||||
m.Cc.Blur()
|
||||
m.Bcc.Blur()
|
||||
}
|
||||
m.From.PromptStyle = labelStyle
|
||||
m.To.PromptStyle = labelStyle
|
||||
if m.showCc {
|
||||
m.Cc.PromptStyle = labelStyle
|
||||
m.Cc.TextStyle = textStyle
|
||||
m.Bcc.PromptStyle = labelStyle
|
||||
m.Bcc.TextStyle = textStyle
|
||||
}
|
||||
m.Subject.PromptStyle = labelStyle
|
||||
m.From.TextStyle = textStyle
|
||||
m.To.TextStyle = textStyle
|
||||
m.Subject.TextStyle = textStyle
|
||||
m.Attachments.Styles.Title = labelStyle
|
||||
m.Attachments.SetDelegate(attachmentDelegate{false})
|
||||
}
|
||||
|
||||
func (m *Model) focusActiveInput() {
|
||||
switch m.state {
|
||||
case editingFrom:
|
||||
m.From.PromptStyle = activeLabelStyle
|
||||
m.From.TextStyle = activeTextStyle
|
||||
m.From.Focus()
|
||||
m.From.CursorEnd()
|
||||
case editingTo:
|
||||
m.To.PromptStyle = activeLabelStyle
|
||||
m.To.TextStyle = activeTextStyle
|
||||
m.To.Focus()
|
||||
m.To.CursorEnd()
|
||||
case editingCc:
|
||||
m.Cc.PromptStyle = activeLabelStyle
|
||||
m.Cc.TextStyle = activeTextStyle
|
||||
m.Cc.Focus()
|
||||
m.Cc.CursorEnd()
|
||||
case editingBcc:
|
||||
m.Bcc.PromptStyle = activeLabelStyle
|
||||
m.Bcc.TextStyle = activeTextStyle
|
||||
m.Bcc.Focus()
|
||||
m.Bcc.CursorEnd()
|
||||
case editingSubject:
|
||||
m.Subject.PromptStyle = activeLabelStyle
|
||||
m.Subject.TextStyle = activeTextStyle
|
||||
m.Subject.Focus()
|
||||
m.Subject.CursorEnd()
|
||||
case editingBody:
|
||||
m.Body.Focus()
|
||||
m.Body.CursorEnd()
|
||||
case editingAttachments:
|
||||
m.Attachments.Styles.Title = activeLabelStyle
|
||||
m.Attachments.SetDelegate(attachmentDelegate{true})
|
||||
}
|
||||
}
|
||||
|
||||
// View displays the application.
|
||||
func (m Model) View() string {
|
||||
func (m Model) View() tea.View {
|
||||
if m.quitting {
|
||||
return ""
|
||||
return tea.NewView("")
|
||||
}
|
||||
|
||||
switch m.state {
|
||||
case pickingFile:
|
||||
return "\n" + activeLabelStyle.Render("Attachments") + " " + commentStyle.Render(m.filepicker.CurrentDirectory) +
|
||||
"\n\n" + m.filepicker.View()
|
||||
return tea.NewView("\n" + activeLabelStyle.Render("Attachments") + " " + commentStyle.Render(m.filepicker.CurrentDirectory) +
|
||||
"\n\n" + m.filepicker.View())
|
||||
case sendingEmail:
|
||||
return "\n " + m.loadingSpinner.View() + "Sending email"
|
||||
return tea.NewView("\n " + m.loadingSpinner.View() + "Sending email")
|
||||
}
|
||||
|
||||
var s strings.Builder
|
||||
@@ -469,5 +403,5 @@ func (m Model) View() string {
|
||||
s.WriteString(errorStyle.Render(m.err.Error()))
|
||||
}
|
||||
|
||||
return paddedStyle.Render(s.String())
|
||||
return tea.NewView(paddedStyle.Render(s.String()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user