From ac99d9ed62644cf0259bdd79481b28c3fbcef650 Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Tue, 27 Aug 2019 21:54:28 -0700 Subject: [PATCH] Fix out-of-order messages by sorting as we display Sometimes I observe out-of-order messages when using a maildir inbox. It appears that the UIDs for these messages are returned out of order by the MessageStore. In order for a maildir MessageStore to return messages in most recently received order, it must have already opened all messages and parsed the date to use as a sort key. Rather than implement that, simply sort messages by time as we display. This fix shows my emails in order. --- lib/msgstore.go | 2 +- widgets/msglist.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/msgstore.go b/lib/msgstore.go index 1061c8e..169d51d 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -15,7 +15,7 @@ type MessageStore struct { Deleted map[uint32]interface{} DirInfo models.DirectoryInfo Messages map[uint32]*models.MessageInfo - // Ordered list of known UIDs + // List of known UIDs, order is not important uids []uint32 selected int diff --git a/widgets/msglist.go b/widgets/msglist.go index 9900a32..df83dbd 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -3,6 +3,7 @@ package widgets import ( "fmt" "log" + "sort" "github.com/gdamore/tcell" "github.com/mattn/go-runewidth" @@ -26,6 +27,34 @@ type MessageList struct { isInitalizing bool } +type msgSorter struct { + uids []uint32 + store *lib.MessageStore +} + +func (s *msgSorter) Len() int { + return len(s.uids) +} + +func (s *msgSorter) Less(i, j int) bool { + msgI := s.store.Messages[s.uids[i]] + msgJ := s.store.Messages[s.uids[j]] + if msgI == nil && msgJ == nil { + return false; // doesn't matter which order among nulls + } else if msgI == nil && msgJ != nil { + return true // say i is before j so we sort i to bottom + } else if msgI != nil && msgJ == nil { + return false // say i is after j so we sort j to bottom + } + return msgI.InternalDate.Before(msgJ.InternalDate) +} + +func (s *msgSorter) Swap(i, j int) { + tmp := s.uids[i] + s.uids[i] = s.uids[j] + s.uids[j] = tmp +} + func NewMessageList(conf *config.AercConfig, logger *log.Logger) *MessageList { ml := &MessageList{ conf: conf, @@ -66,6 +95,8 @@ func (ml *MessageList) Draw(ctx *ui.Context) { row int = 0 ) uids := store.Uids() + sorter := msgSorter{uids: uids, store: store} + sort.Sort(&sorter) for i := len(uids) - 1 - ml.scroll; i >= 0; i-- { uid := uids[i]