about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/msgstore.go86
-rw-r--r--widgets/account.go7
-rw-r--r--widgets/msglist.go86
3 files changed, 93 insertions, 86 deletions
diff --git a/lib/msgstore.go b/lib/msgstore.go
new file mode 100644
index 0000000..79e1977
--- /dev/null
+++ b/lib/msgstore.go
@@ -0,0 +1,86 @@
+package lib
+
+import (
+	"github.com/emersion/go-imap"
+
+	"git.sr.ht/~sircmpwn/aerc2/worker/types"
+)
+
+type MessageStore struct {
+	DirInfo  types.DirectoryInfo
+	Messages map[uint32]*types.MessageInfo
+	// Ordered list of known UIDs
+	Uids []uint32
+	// Map of uids we've asked the worker to fetch
+	onUpdate       func(store *MessageStore)
+	pendingBodies  map[uint32]interface{}
+	pendingHeaders map[uint32]interface{}
+	worker         *types.Worker
+}
+
+func NewMessageStore(worker *types.Worker,
+	dirInfo *types.DirectoryInfo) *MessageStore {
+
+	return &MessageStore{
+		DirInfo: *dirInfo,
+
+		pendingBodies:  make(map[uint32]interface{}),
+		pendingHeaders: make(map[uint32]interface{}),
+		worker:         worker,
+	}
+}
+
+func (store *MessageStore) FetchHeaders(uids []uint32) {
+	// TODO: this could be optimized by pre-allocating toFetch and trimming it
+	// at the end. In practice we expect to get most messages back in one frame.
+	var toFetch imap.SeqSet
+	for _, uid := range uids {
+		if _, ok := store.pendingHeaders[uid]; !ok {
+			toFetch.AddNum(uint32(uid))
+			store.pendingHeaders[uid] = nil
+		}
+	}
+	if !toFetch.Empty() {
+		store.worker.PostAction(&types.FetchMessageHeaders{
+			Uids: toFetch,
+		}, nil)
+	}
+}
+
+func (store *MessageStore) Update(msg types.WorkerMessage) {
+	update := false
+	switch msg := msg.(type) {
+	case *types.DirectoryInfo:
+		store.DirInfo = *msg
+		update = true
+		break
+	case *types.DirectoryContents:
+		newMap := make(map[uint32]*types.MessageInfo)
+		for _, uid := range msg.Uids {
+			if msg, ok := store.Messages[uid]; ok {
+				newMap[uid] = msg
+			} else {
+				newMap[uid] = nil
+			}
+		}
+		store.Messages = newMap
+		store.Uids = msg.Uids
+		update = true
+		break
+	case *types.MessageInfo:
+		// TODO: merge message info into existing record, if applicable
+		store.Messages[msg.Uid] = msg
+		if _, ok := store.pendingHeaders[msg.Uid]; msg.Envelope != nil && ok {
+			delete(store.pendingHeaders, msg.Uid)
+		}
+		update = true
+		break
+	}
+	if update && store.onUpdate != nil {
+		store.onUpdate(store)
+	}
+}
+
+func (store *MessageStore) OnUpdate(fn func(store *MessageStore)) {
+	store.onUpdate = fn
+}
diff --git a/widgets/account.go b/widgets/account.go
index 8716b11..6919c0e 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -8,6 +8,7 @@ import (
 	"github.com/gdamore/tcell"
 
 	"git.sr.ht/~sircmpwn/aerc2/config"
+	"git.sr.ht/~sircmpwn/aerc2/lib"
 	"git.sr.ht/~sircmpwn/aerc2/lib/ui"
 	"git.sr.ht/~sircmpwn/aerc2/worker"
 	"git.sr.ht/~sircmpwn/aerc2/worker/types"
@@ -23,7 +24,7 @@ type AccountView struct {
 	onInvalidate func(d ui.Drawable)
 	runCmd       func(cmd string) error
 	msglist      *MessageList
-	msgStores    map[string]*MessageStore
+	msgStores    map[string]*lib.MessageStore
 	pendingKeys  []config.KeyStroke
 	statusline   *StatusLine
 	statusbar    *ui.Stack
@@ -70,7 +71,7 @@ func NewAccountView(conf *config.AercConfig, acct *config.AccountConfig,
 		grid:       grid,
 		logger:     logger,
 		msglist:    msglist,
-		msgStores:  make(map[string]*MessageStore),
+		msgStores:  make(map[string]*lib.MessageStore),
 		runCmd:     runCmd,
 		statusbar:  statusbar,
 		statusline: statusline,
@@ -226,7 +227,7 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
 		if store, ok := acct.msgStores[msg.Name]; ok {
 			store.Update(msg)
 		} else {
-			acct.msgStores[msg.Name] = NewMessageStore(acct.worker, msg)
+			acct.msgStores[msg.Name] = lib.NewMessageStore(acct.worker, msg)
 		}
 	case *types.DirectoryContents:
 		store := acct.msgStores[acct.dirlist.selected]
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 5ba75a8..0fb919d 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -3,100 +3,20 @@ package widgets
 import (
 	"log"
 
-	"github.com/emersion/go-imap"
 	"github.com/gdamore/tcell"
 
 	"git.sr.ht/~sircmpwn/aerc2/config"
+	"git.sr.ht/~sircmpwn/aerc2/lib"
 	"git.sr.ht/~sircmpwn/aerc2/lib/ui"
-	"git.sr.ht/~sircmpwn/aerc2/worker/types"
 )
 
-type MessageStore struct {
-	DirInfo  types.DirectoryInfo
-	Messages map[uint32]*types.MessageInfo
-	// Ordered list of known UIDs
-	Uids []uint32
-	// Map of uids we've asked the worker to fetch
-	onUpdate       func(store *MessageStore)
-	pendingBodies  map[uint32]interface{}
-	pendingHeaders map[uint32]interface{}
-	worker         *types.Worker
-}
-
-func NewMessageStore(worker *types.Worker,
-	dirInfo *types.DirectoryInfo) *MessageStore {
-
-	return &MessageStore{
-		DirInfo: *dirInfo,
-
-		pendingBodies:  make(map[uint32]interface{}),
-		pendingHeaders: make(map[uint32]interface{}),
-		worker:         worker,
-	}
-}
-
-func (store *MessageStore) FetchHeaders(uids []uint32) {
-	// TODO: this could be optimized by pre-allocating toFetch and trimming it
-	// at the end. In practice we expect to get most messages back in one frame.
-	var toFetch imap.SeqSet
-	for _, uid := range uids {
-		if _, ok := store.pendingHeaders[uid]; !ok {
-			toFetch.AddNum(uint32(uid))
-			store.pendingHeaders[uid] = nil
-		}
-	}
-	if !toFetch.Empty() {
-		store.worker.PostAction(&types.FetchMessageHeaders{
-			Uids: toFetch,
-		}, nil)
-	}
-}
-
-func (store *MessageStore) Update(msg types.WorkerMessage) {
-	update := false
-	switch msg := msg.(type) {
-	case *types.DirectoryInfo:
-		store.DirInfo = *msg
-		update = true
-		break
-	case *types.DirectoryContents:
-		newMap := make(map[uint32]*types.MessageInfo)
-		for _, uid := range msg.Uids {
-			if msg, ok := store.Messages[uid]; ok {
-				newMap[uid] = msg
-			} else {
-				newMap[uid] = nil
-			}
-		}
-		store.Messages = newMap
-		store.Uids = msg.Uids
-		update = true
-		break
-	case *types.MessageInfo:
-		// TODO: merge message info into existing record, if applicable
-		store.Messages[msg.Uid] = msg
-		if _, ok := store.pendingHeaders[msg.Uid]; msg.Envelope != nil && ok {
-			delete(store.pendingHeaders, msg.Uid)
-		}
-		update = true
-		break
-	}
-	if update && store.onUpdate != nil {
-		store.onUpdate(store)
-	}
-}
-
-func (store *MessageStore) OnUpdate(fn func(store *MessageStore)) {
-	store.onUpdate = fn
-}
-
 type MessageList struct {
 	conf         *config.AercConfig
 	logger       *log.Logger
 	onInvalidate func(d ui.Drawable)
 	selected     int
 	spinner      *Spinner
-	store        *MessageStore
+	store        *lib.MessageStore
 }
 
 // TODO: fish in config
@@ -171,7 +91,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
 	}
 }
 
-func (ml *MessageList) SetStore(store *MessageStore) {
+func (ml *MessageList) SetStore(store *lib.MessageStore) {
 	ml.store = store
 	if store != nil {
 		ml.spinner.Stop()