···4646// stay separate.
4747//
4848// Each thread is sorted internally by date ascending (oldest = root at bottom,
4949-// newest replies on top). Threads are sorted by most recent email.
5050-func threadEmails(emails []imap.Email) []threadedEmail {
4949+// newest replies on top). Threads are sorted by the user's chosen sort field
5050+// and order (sortField: "date", "from", "subject", "size"; sortReverse: true/false).
5151+func threadEmails(emails []imap.Email, sortField string, sortReverse bool) []threadedEmail {
5152 if len(emails) == 0 {
5253 return nil
5354 }
···141142 threads = append(threads, thread{indices: indices, newestIdx: newest})
142143 }
143144144144- // Sort threads by most recent email (newest first).
145145+ // Sort threads by user's chosen sort field and order.
146146+ // We use the newest email in each thread as the representative for sorting.
145147 sort.Slice(threads, func(i, j int) bool {
146146- return emails[threads[i].newestIdx].Date.After(emails[threads[j].newestIdx].Date)
148148+ a := emails[threads[i].newestIdx]
149149+ b := emails[threads[j].newestIdx]
150150+ var less bool
151151+ switch sortField {
152152+ case "from":
153153+ less = strings.ToLower(a.From) < strings.ToLower(b.From)
154154+ case "subject":
155155+ less = strings.ToLower(a.Subject) < strings.ToLower(b.Subject)
156156+ case "size":
157157+ less = a.Size < b.Size
158158+ default: // "date"
159159+ less = a.Date.Before(b.Date)
160160+ }
161161+ if sortReverse {
162162+ return !less
163163+ }
164164+ return less
147165 })
148166149167 // Build output with thread connector lines.