diff options
author | Stephen Brennan <stephen@brennan.io> | 2019-08-27 21:54:28 -0700 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-08-29 08:44:08 +0900 |
commit | ac99d9ed62644cf0259bdd79481b28c3fbcef650 (patch) | |
tree | 3c71dda62e9b2cd8f27d03d3af4edf6dbbae6e36 | |
parent | a2c5233f71522c894b90388623959dcd4cd44256 (diff) | |
download | aerc-ac99d9ed62644cf0259bdd79481b28c3fbcef650.tar.gz |
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.
-rw-r--r-- | lib/msgstore.go | 2 | ||||
-rw-r--r-- | widgets/msglist.go | 31 |
2 files changed, 32 insertions, 1 deletions
diff --git a/lib/msgstore.go b/lib/msgstore.go index 1061c8e3..169d51d8 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 9900a32c..df83dbd4 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] |