aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2019-07-03 16:10:16 -0400
committerBen Burwell <ben@benburwell.com>2019-07-04 22:03:04 -0400
commit91529df0fecc68d5b0fdbb682529ee545884e7c5 (patch)
tree45b64884521d2df84dc057c99919f03240600344
parentf9f523ad59491eda08003ce2ccc6d57d7f19ea1e (diff)
Factor UI models out of the worker message package
Before, the information needed to display different parts of the UI was tightly coupled to the specific messages being sent back and forth to the backend worker. Separating out a models package allows us to be more specific about exactly what a backend is able to and required to provide for the UI.
-rw-r--r--lib/indexformat.go4
-rw-r--r--lib/msgstore.go31
-rw-r--r--models/models.go32
-rw-r--r--widgets/account.go3
-rw-r--r--widgets/msglist.go4
-rw-r--r--widgets/msgviewer.go18
-rw-r--r--widgets/providesmessage.go4
-rw-r--r--worker/imap/fetch.go41
-rw-r--r--worker/imap/worker.go13
-rw-r--r--worker/types/messages.go16
10 files changed, 103 insertions, 63 deletions
diff --git a/lib/indexformat.go b/lib/indexformat.go
index 9e7a805..43d2ef8 100644
--- a/lib/indexformat.go
+++ b/lib/indexformat.go
@@ -9,11 +9,11 @@ import (
"github.com/emersion/go-imap"
"git.sr.ht/~sircmpwn/aerc/config"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
func ParseIndexFormat(conf *config.AercConfig, number int,
- msg *types.MessageInfo) (string, []interface{}, error) {
+ msg *models.MessageInfo) (string, []interface{}, error) {
format := conf.Ui.IndexFormat
retval := make([]byte, 0, len(format))
diff --git a/lib/msgstore.go b/lib/msgstore.go
index 09cf31f..19f328d 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -6,6 +6,7 @@ import (
"github.com/emersion/go-imap"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -13,7 +14,7 @@ import (
type MessageStore struct {
Deleted map[uint32]interface{}
DirInfo types.DirectoryInfo
- Messages map[uint32]*types.MessageInfo
+ Messages map[uint32]*models.MessageInfo
// Ordered list of known UIDs
Uids []uint32
@@ -106,11 +107,11 @@ func (store *MessageStore) FetchBodyPart(
if !ok {
return
}
- cb(msg.Reader)
+ cb(msg.Part.Reader)
})
}
-func merge(to *types.MessageInfo, from *types.MessageInfo) {
+func merge(to *models.MessageInfo, from *models.MessageInfo) {
if from.BodyStructure != nil {
to.BodyStructure = from.BodyStructure
}
@@ -135,7 +136,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
store.worker.PostAction(&types.FetchDirectoryContents{}, nil)
update = true
case *types.DirectoryContents:
- newMap := make(map[uint32]*types.MessageInfo)
+ newMap := make(map[uint32]*models.MessageInfo)
for _, uid := range msg.Uids {
if msg, ok := store.Messages[uid]; ok {
newMap[uid] = msg
@@ -147,14 +148,14 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
store.Uids = msg.Uids
update = true
case *types.MessageInfo:
- if existing, ok := store.Messages[msg.Uid]; ok && existing != nil {
- merge(existing, msg)
+ if existing, ok := store.Messages[msg.Info.Uid]; ok && existing != nil {
+ merge(existing, msg.Info)
} else {
- store.Messages[msg.Uid] = msg
+ store.Messages[msg.Info.Uid] = msg.Info
}
- if _, ok := store.pendingHeaders[msg.Uid]; msg.Envelope != nil && ok {
- delete(store.pendingHeaders, msg.Uid)
- if cbs, ok := store.headerCallbacks[msg.Uid]; ok {
+ if _, ok := store.pendingHeaders[msg.Info.Uid]; msg.Info.Envelope != nil && ok {
+ delete(store.pendingHeaders, msg.Info.Uid)
+ if cbs, ok := store.headerCallbacks[msg.Info.Uid]; ok {
for _, cb := range cbs {
cb(msg)
}
@@ -162,11 +163,11 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
}
update = true
case *types.FullMessage:
- if _, ok := store.pendingBodies[msg.Uid]; ok {
- delete(store.pendingBodies, msg.Uid)
- if cbs, ok := store.bodyCallbacks[msg.Uid]; ok {
+ if _, ok := store.pendingBodies[msg.Content.Uid]; ok {
+ delete(store.pendingBodies, msg.Content.Uid)
+ if cbs, ok := store.bodyCallbacks[msg.Content.Uid]; ok {
for _, cb := range cbs {
- cb(msg.Reader)
+ cb(msg.Content.Reader)
}
}
}
@@ -283,7 +284,7 @@ func (store *MessageStore) Read(uids []uint32, read bool,
}, cb)
}
-func (store *MessageStore) Selected() *types.MessageInfo {
+func (store *MessageStore) Selected() *models.MessageInfo {
return store.Messages[store.Uids[len(store.Uids)-store.selected-1]]
}
diff --git a/models/models.go b/models/models.go
new file mode 100644
index 0000000..00297e9
--- /dev/null
+++ b/models/models.go
@@ -0,0 +1,32 @@
+package models
+
+import (
+ "io"
+ "time"
+
+ "github.com/emersion/go-imap"
+ "github.com/emersion/go-message/mail"
+)
+
+// A MessageInfo holds information about the structure of a message
+type MessageInfo struct {
+ BodyStructure *imap.BodyStructure
+ Envelope *imap.Envelope
+ Flags []string
+ InternalDate time.Time
+ RFC822Headers *mail.Header
+ Size uint32
+ Uid uint32
+}
+
+// A MessageBodyPart can be displayed in the message viewer
+type MessageBodyPart struct {
+ Reader io.Reader
+ Uid uint32
+}
+
+// A FullMessage is the entire message
+type FullMessage struct {
+ Reader io.Reader
+ Uid uint32
+}
diff --git a/widgets/account.go b/widgets/account.go
index 824f958..ae0cf56 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -9,6 +9,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -165,7 +166,7 @@ func (acct *AccountView) Store() *lib.MessageStore {
return acct.msglist.Store()
}
-func (acct *AccountView) SelectedMessage() *types.MessageInfo {
+func (acct *AccountView) SelectedMessage() *models.MessageInfo {
return acct.msglist.Selected()
}
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 211cbce..7051478 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -11,7 +11,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
type MessageList struct {
@@ -176,7 +176,7 @@ func (ml *MessageList) Empty() bool {
return store == nil || len(store.Uids) == 0
}
-func (ml *MessageList) Selected() *types.MessageInfo {
+func (ml *MessageList) Selected() *models.MessageInfo {
store := ml.Store()
return store.Messages[store.Uids[len(store.Uids)-ml.store.SelectedIndex()-1]]
}
diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go
index 10c2182..49b4dd4 100644
--- a/widgets/msgviewer.go
+++ b/widgets/msgviewer.go
@@ -20,7 +20,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
var ansi = regexp.MustCompile("^\x1B\\[[0-?]*[ -/]*[@-~]")
@@ -31,7 +31,7 @@ type MessageViewer struct {
conf *config.AercConfig
err error
grid *ui.Grid
- msg *types.MessageInfo
+ msg *models.MessageInfo
switcher *PartSwitcher
store *lib.MessageStore
}
@@ -44,7 +44,7 @@ type PartSwitcher struct {
}
func NewMessageViewer(acct *AccountView, conf *config.AercConfig,
- store *lib.MessageStore, msg *types.MessageInfo) *MessageViewer {
+ store *lib.MessageStore, msg *models.MessageInfo) *MessageViewer {
grid := ui.NewGrid().Rows([]ui.GridSpec{
{ui.SIZE_EXACT, 4}, // TODO: Based on number of header rows
@@ -112,7 +112,7 @@ handle_error:
}
func enumerateParts(conf *config.AercConfig, store *lib.MessageStore,
- msg *types.MessageInfo, body *imap.BodyStructure,
+ msg *models.MessageInfo, body *imap.BodyStructure,
showHeaders bool, index []int) ([]*PartViewer, error) {
var parts []*PartViewer
@@ -140,7 +140,7 @@ func enumerateParts(conf *config.AercConfig, store *lib.MessageStore,
}
func createSwitcher(switcher *PartSwitcher, conf *config.AercConfig,
- store *lib.MessageStore, msg *types.MessageInfo, showHeaders bool) error {
+ store *lib.MessageStore, msg *models.MessageInfo, showHeaders bool) error {
var err error
switcher.showHeaders = showHeaders
@@ -212,7 +212,7 @@ func (mv *MessageViewer) SelectedAccount() *AccountView {
return mv.acct
}
-func (mv *MessageViewer) SelectedMessage() *types.MessageInfo {
+func (mv *MessageViewer) SelectedMessage() *models.MessageInfo {
return mv.msg
}
@@ -321,7 +321,7 @@ type PartViewer struct {
fetched bool
filter *exec.Cmd
index []int
- msg *types.MessageInfo
+ msg *models.MessageInfo
pager *exec.Cmd
pagerin io.WriteCloser
part *imap.BodyStructure
@@ -334,13 +334,13 @@ type PartViewer struct {
type PartInfo struct {
Index []int
- Msg *types.MessageInfo
+ Msg *models.MessageInfo
Part *imap.BodyStructure
Store *lib.MessageStore
}
func NewPartViewer(conf *config.AercConfig,
- store *lib.MessageStore, msg *types.MessageInfo,
+ store *lib.MessageStore, msg *models.MessageInfo,
part *imap.BodyStructure, showHeaders bool,
index []int) (*PartViewer, error) {
diff --git a/widgets/providesmessage.go b/widgets/providesmessage.go
index 7be8e7e..cff546b 100644
--- a/widgets/providesmessage.go
+++ b/widgets/providesmessage.go
@@ -3,12 +3,12 @@ package widgets
import (
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/lib/ui"
- "git.sr.ht/~sircmpwn/aerc/worker/types"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
type ProvidesMessage interface {
ui.Drawable
Store() *lib.MessageStore
- SelectedMessage() *types.MessageInfo
+ SelectedMessage() *models.MessageInfo
SelectedAccount() *AccountView
}
diff --git a/worker/imap/fetch.go b/worker/imap/fetch.go
index 7d1bfcf..d5bb9aa 100644
--- a/worker/imap/fetch.go
+++ b/worker/imap/fetch.go
@@ -8,6 +8,7 @@ import (
"github.com/emersion/go-message/mail"
"github.com/emersion/go-message/textproto"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -82,39 +83,49 @@ func (imapw *IMAPWorker) handleFetchMessages(
header = &mail.Header{message.Header{textprotoHeader}}
}
imapw.worker.PostMessage(&types.MessageInfo{
- Message: types.RespondTo(msg),
- BodyStructure: _msg.BodyStructure,
- Envelope: _msg.Envelope,
- Flags: _msg.Flags,
- InternalDate: _msg.InternalDate,
- RFC822Headers: header,
- Uid: _msg.Uid,
+ Message: types.RespondTo(msg),
+ Info: &models.MessageInfo{
+ BodyStructure: _msg.BodyStructure,
+ Envelope: _msg.Envelope,
+ Flags: _msg.Flags,
+ InternalDate: _msg.InternalDate,
+ RFC822Headers: header,
+ Uid: _msg.Uid,
+ },
}, nil)
case *types.FetchFullMessages:
reader := _msg.GetBody(section)
imapw.worker.PostMessage(&types.FullMessage{
Message: types.RespondTo(msg),
- Reader: reader,
- Uid: _msg.Uid,
+ Content: &models.FullMessage{
+ Reader: reader,
+ Uid: _msg.Uid,
+ },
}, nil)
// Update flags (to mark message as read)
imapw.worker.PostMessage(&types.MessageInfo{
Message: types.RespondTo(msg),
- Flags: _msg.Flags,
- Uid: _msg.Uid,
+ Info: &models.MessageInfo{
+ Flags: _msg.Flags,
+ Uid: _msg.Uid,
+ },
}, nil)
case *types.FetchMessageBodyPart:
reader := _msg.GetBody(section)
imapw.worker.PostMessage(&types.MessageBodyPart{
Message: types.RespondTo(msg),
- Reader: reader,
- Uid: _msg.Uid,
+ Part: &models.MessageBodyPart{
+ Reader: reader,
+ Uid: _msg.Uid,
+ },
}, nil)
// Update flags (to mark message as read)
imapw.worker.PostMessage(&types.MessageInfo{
Message: types.RespondTo(msg),
- Flags: _msg.Flags,
- Uid: _msg.Uid,
+ Info: &models.MessageInfo{
+ Flags: _msg.Flags,
+ Uid: _msg.Uid,
+ },
}, nil)
}
}
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index 5005620..ff02a78 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -10,6 +10,7 @@ import (
idle "github.com/emersion/go-imap-idle"
"github.com/emersion/go-imap/client"
+ "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -183,11 +184,13 @@ func (w *IMAPWorker) handleImapUpdate(update client.Update) {
msg.Uid = w.seqMap[msg.SeqNum-1]
}
w.worker.PostMessage(&types.MessageInfo{
- BodyStructure: msg.BodyStructure,
- Envelope: msg.Envelope,
- Flags: msg.Flags,
- InternalDate: msg.InternalDate,
- Uid: msg.Uid,
+ Info: &models.MessageInfo{
+ BodyStructure: msg.BodyStructure,
+ Envelope: msg.Envelope,
+ Flags: msg.Flags,
+ InternalDate: msg.InternalDate,
+ Uid: msg.Uid,
+ },
}, nil)
case *client.ExpungeUpdate:
i := update.SeqNum - 1
diff --git a/worker/types/messages.go b/worker/types/messages.go
index d9e911f..7eac896 100644
--- a/worker/types/messages.go
+++ b/worker/types/messages.go
@@ -5,9 +5,9 @@ import (
"time"
"github.com/emersion/go-imap"
- "github.com/emersion/go-message/mail"
"git.sr.ht/~sircmpwn/aerc/config"
+ "git.sr.ht/~sircmpwn/aerc/models"
)
type WorkerMessage interface {
@@ -164,25 +164,17 @@ type SearchResults struct {
type MessageInfo struct {
Message
- BodyStructure *imap.BodyStructure
- Envelope *imap.Envelope
- Flags []string
- InternalDate time.Time
- RFC822Headers *mail.Header
- Size uint32
- Uid uint32
+ Info *models.MessageInfo
}
type FullMessage struct {
Message
- Reader io.Reader
- Uid uint32
+ Content *models.FullMessage
}
type MessageBodyPart struct {
Message
- Reader io.Reader
- Uid uint32
+ Part *models.MessageBodyPart
}
type MessagesDeleted struct {