diff options
author | Tim Culverhouse <tim@timculverhouse.com> | 2022-06-01 19:24:53 -0500 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-06-07 16:19:23 +0200 |
commit | 8b6f9719a84fa0ee31d84b9e864495af4f166d92 (patch) | |
tree | 8c5bc108673cce4a33e124c20855e633acabd667 | |
parent | 4985d1bab8996a995bd93abe120835320e3c7d82 (diff) | |
download | aerc-8b6f9719a84fa0ee31d84b9e864495af4f166d92.zip |
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>
-rw-r--r-- | widgets/account.go | 34 | ||||
-rw-r--r-- | widgets/dirlist.go | 12 | ||||
-rw-r--r-- | worker/imap/movecopy.go | 5 | ||||
-rw-r--r-- | worker/maildir/worker.go | 17 | ||||
-rw-r--r-- | worker/types/messages.go | 6 |
5 files changed, 53 insertions, 21 deletions
diff --git a/widgets/account.go b/widgets/account.go index e913cb7..2d3b0d2 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -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: diff --git a/widgets/dirlist.go b/widgets/dirlist.go index 99ffe19..60bd7fa 100644 --- a/widgets/dirlist.go +++ b/widgets/dirlist.go @@ -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) diff --git a/worker/imap/movecopy.go b/worker/imap/movecopy.go index 0b19ead..f1f2b45 100644 --- a/worker/imap/movecopy.go +++ b/worker/imap/movecopy.go @@ -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) } } diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go index d3de844..0a51ea7 100644 --- a/worker/maildir/worker.go +++ b/worker/maildir/worker.go @@ -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), - }, nil) - - w.worker.PostMessage(&types.DirectoryInfo{ - Info: w.getDirectoryInfo(msg.Destination), + w.worker.PostMessage(&types.MessagesCopied{ + Message: types.RespondTo(msg), + Destination: msg.Destination, + Uids: msg.Uids, }, nil) - return nil } diff --git a/worker/types/messages.go b/worker/types/messages.go index 5cd3768..d2d98fd 100644 --- a/worker/types/messages.go +++ b/worker/types/messages.go @@ -218,6 +218,12 @@ type MessagesDeleted struct { Uids []uint32 } +type MessagesCopied struct { + Message + Destination string + Uids []uint32 +} + type ModifyLabels struct { Message Uids []uint32 |