diff options
| author | Drew DeVault <sir@cmpwn.com> | 2019-03-15 21:36:06 -0400 | 
|---|---|---|
| committer | Drew DeVault <sir@cmpwn.com> | 2019-03-15 21:36:06 -0400 | 
| commit | ef6178a12ae5ef7070711f5cc2f2114dfd015dcd (patch) | |
| tree | 6bfba867c30bfc5ac0188aa66d4263789b1199e3 | |
| parent | 77c76ba46296f57f88c591a420e929a059a55d3e (diff) | |
Move MessageStore into its own file
| -rw-r--r-- | lib/msgstore.go | 86 | ||||
| -rw-r--r-- | widgets/account.go | 7 | ||||
| -rw-r--r-- | widgets/msglist.go | 86 | 
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() | 
