aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2023-04-16 09:53:44 -0500
committerRobin Jarry <robin@jarry.cc>2023-04-22 22:40:12 +0200
commit5b0a98b8c936532fa5444b1cabf53d7c929d19c1 (patch)
treeb04415f6120d944cd74c45464a771d064cdd4305
parentf13fbe7a27756c63d85f40c15320664d634f59e2 (diff)
downloadaerc-5b0a98b8c936532fa5444b1cabf53d7c929d19c1.tar.gz
directory: use directory to store rue counts
Store the Directory RUE counts on the Directory data model. Use DirectoryInfo messages to update the Directory model. Access Directories via the dirlist instead of via the msgstore. Remove unused fields on DirectoryInfo, all backends now give accurate counts. Move refetch logic into dirlist Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry<robin@jarry.cc>
-rw-r--r--lib/dirstore.go4
-rw-r--r--lib/msgstore.go7
-rw-r--r--models/models.go16
-rw-r--r--widgets/account.go28
-rw-r--r--widgets/dirlist.go49
-rw-r--r--worker/imap/checkmail.go6
-rw-r--r--worker/imap/list.go6
-rw-r--r--worker/maildir/worker.go7
-rw-r--r--worker/mbox/models.go11
-rw-r--r--worker/notmuch/worker.go7
10 files changed, 57 insertions, 84 deletions
diff --git a/lib/dirstore.go b/lib/dirstore.go
index 76833622..bbf4e20b 100644
--- a/lib/dirstore.go
+++ b/lib/dirstore.go
@@ -36,3 +36,7 @@ func (store *DirStore) Remove(name string) {
delete(store.dirs, name)
delete(store.msgStores, name)
}
+
+func (store *DirStore) Directory(name string) *models.Directory {
+ return store.dirs[name]
+}
diff --git a/lib/msgstore.go b/lib/msgstore.go
index f81851e2..8e0785a6 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -18,7 +18,6 @@ import (
type MessageStore struct {
sync.Mutex
Deleted map[uint32]interface{}
- DirInfo models.DirectoryInfo
Messages map[uint32]*models.MessageInfo
Sorting bool
@@ -215,12 +214,6 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
case *types.OpenDirectory:
store.Sort(store.sortCriteria, nil)
update = true
- case *types.DirectoryInfo:
- store.DirInfo = *msg.Info
- if msg.Refetch {
- store.Sort(store.sortCriteria, nil)
- update = true
- }
case *types.DirectoryContents:
newMap := make(map[uint32]*models.MessageInfo)
for _, uid := range msg.Uids {
diff --git a/models/models.go b/models/models.go
index 5caeb4d3..a47ac24b 100644
--- a/models/models.go
+++ b/models/models.go
@@ -38,24 +38,22 @@ func (f Flags) Has(flags Flags) bool {
type Directory struct {
Name string
+ // Exists messages in the Directory
+ Exists int
+ // Recent messages in the Directory
+ Recent int
+ // Unseen messages in the Directory
+ Unseen int
}
type DirectoryInfo struct {
- Name string
- Flags []string
- ReadOnly bool
-
+ Name string
// The total number of messages in this mailbox.
Exists int
-
// The number of messages not seen since the last time the mailbox was opened.
Recent int
-
// The number of unread messages
Unseen int
-
- // set to true if the value counts are accurate
- AccurateCounts bool
}
// Capabilities provides the backend capabilities
diff --git a/widgets/account.go b/widgets/account.go
index 6449aeba..983c2382 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -310,9 +310,7 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
store.SetMarker(marker.New(store))
acct.dirlist.SetMsgStore(msg.Dir, store)
case *types.DirectoryInfo:
- if store, ok := acct.dirlist.MsgStore(msg.Info.Name); ok {
- store.Update(msg)
- }
+ acct.dirlist.Update(msg)
case *types.DirectoryContents:
if store, ok := acct.dirlist.SelectedMsgStore(); ok {
if acct.msglist.Store() == nil {
@@ -344,10 +342,10 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
store.Update(msg)
}
case *types.MessagesDeleted:
+ if dir := acct.dirlist.SelectedDirectory(); dir != nil {
+ dir.Exists -= len(msg.Uids)
+ }
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:
@@ -371,8 +369,8 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
}
func (acct *AccountView) updateDirCounts(destination string, uids []uint32) {
- // Only update the destination destStore if it is initialized
- if destStore, ok := acct.dirlist.MsgStore(destination); ok {
+ // Only update the destination destDir if it is initialized
+ if destDir := acct.dirlist.Directory(destination); destDir != nil {
var recent, unseen int
var accurate bool = true
for _, uid := range uids {
@@ -395,17 +393,11 @@ func (acct *AccountView) updateDirCounts(destination string, uids []uint32) {
}
}
if accurate {
- destStore.DirInfo.Recent += recent
- destStore.DirInfo.Unseen += unseen
- destStore.DirInfo.Exists += len(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
+ destDir.Recent += recent
+ destDir.Unseen += unseen
+ destDir.Exists += len(uids)
} else {
- destStore.DirInfo.Exists += len(uids)
- // False to trigger recount of recent/unseen
- destStore.DirInfo.AccurateCounts = false
+ destDir.Exists += len(uids)
}
}
}
diff --git a/widgets/dirlist.go b/widgets/dirlist.go
index 85cf4112..ee2acb1b 100644
--- a/widgets/dirlist.go
+++ b/widgets/dirlist.go
@@ -39,6 +39,8 @@ type DirectoryLister interface {
SelectedMsgStore() (*lib.MessageStore, bool)
MsgStore(string) (*lib.MessageStore, bool)
+ SelectedDirectory() *models.Directory
+ Directory(string) *models.Directory
SetMsgStore(*models.Directory, *lib.MessageStore)
FilterDirs([]string, []string, bool) []string
@@ -112,6 +114,20 @@ func (dirlist *DirectoryList) Update(msg types.WorkerMessage) {
dirlist.filterDirsByFoldersConfig()
dirlist.sortDirsByFoldersSortConfig()
}
+ case *types.DirectoryInfo:
+ dir := dirlist.Directory(msg.Info.Name)
+ if dir == nil {
+ return
+ }
+ dir.Exists = msg.Info.Exists
+ dir.Recent = msg.Info.Recent
+ dir.Unseen = msg.Info.Unseen
+ if msg.Refetch {
+ store, ok := dirlist.SelectedMsgStore()
+ if ok {
+ store.Sort(store.GetCurrentSortCriteria(), nil)
+ }
+ }
default:
return
}
@@ -183,15 +199,11 @@ func (dirlist *DirectoryList) Invalidate() {
// Returns the Recent, Unread, and Exist counts for the named directory
func (dirlist *DirectoryList) GetRUECount(name string) (int, int, int) {
- msgStore, ok := dirlist.MsgStore(name)
- if !ok {
+ dir := dirlist.Directory(name)
+ if dir == nil {
return 0, 0, 0
}
- if !msgStore.DirInfo.AccurateCounts {
- msgStore.DirInfo.Recent, msgStore.DirInfo.Unseen = countRUE(msgStore)
- }
- di := msgStore.DirInfo
- return di.Recent, di.Unseen, di.Exists
+ return dir.Recent, dir.Unseen, dir.Exists
}
func (dirlist *DirectoryList) Draw(ctx *ui.Context) {
@@ -478,6 +490,14 @@ func (dirlist *DirectoryList) MsgStore(name string) (*lib.MessageStore, bool) {
return dirlist.store.MessageStore(name)
}
+func (dirlist *DirectoryList) SelectedDirectory() *models.Directory {
+ return dirlist.store.Directory(dirlist.selected)
+}
+
+func (dirlist *DirectoryList) Directory(name string) *models.Directory {
+ return dirlist.store.Directory(name)
+}
+
func (dirlist *DirectoryList) SetMsgStore(dir *models.Directory, msgStore *lib.MessageStore) {
dirlist.store.SetMessageStore(dir, msgStore)
msgStore.OnUpdateDirs(func() {
@@ -493,18 +513,3 @@ func findString(slice []string, str string) int {
}
return -1
}
-
-func countRUE(msgStore *lib.MessageStore) (recent, unread int) {
- for _, msg := range msgStore.Messages {
- if msg == nil {
- continue
- }
- if msg.Flags.Has(models.RecentFlag) {
- recent++
- }
- if !msg.Flags.Has(models.SeenFlag) {
- unread++
- }
- }
- return recent, unread
-}
diff --git a/worker/imap/checkmail.go b/worker/imap/checkmail.go
index 05441a3c..76da58ad 100644
--- a/worker/imap/checkmail.go
+++ b/worker/imap/checkmail.go
@@ -58,11 +58,7 @@ func (w *IMAPWorker) handleCheckMailMessage(msg *types.CheckMail) {
}
w.worker.PostMessage(&types.DirectoryInfo{
Info: &models.DirectoryInfo{
- Flags: status.Flags,
- Name: status.Name,
- ReadOnly: status.ReadOnly,
- AccurateCounts: true,
-
+ Name: status.Name,
Exists: int(status.Messages),
Recent: int(status.Recent),
Unseen: int(status.Unseen),
diff --git a/worker/imap/list.go b/worker/imap/list.go
index 07aa2971..657779e5 100644
--- a/worker/imap/list.go
+++ b/worker/imap/list.go
@@ -56,11 +56,7 @@ func (imapw *IMAPWorker) handleListDirectories(msg *types.ListDirectories) {
for _, status := range statuses {
imapw.worker.PostMessage(&types.DirectoryInfo{
Info: &models.DirectoryInfo{
- Flags: status.Flags,
- Name: status.Name,
- ReadOnly: status.ReadOnly,
- AccurateCounts: true,
-
+ Name: status.Name,
Exists: int(status.Messages),
Recent: int(status.Recent),
Unseen: int(status.Unseen),
diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go
index c57f0d67..69d39fa8 100644
--- a/worker/maildir/worker.go
+++ b/worker/maildir/worker.go
@@ -186,17 +186,13 @@ func dirFiles(name string) ([]string, error) {
func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo {
dirInfo := &models.DirectoryInfo{
- Name: name,
- Flags: []string{},
- ReadOnly: false,
+ Name: name,
// total messages
Exists: 0,
// new messages since mailbox was last opened
Recent: 0,
// total unread
Unseen: 0,
-
- AccurateCounts: false,
}
dir := w.c.Store.Dir(name)
@@ -263,7 +259,6 @@ func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo {
dirInfo.Recent++
}
}
- dirInfo.AccurateCounts = true
return dirInfo
}
diff --git a/worker/mbox/models.go b/worker/mbox/models.go
index 1546f01a..491128c5 100644
--- a/worker/mbox/models.go
+++ b/worker/mbox/models.go
@@ -42,13 +42,10 @@ func (md *mailboxContainer) DirectoryInfo(file string) *models.DirectoryInfo {
exists = len(md.Uids())
}
return &models.DirectoryInfo{
- Name: file,
- Flags: []string{},
- ReadOnly: false,
- Exists: exists,
- Recent: 0,
- Unseen: 0,
- AccurateCounts: false,
+ Name: file,
+ Exists: exists,
+ Recent: 0,
+ Unseen: 0,
}
}
diff --git a/worker/notmuch/worker.go b/worker/notmuch/worker.go
index 199eb64f..b25a8786 100644
--- a/worker/notmuch/worker.go
+++ b/worker/notmuch/worker.go
@@ -273,16 +273,13 @@ func (w *worker) handleListDirectories(msg *types.ListDirectories) error {
func (w *worker) getDirectoryInfo(name string, query string) *models.DirectoryInfo {
dirInfo := &models.DirectoryInfo{
- Name: name,
- Flags: []string{},
- ReadOnly: false,
+ Name: name,
// total messages
Exists: 0,
// new messages since mailbox was last opened
Recent: 0,
// total unread
- Unseen: 0,
- AccurateCounts: true,
+ Unseen: 0,
}
count, err := w.db.QueryCountMessages(query)