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.
This commit is contained in:
Stephen Brennan 2019-08-27 21:54:28 -07:00 committed by Drew DeVault
parent a2c5233f71
commit ac99d9ed62
2 changed files with 32 additions and 1 deletions

View file

@ -15,7 +15,7 @@ type MessageStore struct {
Deleted map[uint32]interface{} Deleted map[uint32]interface{}
DirInfo models.DirectoryInfo DirInfo models.DirectoryInfo
Messages map[uint32]*models.MessageInfo Messages map[uint32]*models.MessageInfo
// Ordered list of known UIDs // List of known UIDs, order is not important
uids []uint32 uids []uint32
selected int selected int

View file

@ -3,6 +3,7 @@ package widgets
import ( import (
"fmt" "fmt"
"log" "log"
"sort"
"github.com/gdamore/tcell" "github.com/gdamore/tcell"
"github.com/mattn/go-runewidth" "github.com/mattn/go-runewidth"
@ -26,6 +27,34 @@ type MessageList struct {
isInitalizing bool 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 { func NewMessageList(conf *config.AercConfig, logger *log.Logger) *MessageList {
ml := &MessageList{ ml := &MessageList{
conf: conf, conf: conf,
@ -66,6 +95,8 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
row int = 0 row int = 0
) )
uids := store.Uids() uids := store.Uids()
sorter := msgSorter{uids: uids, store: store}
sort.Sort(&sorter)
for i := len(uids) - 1 - ml.scroll; i >= 0; i-- { for i := len(uids) - 1 - ml.scroll; i >= 0; i-- {
uid := uids[i] uid := uids[i]