dirlist: update RUE counts for imap/maildir on move|copy|delete|archive
When moving/copying/deleting/archiving a message in imap, the RUE counts displayed in the dirlist would not update properly. Maildir has (had) an implementation that recounts the entire directory and updates the DirectoryInfo after one of these actions. This patch implements a more efficient method of updating, and also enables it to apply to IMAP without any additional requests. Upon completion of the action, the counts are manually updated with the count of messages in the action and recent and/or unseen states of those messages. This is more efficient for maildir, because we aren't counting everything in the store. For IMAP, we get the updates for free because we are only performing the update after confirmation from the server that the action has happened. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
parent
4985d1bab8
commit
8b6f9719a8
5 changed files with 53 additions and 21 deletions
|
@ -331,8 +331,42 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
|
|||
}
|
||||
case *types.MessagesDeleted:
|
||||
if store, ok := acct.dirlist.SelectedMsgStore(); ok {
|
||||
store.DirInfo.Exists -= len(msg.Uids)
|
||||
// False to trigger recount of recent/unseen
|
||||
store.DirInfo.AccurateCounts = false
|
||||
store.Update(msg)
|
||||
}
|
||||
case *types.MessagesCopied:
|
||||
// Only update the destination destStore if it is initialized
|
||||
if destStore, ok := acct.dirlist.MsgStore(msg.Destination); ok {
|
||||
var recent, unseen int
|
||||
for _, uid := range msg.Uids {
|
||||
// Get the message from the originating store
|
||||
msg, ok := acct.Store().Messages[uid]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
seen := false
|
||||
for _, flag := range msg.Flags {
|
||||
if flag == models.SeenFlag {
|
||||
seen = true
|
||||
}
|
||||
if flag == models.RecentFlag {
|
||||
recent = recent + 1
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
unseen = unseen + 1
|
||||
}
|
||||
}
|
||||
destStore.DirInfo.Recent += recent
|
||||
destStore.DirInfo.Unseen += unseen
|
||||
destStore.DirInfo.Exists += len(msg.Uids)
|
||||
// True. For imap, we don't have the message in the store until we
|
||||
// Select so we need to rely on the math we just did for accurate
|
||||
// counts
|
||||
destStore.DirInfo.AccurateCounts = true
|
||||
}
|
||||
case *types.LabelList:
|
||||
acct.labels = msg.Labels
|
||||
case *types.ConnError:
|
||||
|
|
|
@ -244,16 +244,12 @@ func (dirlist *DirectoryList) getRUEString(name string) string {
|
|||
return ""
|
||||
}
|
||||
var totalRecent, totalUnseen, totalExists int
|
||||
if msgStore.DirInfo.AccurateCounts {
|
||||
totalRecent = msgStore.DirInfo.Recent
|
||||
totalUnseen = msgStore.DirInfo.Unseen
|
||||
totalExists = msgStore.DirInfo.Exists
|
||||
} else {
|
||||
if !msgStore.DirInfo.AccurateCounts {
|
||||
totalRecent, totalUnseen = countRUE(msgStore)
|
||||
// use the total count from the dirinfo, else we only count already
|
||||
// fetched messages
|
||||
totalExists = msgStore.DirInfo.Exists
|
||||
msgStore.DirInfo.Recent = totalRecent
|
||||
msgStore.DirInfo.Unseen = totalUnseen
|
||||
}
|
||||
totalExists = msgStore.DirInfo.Exists
|
||||
rueString := ""
|
||||
if totalRecent > 0 {
|
||||
rueString = fmt.Sprintf("%d/%d/%d", totalRecent, totalUnseen, totalExists)
|
||||
|
|
|
@ -14,6 +14,11 @@ func (imapw *IMAPWorker) handleCopyMessages(msg *types.CopyMessages) {
|
|||
Error: err,
|
||||
}, nil)
|
||||
} else {
|
||||
imapw.worker.PostMessage(&types.MessagesCopied{
|
||||
Message: types.RespondTo(msg),
|
||||
Destination: msg.Destination,
|
||||
Uids: msg.Uids,
|
||||
}, nil)
|
||||
imapw.worker.PostMessage(&types.Done{Message: types.RespondTo(msg)}, nil)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -536,11 +536,6 @@ func (w *Worker) handleDeleteMessages(msg *types.DeleteMessages) error {
|
|||
w.worker.Logger.Printf("error removing some messages: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
w.worker.PostMessage(&types.DirectoryInfo{
|
||||
Info: w.getDirectoryInfo(w.selectedName),
|
||||
}, nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -617,15 +612,11 @@ func (w *Worker) handleCopyMessages(msg *types.CopyMessages) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.worker.PostMessage(&types.DirectoryInfo{
|
||||
Info: w.getDirectoryInfo(w.selectedName),
|
||||
w.worker.PostMessage(&types.MessagesCopied{
|
||||
Message: types.RespondTo(msg),
|
||||
Destination: msg.Destination,
|
||||
Uids: msg.Uids,
|
||||
}, nil)
|
||||
|
||||
w.worker.PostMessage(&types.DirectoryInfo{
|
||||
Info: w.getDirectoryInfo(msg.Destination),
|
||||
}, nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,12 @@ type MessagesDeleted struct {
|
|||
Uids []uint32
|
||||
}
|
||||
|
||||
type MessagesCopied struct {
|
||||
Message
|
||||
Destination string
|
||||
Uids []uint32
|
||||
}
|
||||
|
||||
type ModifyLabels struct {
|
||||
Message
|
||||
Uids []uint32
|
||||
|
|
Loading…
Reference in a new issue