diff options
-rw-r--r-- | lib/indexformat.go | 4 | ||||
-rw-r--r-- | lib/msgstore.go | 31 | ||||
-rw-r--r-- | models/models.go | 32 | ||||
-rw-r--r-- | widgets/account.go | 3 | ||||
-rw-r--r-- | widgets/msglist.go | 4 | ||||
-rw-r--r-- | widgets/msgviewer.go | 18 | ||||
-rw-r--r-- | widgets/providesmessage.go | 4 | ||||
-rw-r--r-- | worker/imap/fetch.go | 41 | ||||
-rw-r--r-- | worker/imap/worker.go | 13 | ||||
-rw-r--r-- | worker/types/messages.go | 16 |
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 { |