diff --git a/internal/db/db.go b/internal/db/db.go index ce49922..7908088 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -1741,8 +1741,8 @@ func (d *DB) ListMessages(userID int64, folderIDs []int64, accountID int64, page args = append(args, pageSize, offset) rows, err := d.sql.Query(` - SELECT m.id, m.account_id, a.email_address, a.color, m.folder_id, f.name, - m.subject, m.from_name, m.from_email, m.body_text, + SELECT m.id, m.account_id, a.email_address, a.display_name, a.color, m.folder_id, f.name, + m.subject, m.from_name, m.from_email, m.to_list, m.body_text, m.date, m.is_read, m.is_starred, m.has_attachment FROM messages m JOIN email_accounts a ON a.id = m.account_id @@ -1759,10 +1759,10 @@ func (d *DB) ListMessages(userID int64, folderIDs []int64, accountID int64, page var summaries []models.MessageSummary for rows.Next() { s := models.MessageSummary{} - var subjectEnc, fromNameEnc, fromEmailEnc, bodyTextEnc string + var subjectEnc, fromNameEnc, fromEmailEnc, toListEnc, bodyTextEnc string if err := rows.Scan( - &s.ID, &s.AccountID, &s.AccountEmail, &s.AccountColor, &s.FolderID, &s.FolderName, - &subjectEnc, &fromNameEnc, &fromEmailEnc, &bodyTextEnc, + &s.ID, &s.AccountID, &s.AccountEmail, &s.AccountName, &s.AccountColor, &s.FolderID, &s.FolderName, + &subjectEnc, &fromNameEnc, &fromEmailEnc, &toListEnc, &bodyTextEnc, &s.Date, &s.IsRead, &s.IsStarred, &s.HasAttachment, ); err != nil { return nil, err @@ -1770,6 +1770,7 @@ func (d *DB) ListMessages(userID int64, folderIDs []int64, accountID int64, page s.Subject, _ = d.enc.Decrypt(subjectEnc) s.FromName, _ = d.enc.Decrypt(fromNameEnc) s.FromEmail, _ = d.enc.Decrypt(fromEmailEnc) + s.ToList, _ = d.enc.Decrypt(toListEnc) bodyText, _ := d.enc.Decrypt(bodyTextEnc) if len(bodyText) > 120 { bodyText = bodyText[:120] + "…" @@ -1874,8 +1875,8 @@ func (d *DB) SearchMessages(userID int64, q string, filters SearchFilters, page, qArgs := append(append([]interface{}{}, args...), pageSize, offset) rows, err := d.sql.Query(` - SELECT m.id, m.account_id, a.email_address, a.color, m.folder_id, f.name, - m.subject, m.from_name, m.from_email, m.body_text, + SELECT m.id, m.account_id, a.email_address, a.display_name, a.color, m.folder_id, f.name, + m.subject, m.from_name, m.from_email, m.to_list, m.body_text, m.date, m.is_read, m.is_starred, m.has_attachment, `+approxSizeExpr+` FROM messages m JOIN email_accounts a ON a.id=m.account_id @@ -1891,10 +1892,10 @@ func (d *DB) SearchMessages(userID int64, q string, filters SearchFilters, page, var summaries []models.MessageSummary for rows.Next() { s := models.MessageSummary{} - var subjectEnc, fromNameEnc, fromEmailEnc, bodyTextEnc string + var subjectEnc, fromNameEnc, fromEmailEnc, toListEnc, bodyTextEnc string if err := rows.Scan( - &s.ID, &s.AccountID, &s.AccountEmail, &s.AccountColor, &s.FolderID, &s.FolderName, - &subjectEnc, &fromNameEnc, &fromEmailEnc, &bodyTextEnc, + &s.ID, &s.AccountID, &s.AccountEmail, &s.AccountName, &s.AccountColor, &s.FolderID, &s.FolderName, + &subjectEnc, &fromNameEnc, &fromEmailEnc, &toListEnc, &bodyTextEnc, &s.Date, &s.IsRead, &s.IsStarred, &s.HasAttachment, &s.Size, ); err != nil { return nil, err @@ -1902,6 +1903,7 @@ func (d *DB) SearchMessages(userID int64, q string, filters SearchFilters, page, s.Subject, _ = d.enc.Decrypt(subjectEnc) s.FromName, _ = d.enc.Decrypt(fromNameEnc) s.FromEmail, _ = d.enc.Decrypt(fromEmailEnc) + s.ToList, _ = d.enc.Decrypt(toListEnc) bodyText, _ := d.enc.Decrypt(bodyTextEnc) if len(bodyText) > 120 { bodyText = bodyText[:120] + "…" diff --git a/internal/models/models.go b/internal/models/models.go index b8e9e3f..a006d59 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -205,23 +205,25 @@ type Message struct { // MessageSummary is a lightweight version for list views. type MessageSummary struct { - ID int64 `json:"id"` - AccountID int64 `json:"account_id"` - AccountEmail string `json:"account_email"` - AccountColor string `json:"account_color"` - FolderID int64 `json:"folder_id"` - FolderName string `json:"folder_name"` - Subject string `json:"subject"` - FromName string `json:"from_name"` - FromEmail string `json:"from_email"` - Preview string `json:"preview"` // first ~100 chars of body - Date time.Time `json:"date"` - IsRead bool `json:"is_read"` - IsStarred bool `json:"is_starred"` - HasAttachment bool `json:"has_attachment"` + ID int64 `json:"id"` + AccountID int64 `json:"account_id"` + AccountEmail string `json:"account_email"` + AccountName string `json:"account_name"` // account's own display_name (may be blank) + AccountColor string `json:"account_color"` + FolderID int64 `json:"folder_id"` + FolderName string `json:"folder_name"` + Subject string `json:"subject"` + FromName string `json:"from_name"` + FromEmail string `json:"from_email"` + ToList string `json:"to_list"` // comma-separated; only shown in the Sent folder view + Preview string `json:"preview"` // first ~100 chars of body + Date time.Time `json:"date"` + IsRead bool `json:"is_read"` + IsStarred bool `json:"is_starred"` + HasAttachment bool `json:"has_attachment"` SnoozedUntil *time.Time `json:"snoozed_until,omitempty"` - Size int64 `json:"size,omitempty"` // approximate; only populated by search results - Labels []Label `json:"labels,omitempty"` + Size int64 `json:"size,omitempty"` // approximate; only populated by search results + Labels []Label `json:"labels,omitempty"` } // ScheduledSend is a fully-composed message held until SendAt, delivered by the background diff --git a/web/static/css/gowebmail.css b/web/static/css/gowebmail.css index 9d383d4..6090b93 100644 --- a/web/static/css/gowebmail.css +++ b/web/static/css/gowebmail.css @@ -279,6 +279,8 @@ body.app-page{overflow:hidden} .msg-thread-count{color:var(--muted);font-size:11px;font-weight:600} .msg-preview{color:var(--muted)} .msg-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0} +.msg-account-name{font-size:10px;color:var(--muted);flex-shrink:0;max-width:110px;overflow:hidden; + text-overflow:ellipsis;white-space:nowrap;background:var(--surface3);padding:1px 6px;border-radius:4px} .msg-icons{display:flex;align-items:center;gap:4px;flex-shrink:0} .msg-size{font-size:10px;color:var(--muted)} .msg-star{color:var(--muted);font-size:15px;cursor:pointer} diff --git a/web/static/js/app.js b/web/static/js/app.js index 764c647..d0b4afb 100644 --- a/web/static/js/app.js +++ b/web/static/js/app.js @@ -1349,7 +1349,14 @@ function renderMessageList() { // Update bulk action bar updateBulkBar(); - list.innerHTML=msgs.map((m,i)=>` + const sentView = isSentFolderView(); + + list.innerHTML=msgs.map((m,i)=>{ + const acctLabel = m.account_name || m.account_email || ''; + const fromLine = sentView + ? `To: ${m.to_list || '(no recipient)'}` + : (m.from_name ? `${m.from_name} - ${m.from_email}` : (m.from_email||'')); + return `