~rjarry/aerc

622802d3a5ea980b2d08ffec91497b57d3bae7f4 — Robin Jarry 5 months ago a5c046e
maildir: defer the count of recent messages

Since commit 01c96e78dfe8 ("Update DirectoryInfo handling for maildir"),
flags are checked for every message of a folder when entering it.
Iterating over all messages of a folder takes a long time for large
collections of emails.

Only count the number of messages and state that the directory info
counts are not accurate. Defer the parsing of message flags in
a goroutine to have a more responsive UI.

Fixes: https://todo.sr.ht/~rjarry/aerc/16
Suggested-by: Koni Marti <koni.marti@gmail.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
1 files changed, 32 insertions(+), 25 deletions(-)

M worker/maildir/worker.go
M worker/maildir/worker.go => worker/maildir/worker.go +32 -25
@@ 132,7 132,7 @@ func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo {
		// total unread
		Unseen: 0,

		AccurateCounts: true,
		AccurateCounts: false,
	}

	dir := w.c.Dir(name)


@@ 143,32 143,39 @@ func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo {
		return dirInfo
	}

	for _, uid := range uids {
		message, err := w.c.Message(dir, uid)
		if err != nil {
			w.worker.Logger.Printf("could not get message: %v", err)
			continue
		}
		flags, err := message.Flags()
		if err != nil {
			w.worker.Logger.Printf("could not get flags: %v", err)
			continue
		}
		seen := false
		for _, flag := range flags {
			if flag == maildir.FlagSeen {
				seen = true
	dirInfo.Exists = len(uids)

	go func() {
		info := dirInfo
		for _, uid := range uids {
			message, err := w.c.Message(dir, uid)
			if err != nil {
				w.worker.Logger.Printf("could not get message: %v", err)
				continue
			}
			flags, err := message.Flags()
			if err != nil {
				w.worker.Logger.Printf("could not get flags: %v", err)
				continue
			}
			seen := false
			for _, flag := range flags {
				if flag == maildir.FlagSeen {
					seen = true
				}
			}
			if !seen {
				info.Unseen++
			}
			if w.c.IsRecent(uid) {
				info.Recent++
			}
		}
		if !seen {
			dirInfo.Unseen++
		}
		if w.c.IsRecent(uid) {
			dirInfo.Recent++
		}
	}
	dirInfo.Unseen += dirInfo.Recent
	dirInfo.Exists = len(uids) + dirInfo.Recent
		info.Unseen += info.Recent
		info.Exists += info.Recent
		info.AccurateCounts = true
	}()

	return dirInfo
}