Detailed changes
@@ -15,6 +15,9 @@ type Account struct {
Email string `json:"email"`
Password string `json:"password"`
ServiceProvider string `json:"service_provider"` // "gmail", "icloud", or "custom"
+ // FetchEmail is the single email address for which messages should be fetched.
+ // If empty, it will default to `Email` when accounts are added.
+ FetchEmail string `json:"fetch_email,omitempty"`
// Custom server settings (used when ServiceProvider is "custom")
IMAPServer string `json:"imap_server,omitempty"`
@@ -144,6 +147,8 @@ func LoadConfig() (*Config, error) {
Email: legacyConfig.Email,
Password: legacyConfig.Password,
ServiceProvider: legacyConfig.ServiceProvider,
+ // Default FetchEmail to the legacy Email value
+ FetchEmail: legacyConfig.Email,
},
},
}
@@ -171,6 +176,10 @@ func (c *Config) AddAccount(account Account) {
if account.ID == "" {
account.ID = uuid.New().String()
}
+ // Ensure FetchEmail defaults to the login Email if not explicitly set.
+ if account.FetchEmail == "" && account.Email != "" {
+ account.FetchEmail = account.Email
+ }
c.Accounts = append(c.Accounts, account)
}
@@ -164,9 +164,33 @@ func FetchEmails(account *config.Account, limit, offset uint32) ([]Email, error)
}
var toAddrList []string
+ // Build recipient list from To and Cc for matching and display
for _, addr := range msg.Envelope.To {
toAddrList = append(toAddrList, addr.Address())
}
+ for _, addr := range msg.Envelope.Cc {
+ toAddrList = append(toAddrList, addr.Address())
+ }
+
+ // Determine which email to filter on: prefer Account.FetchEmail, fallback to Account.Email
+ fetchEmail := strings.ToLower(strings.TrimSpace(account.FetchEmail))
+ if fetchEmail == "" {
+ fetchEmail = strings.ToLower(strings.TrimSpace(account.Email))
+ }
+
+ // Check if any recipient matches the fetchEmail
+ matched := false
+ for _, r := range toAddrList {
+ if strings.EqualFold(strings.TrimSpace(r), fetchEmail) {
+ matched = true
+ break
+ }
+ }
+
+ if !matched {
+ // Skip messages not addressed to the configured fetch email
+ continue
+ }
emails = append(emails, Email{
UID: msg.Uid,
@@ -140,9 +140,10 @@ func (m *mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
account := config.Account{
ID: uuid.New().String(),
Name: msg.Name,
- Email: msg.Email,
+ Email: msg.Host, // login/email used for authentication comes from Host field in the form
Password: msg.Password,
ServiceProvider: msg.Provider,
+ FetchEmail: msg.FetchEmail,
}
if msg.Provider == "custom" {
@@ -152,6 +153,11 @@ func (m *mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
account.SMTPPort = msg.SMTPPort
}
+ // Ensure FetchEmail defaults to the login Email (Host) if not explicitly set
+ if account.FetchEmail == "" && account.Email != "" {
+ account.FetchEmail = account.Email
+ }
+
if m.config == nil {
m.config = &config.Config{}
}
@@ -23,6 +23,7 @@ const (
inputProvider = iota
inputName
inputEmail
+ inputFetchEmail
inputPassword
inputIMAPServer
inputIMAPPort
@@ -52,6 +53,9 @@ func NewLogin() *Login {
t.Placeholder = "Display Name"
t.Prompt = "👤 > "
case inputEmail:
+ t.Placeholder = "Host"
+ t.Prompt = "🏠 > "
+ case inputFetchEmail:
t.Placeholder = "Email Address"
t.Prompt = "✉️ > "
case inputPassword:
@@ -130,7 +134,8 @@ func (m *Login) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return Credentials{
Provider: m.inputs[inputProvider].Value(),
Name: m.inputs[inputName].Value(),
- Email: m.inputs[inputEmail].Value(),
+ Host: m.inputs[inputEmail].Value(),
+ FetchEmail: m.inputs[inputFetchEmail].Value(),
Password: m.inputs[inputPassword].Value(),
IMAPServer: m.inputs[inputIMAPServer].Value(),
IMAPPort: imapPort,
@@ -218,6 +223,7 @@ func (m *Login) View() string {
m.inputs[inputProvider].View(),
m.inputs[inputName].View(),
m.inputs[inputEmail].View(),
+ m.inputs[inputFetchEmail].View(),
m.inputs[inputPassword].View(),
}
@@ -238,12 +244,13 @@ func (m *Login) View() string {
}
// SetEditMode sets the login form to edit an existing account.
-func (m *Login) SetEditMode(accountID, provider, name, email, imapServer string, imapPort int, smtpServer string, smtpPort int) {
+func (m *Login) SetEditMode(accountID, provider, name, email, fetchEmail, imapServer string, imapPort int, smtpServer string, smtpPort int) {
m.isEditMode = true
m.accountID = accountID
m.inputs[inputProvider].SetValue(provider)
m.inputs[inputName].SetValue(name)
m.inputs[inputEmail].SetValue(email)
+ m.inputs[inputFetchEmail].SetValue(fetchEmail)
m.showCustom = provider == "custom"
if m.showCustom {
@@ -24,7 +24,8 @@ type SendEmailMsg struct {
type Credentials struct {
Provider string
Name string
- Email string
+ Host string // Host (this was the previous \"Email Address\" field in the UI)
+ FetchEmail string // Single email address to fetch messages for. If empty, code should default this to Host when creating the account.
Password string
IMAPServer string
IMAPPort int